Skip to content

Commit c19e900

Browse files
committed
Fix Cancel On Loss Test's Race Condition (#4121)
1 parent fa50391 commit c19e900

File tree

1 file changed

+23
-65
lines changed

1 file changed

+23
-65
lines changed

src/test/lib/DataTest.cpp

Lines changed: 23 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,7 +1398,6 @@ struct CancelOnLossContext
13981398
CxPlatEvent SendPhaseEndedEvent = {};
13991399
};
14001400

1401-
14021401
_Function_class_(MsQuicStreamCallback)
14031402
QUIC_STATUS
14041403
QuicCancelOnLossStreamHandler(
@@ -1407,27 +1406,18 @@ QuicCancelOnLossStreamHandler(
14071406
_Inout_ QUIC_STREAM_EVENT* Event
14081407
)
14091408
{
1410-
if (Context == nullptr) {
1411-
return QUIC_STATUS_INVALID_PARAMETER;
1412-
}
1413-
14141409
auto TestContext = reinterpret_cast<CancelOnLossContext*>(Context);
1415-
1416-
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
1417-
14181410
switch (Event->Type) {
14191411
case QUIC_STREAM_EVENT_RECEIVE:
14201412
if (TestContext->IsServer) { // only server receives
1421-
TestContext->SendPhaseEndedEvent.Set();
14221413
TestContext->ExitCode = CancelOnLossContext::SuccessExitCode;
1414+
TestContext->SendPhaseEndedEvent.Set();
14231415
}
14241416
break;
14251417
case QUIC_STREAM_EVENT_PEER_SEND_ABORTED:
14261418
if (TestContext->IsServer) { // server-side 'cancel on loss' detection
1427-
TestContext->SendPhaseEndedEvent.Set();
14281419
TestContext->ExitCode = Event->PEER_SEND_ABORTED.ErrorCode;
1429-
} else {
1430-
Status = QUIC_STATUS_INVALID_STATE;
1420+
TestContext->SendPhaseEndedEvent.Set();
14311421
}
14321422
break;
14331423
case QUIC_STREAM_EVENT_PEER_SEND_SHUTDOWN:
@@ -1440,23 +1430,18 @@ QuicCancelOnLossStreamHandler(
14401430
if (!TestContext->IsDropScenario) { // if drop scenario, we use 'cancel on loss' event
14411431
TestContext->SendPhaseEndedEvent.Set();
14421432
}
1443-
} else {
1444-
Status = QUIC_STATUS_INVALID_STATE;
14451433
}
14461434
break;
14471435
case QUIC_STREAM_EVENT_CANCEL_ON_LOSS:
14481436
if (!TestContext->IsServer && TestContext->IsDropScenario) { // only client sends & only happens if in drop scenario
14491437
Event->CANCEL_ON_LOSS.ErrorCode = CancelOnLossContext::ErrorExitCode;
14501438
TestContext->SendPhaseEndedEvent.Set();
1451-
} else {
1452-
Status = QUIC_STATUS_INVALID_STATE;
14531439
}
14541440
break;
14551441
default:
14561442
break;
14571443
}
1458-
1459-
return Status;
1444+
return QUIC_STATUS_SUCCESS;
14601445
}
14611446

14621447
_Function_class_(MsQuicConnectionCallback)
@@ -1467,14 +1452,7 @@ QuicCancelOnLossConnectionHandler(
14671452
_Inout_ QUIC_CONNECTION_EVENT* Event
14681453
)
14691454
{
1470-
if (Context == nullptr) {
1471-
return QUIC_STATUS_INVALID_PARAMETER;
1472-
}
1473-
14741455
auto TestContext = reinterpret_cast<CancelOnLossContext*>(Context);
1475-
1476-
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
1477-
14781456
switch (Event->Type) {
14791457
case QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED:
14801458
TestContext->Stream = new(std::nothrow) MsQuicStream(
@@ -1489,8 +1467,7 @@ QuicCancelOnLossConnectionHandler(
14891467
default:
14901468
break;
14911469
}
1492-
1493-
return Status;
1470+
return QUIC_STATUS_SUCCESS;
14941471
}
14951472

14961473
void
@@ -1511,49 +1488,38 @@ QuicCancelOnLossSend(
15111488

15121489
uint8_t RawBuffer[] = "cancel on loss message";
15131490
QUIC_BUFFER MessageBuffer = { sizeof(RawBuffer), RawBuffer };
1514-
15151491
SelectiveLossHelper LossHelper; // used later to trigger packet drops
15161492

1517-
// Start the server.
15181493
MsQuicConfiguration ServerConfiguration(Registration, Alpn, Settings, ServerSelfSignedCredConfig);
15191494
TEST_TRUE(ServerConfiguration.IsValid());
1495+
MsQuicCredentialConfig ClientCredConfig;
1496+
MsQuicConfiguration ClientConfiguration(Registration, Alpn, Settings, ClientCredConfig);
1497+
TEST_TRUE(ClientConfiguration.IsValid());
15201498

1521-
CancelOnLossContext ServerContext{ DropPackets, true /* IsServer */, &ServerConfiguration};
1522-
QuicAddr ServerLocalAddr;
1523-
1499+
CancelOnLossContext ServerContext(DropPackets, true /* IsServer */, &ServerConfiguration);
15241500
MsQuicAutoAcceptListener Listener(Registration, ServerConfiguration, QuicCancelOnLossConnectionHandler, &ServerContext);
15251501
TEST_TRUE(Listener.IsValid());
15261502
TEST_EQUAL(Listener.Start(Alpn), QUIC_STATUS_SUCCESS);
1503+
QuicAddr ServerLocalAddr;
15271504
TEST_EQUAL(Listener.GetLocalAddr(ServerLocalAddr), QUIC_STATUS_SUCCESS);
15281505

1529-
// Start the client.
1530-
MsQuicCredentialConfig ClientCredConfig;
1531-
MsQuicConfiguration ClientConfiguration(Registration, Alpn, Settings, ClientCredConfig);
1532-
TEST_TRUE(ClientConfiguration.IsValid());
1533-
1534-
CancelOnLossContext ClientContext{ DropPackets, false /* IsServer */, &ClientConfiguration};
1535-
1536-
// Initiate connection.
1506+
CancelOnLossContext ClientContext(DropPackets, false /* IsServer */, &ClientConfiguration);
15371507
ClientContext.Connection = new(std::nothrow) MsQuicConnection(
15381508
Registration,
15391509
CleanUpManual,
15401510
QuicCancelOnLossConnectionHandler,
15411511
&ClientContext);
15421512
TEST_TRUE(ClientContext.Connection->IsValid());
15431513

1544-
QUIC_STATUS Status = ClientContext.Connection->Start(
1545-
ClientConfiguration,
1546-
QUIC_ADDRESS_FAMILY_INET,
1547-
QUIC_TEST_LOOPBACK_FOR_AF(QUIC_ADDRESS_FAMILY_INET),
1548-
ServerLocalAddr.GetPort());
1549-
if (QUIC_FAILED(Status)) {
1550-
TEST_FAILURE("Failed to start a connection from the client.");
1551-
return;
1552-
}
1514+
TEST_QUIC_SUCCEEDED(
1515+
ClientContext.Connection->Start(
1516+
ClientConfiguration,
1517+
QUIC_ADDRESS_FAMILY_INET,
1518+
QUIC_TEST_LOOPBACK_FOR_AF(QUIC_ADDRESS_FAMILY_INET),
1519+
ServerLocalAddr.GetPort()));
15531520

15541521
// Wait for connection to be established.
15551522
constexpr uint32_t EventWaitTimeoutMs{ 1'000 };
1556-
15571523
if (!ClientContext.ConnectedEvent.WaitTimeout(EventWaitTimeoutMs)) {
15581524
TEST_FAILURE("Client failed to get connected before timeout!");
15591525
return;
@@ -1574,18 +1540,8 @@ QuicCancelOnLossSend(
15741540
QuicCancelOnLossStreamHandler,
15751541
&ClientContext);
15761542
TEST_TRUE(ClientContext.Stream->IsValid());
1577-
Status = ClientContext.Stream->Start();
1578-
if (QUIC_FAILED(Status)) {
1579-
TEST_FAILURE("Client failed to start stream.");
1580-
return;
1581-
}
1582-
1583-
// Send test message.
1584-
Status = ClientContext.Stream->Send(&MessageBuffer, 1, QUIC_SEND_FLAG_CANCEL_ON_LOSS);
1585-
if (QUIC_FAILED(Status)) {
1586-
TEST_FAILURE("Client failed to send message.");
1587-
return;
1588-
}
1543+
TEST_QUIC_SUCCEEDED(ClientContext.Stream->Start());
1544+
TEST_QUIC_SUCCEEDED(ClientContext.Stream->Send(&MessageBuffer, 1, QUIC_SEND_FLAG_CANCEL_ON_LOSS));
15891545

15901546
// If requested, drop packets.
15911547
if (DropPackets) {
@@ -1603,11 +1559,13 @@ QuicCancelOnLossSend(
16031559

16041560
// Check results.
16051561
if (DropPackets) {
1606-
TEST_EQUAL(ServerContext.ExitCode, CancelOnLossContext::ErrorExitCode);
1562+
if (ServerContext.ExitCode != CancelOnLossContext::ErrorExitCode) {
1563+
TEST_FAILURE("ServerContext.ExitCode %u != ErrorExitCode", ServerContext.ExitCode);
1564+
}
16071565
} else {
16081566
if (ServerContext.ExitCode != CancelOnLossContext::SuccessExitCode) {
1609-
TEST_FAILURE("ServerContext.ExitCode %u, CancelOnLossContext::SuccessExitCode: %u", ServerContext.ExitCode, CancelOnLossContext::SuccessExitCode);
1610-
}
1567+
TEST_FAILURE("ServerContext.ExitCode %u != SuccessExitCode", ServerContext.ExitCode);
1568+
}
16111569
}
16121570

16131571
if (Listener.LastConnection) {

0 commit comments

Comments
 (0)