Skip to content

Commit 2bb5c96

Browse files
Copilotsaikat107
andcommitted
Add tests for division-by-zero fix in NetStats bandwidth calculation
Co-authored-by: saikat107 <2145576+saikat107@users.noreply.github.com> Agent-Logs-Url: https://github.com/microsoft/msquic/sessions/75f472a3-7faa-4236-bb73-dce3bf94d089
1 parent bf7c18e commit 2bb5c96

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

src/core/unittest/CubicTest.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,88 @@ TEST_F(CubicTest, GetNetworkStatistics_RetrieveStats)
12741274
ASSERT_EQ(NetworkStats.IdealBytes, 0u);
12751275
}
12761276

1277+
//
1278+
// Test: GetNetworkStatistics - Zero SmoothedRtt returns zero Bandwidth
1279+
// Scenario: Verifies no division-by-zero occurs when SmoothedRtt is 0 at the
1280+
// time GetNetworkStatistics is called (e.g. before the first RTT sample).
1281+
// Bandwidth must be reported as 0 rather than crashing.
1282+
//
1283+
TEST_F(CubicTest, GetNetworkStatistics_ZeroSmoothedRtt_BandwidthIsZero)
1284+
{
1285+
// Initialize without an RTT sample so SmoothedRtt stays 0.
1286+
InitializeWithDefaults(
1287+
/*WindowPackets=*/10,
1288+
/*HyStart=*/false,
1289+
/*Mtu=*/1280,
1290+
/*IdleTimeoutMs=*/1000,
1291+
/*GotRttSample=*/false
1292+
);
1293+
1294+
ASSERT_EQ(Connection.Paths[0].SmoothedRtt, 0u);
1295+
1296+
CC->QuicCongestionControlOnDataSent(CC, 5000);
1297+
1298+
QUIC_NETWORK_STATISTICS NetworkStats;
1299+
CxPlatZeroMemory(&NetworkStats, sizeof(NetworkStats));
1300+
1301+
// Must not crash with divide-by-zero when SmoothedRtt == 0.
1302+
CC->QuicCongestionControlGetNetworkStatistics(&Connection, CC, &NetworkStats);
1303+
1304+
ASSERT_EQ(NetworkStats.Bandwidth, 0u);
1305+
ASSERT_EQ(NetworkStats.SmoothedRTT, 0u);
1306+
ASSERT_EQ(NetworkStats.CongestionWindow, Cubic->CongestionWindow);
1307+
}
1308+
1309+
//
1310+
// Test: OnDataAcknowledged NetStats path - Zero SmoothedRtt returns zero Bandwidth
1311+
// Scenario: Verifies no division-by-zero occurs inside the NetStatsEventEnabled
1312+
// path of OnDataAcknowledged when an ACK arrives before the first RTT sample
1313+
// (SmoothedRtt == 0). The NETWORK_STATISTICS event must fire without crashing.
1314+
//
1315+
static QUIC_STATUS
1316+
QUIC_API
1317+
NetStatsDummyCallback(
1318+
_In_ HQUIC /* Connection */,
1319+
_In_opt_ void* /* Context */,
1320+
_Inout_ QUIC_CONNECTION_EVENT* /* Event */)
1321+
{
1322+
return QUIC_STATUS_SUCCESS;
1323+
}
1324+
1325+
TEST_F(CubicTest, OnDataAcknowledged_NetStats_ZeroSmoothedRtt_BandwidthIsZero)
1326+
{
1327+
// Initialize without an RTT sample so SmoothedRtt stays 0.
1328+
InitializeWithDefaults(
1329+
/*WindowPackets=*/10,
1330+
/*HyStart=*/false,
1331+
/*Mtu=*/1280,
1332+
/*IdleTimeoutMs=*/1000,
1333+
/*GotRttSample=*/false
1334+
);
1335+
1336+
// Enable the NetStats event path and supply a no-op callback so
1337+
// QuicConnIndicateEvent does not dereference a null function pointer.
1338+
Connection.Settings.NetStatsEventEnabled = TRUE;
1339+
Connection.ClientCallbackHandler = NetStatsDummyCallback;
1340+
1341+
ASSERT_EQ(Connection.Paths[0].SmoothedRtt, 0u);
1342+
1343+
Cubic->BytesInFlight = 5000;
1344+
1345+
// Construct an ACK event with SmoothedRtt == 0 (no RTT sample yet).
1346+
QUIC_ACK_EVENT AckEvent = MakeAckEvent(
1347+
/*TimeNow=*/1000000,
1348+
/*LargestAck=*/5,
1349+
/*LargestSentPacketNumber=*/10,
1350+
/*BytesAcked=*/1000,
1351+
/*SmoothedRtt=*/0,
1352+
/*MinRtt=*/0,
1353+
/*MinRttValid=*/FALSE);
1354+
1355+
// Must not crash with STATUS_INTEGER_DIVIDE_BY_ZERO.
1356+
CC->QuicCongestionControlOnDataAcknowledged(CC, &AckEvent);
1357+
}
1358+
12771359
//
12781360
// Test: Spurious Congestion Event - No-Op When Not In Recovery
12791361
// Scenario: Verifies OnSpuriousCongestionEvent returns FALSE with no state change

0 commit comments

Comments
 (0)