From de3c63cd9dd536cf36e29aad381096b7cd061af9 Mon Sep 17 00:00:00 2001 From: Mithun Iyer Date: Wed, 27 Jan 2021 12:25:20 -0800 Subject: Deflake tcp_zero_window_probe_retransmit_test Fix the test to rely on more deterministic retransmission interval computations by skipping the initial probe transmission time as that can be non-deterministic given arbitrary time taken for the DUT to receive a send command and initiate a send. Fixes #5080 PiperOrigin-RevId: 354146256 --- .../tests/tcp_zero_window_probe_retransmit_test.go | 28 +++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'test/packetimpact') diff --git a/test/packetimpact/tests/tcp_zero_window_probe_retransmit_test.go b/test/packetimpact/tests/tcp_zero_window_probe_retransmit_test.go index 1ab9ee1b2..b15b8fc25 100644 --- a/test/packetimpact/tests/tcp_zero_window_probe_retransmit_test.go +++ b/test/packetimpact/tests/tcp_zero_window_probe_retransmit_test.go @@ -66,33 +66,39 @@ func TestZeroWindowProbeRetransmit(t *testing.T) { probeSeq := testbench.Uint32(uint32(*conn.RemoteSeqNum(t) - 1)) ackProbe := testbench.Uint32(uint32(*conn.RemoteSeqNum(t))) - startProbeDuration := time.Second - current := startProbeDuration - first := time.Now() // Ask the dut to send out data. dut.Send(t, acceptFd, sampleData, 0) + + var prev time.Duration // Expect the dut to keep the connection alive as long as the remote is // acknowledging the zero-window probes. - for i := 0; i < 5; i++ { + for i := 1; i <= 5; i++ { start := time.Now() // Expect zero-window probe with a timeout which is a function of the typical // first retransmission time. The retransmission times is supposed to // exponentially increase. - if _, err := conn.ExpectData(t, &testbench.TCP{SeqNum: probeSeq}, nil, 2*current); err != nil { + if _, err := conn.ExpectData(t, &testbench.TCP{SeqNum: probeSeq}, nil, time.Duration(i)*time.Second); err != nil { t.Fatalf("expected a probe with sequence number %d: loop %d", probeSeq, i) } - if i == 0 { - startProbeDuration = time.Now().Sub(first) - current = 2 * startProbeDuration + if i == 1 { + // Skip the first probe as computing transmit time for that is + // non-deterministic because of the arbitrary time taken for + // the dut to receive a send command and issue a send. continue } - // Check if the probes came at exponentially increasing intervals. - if got, want := time.Since(start), current-startProbeDuration; got < want { + + // Check if the time taken to receive the probe from the dut is + // increasing exponentially. To avoid flakes, use a correction + // factor for the expected duration which accounts for any + // scheduling non-determinism. + const timeCorrection = 200 * time.Millisecond + got := time.Since(start) + if want := (2 * prev) - timeCorrection; prev != 0 && got < want { t.Errorf("got zero probe %d after %s, want >= %s", i, got, want) } + prev = got // Acknowledge the zero-window probes from the dut. conn.Send(t, testbench.TCP{AckNum: ackProbe, Flags: testbench.Uint8(header.TCPFlagAck), WindowSize: testbench.Uint16(0)}) - current *= 2 } // Advertize non-zero window. conn.Send(t, testbench.TCP{AckNum: ackProbe, Flags: testbench.Uint8(header.TCPFlagAck)}) -- cgit v1.2.3