1 // Copyright (c) 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/core/quic_idle_network_detector.h"
6
7 #include "quiche/quic/core/quic_one_block_arena.h"
8 #include "quiche/quic/core/quic_time.h"
9 #include "quiche/quic/platform/api/quic_expect_bug.h"
10 #include "quiche/quic/platform/api/quic_flags.h"
11 #include "quiche/quic/platform/api/quic_test.h"
12 #include "quiche/quic/test_tools/quic_test_utils.h"
13
14 namespace quic {
15 namespace test {
16
17 class QuicIdleNetworkDetectorTestPeer {
18 public:
GetAlarm(QuicIdleNetworkDetector * detector)19 static QuicAlarm* GetAlarm(QuicIdleNetworkDetector* detector) {
20 return detector->alarm_.get();
21 }
22 };
23
24 namespace {
25
26 class MockDelegate : public QuicIdleNetworkDetector::Delegate {
27 public:
28 MOCK_METHOD(void, OnHandshakeTimeout, (), (override));
29 MOCK_METHOD(void, OnIdleNetworkDetected, (), (override));
30 };
31
32 class QuicIdleNetworkDetectorTest : public QuicTest {
33 public:
QuicIdleNetworkDetectorTest()34 QuicIdleNetworkDetectorTest() {
35 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
36 detector_ = std::make_unique<QuicIdleNetworkDetector>(
37 &delegate_, clock_.Now(), &arena_, &alarm_factory_,
38 /*context=*/nullptr);
39 alarm_ = static_cast<MockAlarmFactory::TestAlarm*>(
40 QuicIdleNetworkDetectorTestPeer::GetAlarm(detector_.get()));
41 }
42
43 protected:
44 testing::StrictMock<MockDelegate> delegate_;
45 QuicConnectionArena arena_;
46 MockAlarmFactory alarm_factory_;
47
48 std::unique_ptr<QuicIdleNetworkDetector> detector_;
49
50 MockAlarmFactory::TestAlarm* alarm_;
51 MockClock clock_;
52 };
53
TEST_F(QuicIdleNetworkDetectorTest,IdleNetworkDetectedBeforeHandshakeCompletes)54 TEST_F(QuicIdleNetworkDetectorTest,
55 IdleNetworkDetectedBeforeHandshakeCompletes) {
56 EXPECT_FALSE(alarm_->IsSet());
57 detector_->SetTimeouts(
58 /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
59 /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
60 EXPECT_TRUE(alarm_->IsSet());
61 EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(20),
62 alarm_->deadline());
63
64 // No network activity for 20s.
65 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(20));
66 EXPECT_CALL(delegate_, OnIdleNetworkDetected());
67 alarm_->Fire();
68 }
69
TEST_F(QuicIdleNetworkDetectorTest,HandshakeTimeout)70 TEST_F(QuicIdleNetworkDetectorTest, HandshakeTimeout) {
71 EXPECT_FALSE(alarm_->IsSet());
72 detector_->SetTimeouts(
73 /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
74 /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
75 EXPECT_TRUE(alarm_->IsSet());
76
77 // Has network activity after 15s.
78 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
79 detector_->OnPacketReceived(clock_.Now());
80 EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(15),
81 alarm_->deadline());
82 // Handshake does not complete for another 15s.
83 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
84 EXPECT_CALL(delegate_, OnHandshakeTimeout());
85 alarm_->Fire();
86 }
87
TEST_F(QuicIdleNetworkDetectorTest,IdleNetworkDetectedAfterHandshakeCompletes)88 TEST_F(QuicIdleNetworkDetectorTest,
89 IdleNetworkDetectedAfterHandshakeCompletes) {
90 EXPECT_FALSE(alarm_->IsSet());
91 detector_->SetTimeouts(
92 /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
93 /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
94 EXPECT_TRUE(alarm_->IsSet());
95 EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(20),
96 alarm_->deadline());
97
98 // Handshake completes in 200ms.
99 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
100 detector_->OnPacketReceived(clock_.Now());
101 detector_->SetTimeouts(
102 /*handshake_timeout=*/QuicTime::Delta::Infinite(),
103 /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(600));
104 EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
105 alarm_->deadline());
106
107 // No network activity for 600s.
108 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600));
109 EXPECT_CALL(delegate_, OnIdleNetworkDetected());
110 alarm_->Fire();
111 }
112
TEST_F(QuicIdleNetworkDetectorTest,DoNotExtendIdleDeadlineOnConsecutiveSentPackets)113 TEST_F(QuicIdleNetworkDetectorTest,
114 DoNotExtendIdleDeadlineOnConsecutiveSentPackets) {
115 EXPECT_FALSE(alarm_->IsSet());
116 detector_->SetTimeouts(
117 /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
118 /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
119 EXPECT_TRUE(alarm_->IsSet());
120
121 // Handshake completes in 200ms.
122 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
123 detector_->OnPacketReceived(clock_.Now());
124 detector_->SetTimeouts(
125 /*handshake_timeout=*/QuicTime::Delta::Infinite(),
126 QuicTime::Delta::FromSeconds(600));
127 EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
128 alarm_->deadline());
129
130 // Sent packets after 200ms.
131 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
132 detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::Zero());
133 const QuicTime packet_sent_time = clock_.Now();
134 EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(600),
135 alarm_->deadline());
136
137 // Sent another packet after 200ms
138 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
139 detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::Zero());
140 // Verify network deadline does not extend.
141 EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(600),
142 alarm_->deadline());
143
144 // No network activity for 600s.
145 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600) -
146 QuicTime::Delta::FromMilliseconds(200));
147 EXPECT_CALL(delegate_, OnIdleNetworkDetected());
148 alarm_->Fire();
149 }
150
TEST_F(QuicIdleNetworkDetectorTest,ShorterIdleTimeoutOnSentPacket)151 TEST_F(QuicIdleNetworkDetectorTest, ShorterIdleTimeoutOnSentPacket) {
152 detector_->enable_shorter_idle_timeout_on_sent_packet();
153 QuicTime::Delta idle_network_timeout = QuicTime::Delta::Zero();
154 idle_network_timeout = QuicTime::Delta::FromSeconds(30);
155 detector_->SetTimeouts(
156 /*handshake_timeout=*/QuicTime::Delta::Infinite(), idle_network_timeout);
157 EXPECT_TRUE(alarm_->IsSet());
158 const QuicTime deadline = alarm_->deadline();
159 EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30), deadline);
160
161 // Send a packet after 15s and 2s PTO delay.
162 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
163 detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
164 EXPECT_TRUE(alarm_->IsSet());
165 // Verify alarm does not get extended because deadline is > PTO delay.
166 EXPECT_EQ(deadline, alarm_->deadline());
167
168 // Send another packet near timeout and 2 s PTO delay.
169 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(14));
170 detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
171 EXPECT_TRUE(alarm_->IsSet());
172 // Verify alarm does not get extended although it is shorter than PTO.
173 EXPECT_EQ(deadline, alarm_->deadline());
174
175 // Receive a packet after 1s.
176 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
177 detector_->OnPacketReceived(clock_.Now());
178 EXPECT_TRUE(alarm_->IsSet());
179 // Verify idle timeout gets extended by 30s.
180 EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30),
181 alarm_->deadline());
182
183 // Send a packet near timeout.
184 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(29));
185 detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
186 EXPECT_TRUE(alarm_->IsSet());
187 // Verify idle timeout gets extended by 1s.
188 EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(2), alarm_->deadline());
189 }
190
TEST_F(QuicIdleNetworkDetectorTest,NoAlarmAfterStopped)191 TEST_F(QuicIdleNetworkDetectorTest, NoAlarmAfterStopped) {
192 detector_->StopDetection();
193
194 EXPECT_QUIC_BUG(
195 detector_->SetTimeouts(
196 /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
197 /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20)),
198 "SetAlarm called after stopped");
199 EXPECT_FALSE(alarm_->IsSet());
200 }
201
202 } // namespace
203
204 } // namespace test
205 } // namespace quic
206