1 // Copyright 2012 The Chromium Authors
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 "net/quic/quic_chromium_alarm_factory.h"
6
7 #include "net/quic/test_task_runner.h"
8 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace net::test {
12 namespace {
13
14 class TestDelegate : public quic::QuicAlarm::DelegateWithoutContext {
15 public:
16 TestDelegate() = default;
17
OnAlarm()18 void OnAlarm() override { fired_ = true; }
19
fired() const20 bool fired() const { return fired_; }
Clear()21 void Clear() { fired_ = false; }
22
23 private:
24 bool fired_ = false;
25 };
26
27 class QuicChromiumAlarmFactoryTest : public ::testing::Test {
28 protected:
QuicChromiumAlarmFactoryTest()29 QuicChromiumAlarmFactoryTest()
30 : runner_(base::MakeRefCounted<TestTaskRunner>(&clock_)),
31 alarm_factory_(runner_.get(), &clock_) {}
32
33 scoped_refptr<TestTaskRunner> runner_;
34 QuicChromiumAlarmFactory alarm_factory_;
35 quic::MockClock clock_;
36 };
37
TEST_F(QuicChromiumAlarmFactoryTest,CreateAlarm)38 TEST_F(QuicChromiumAlarmFactoryTest, CreateAlarm) {
39 TestDelegate* delegate = new TestDelegate();
40 std::unique_ptr<quic::QuicAlarm> alarm(alarm_factory_.CreateAlarm(delegate));
41
42 // Set the deadline 1µs in the future.
43 constexpr quic::QuicTime::Delta kDelta =
44 quic::QuicTime::Delta::FromMicroseconds(1);
45 quic::QuicTime deadline = clock_.Now() + kDelta;
46 alarm->Set(deadline);
47 EXPECT_TRUE(alarm->IsSet());
48 EXPECT_EQ(alarm->deadline(), deadline);
49 EXPECT_FALSE(delegate->fired());
50
51 runner_->FastForwardBy(kDelta);
52
53 EXPECT_EQ(quic::QuicTime::Zero() + kDelta, clock_.Now());
54 EXPECT_FALSE(alarm->IsSet());
55 EXPECT_TRUE(delegate->fired());
56 }
57
TEST_F(QuicChromiumAlarmFactoryTest,CreateAlarmAndCancel)58 TEST_F(QuicChromiumAlarmFactoryTest, CreateAlarmAndCancel) {
59 TestDelegate* delegate = new TestDelegate();
60 std::unique_ptr<quic::QuicAlarm> alarm(alarm_factory_.CreateAlarm(delegate));
61
62 constexpr quic::QuicTime::Delta kDelta =
63 quic::QuicTime::Delta::FromMicroseconds(1);
64 quic::QuicTime deadline = clock_.Now() + kDelta;
65 alarm->Set(deadline);
66 EXPECT_TRUE(alarm->IsSet());
67 EXPECT_EQ(alarm->deadline(), deadline);
68 EXPECT_FALSE(delegate->fired());
69
70 alarm->Cancel();
71
72 EXPECT_FALSE(alarm->IsSet());
73 EXPECT_FALSE(delegate->fired());
74
75 // Advancing time should not cause the alarm to fire.
76 runner_->FastForwardBy(kDelta);
77
78 EXPECT_EQ(quic::QuicTime::Zero() + kDelta, clock_.Now());
79 EXPECT_FALSE(alarm->IsSet());
80 EXPECT_FALSE(delegate->fired());
81 }
82
TEST_F(QuicChromiumAlarmFactoryTest,CreateAlarmAndReset)83 TEST_F(QuicChromiumAlarmFactoryTest, CreateAlarmAndReset) {
84 TestDelegate* delegate = new TestDelegate();
85 std::unique_ptr<quic::QuicAlarm> alarm(alarm_factory_.CreateAlarm(delegate));
86
87 // Set the deadline 1µs in the future.
88 constexpr quic::QuicTime::Delta kDelta =
89 quic::QuicTime::Delta::FromMicroseconds(1);
90 quic::QuicTime deadline = clock_.Now() + kDelta;
91 alarm->Set(deadline);
92 EXPECT_TRUE(alarm->IsSet());
93 EXPECT_EQ(alarm->deadline(), deadline);
94 EXPECT_FALSE(delegate->fired());
95
96 alarm->Cancel();
97
98 EXPECT_FALSE(alarm->IsSet());
99 EXPECT_FALSE(delegate->fired());
100
101 // Set the timer with a longer delta.
102 constexpr quic::QuicTime::Delta kNewDelta =
103 quic::QuicTime::Delta::FromMicroseconds(3);
104 quic::QuicTime new_deadline = clock_.Now() + kNewDelta;
105 alarm->Set(new_deadline);
106 EXPECT_TRUE(alarm->IsSet());
107 EXPECT_EQ(alarm->deadline(), new_deadline);
108 EXPECT_FALSE(delegate->fired());
109
110 // Advancing time for the first delay should not cause the alarm to fire.
111 runner_->FastForwardBy(kDelta);
112
113 EXPECT_EQ(quic::QuicTime::Zero() + kDelta, clock_.Now());
114 EXPECT_TRUE(alarm->IsSet());
115 EXPECT_FALSE(delegate->fired());
116
117 // Advancing time for the remaining of the new delay will fire the alarm.
118 runner_->FastForwardBy(kNewDelta - kDelta);
119
120 EXPECT_EQ(quic::QuicTime::Zero() + kNewDelta, clock_.Now());
121 EXPECT_FALSE(alarm->IsSet());
122 EXPECT_TRUE(delegate->fired());
123 }
124
TEST_F(QuicChromiumAlarmFactoryTest,CreateAlarmAndResetEarlier)125 TEST_F(QuicChromiumAlarmFactoryTest, CreateAlarmAndResetEarlier) {
126 TestDelegate* delegate = new TestDelegate();
127 std::unique_ptr<quic::QuicAlarm> alarm(alarm_factory_.CreateAlarm(delegate));
128
129 // Set the deadline 3µs in the future.
130 constexpr quic::QuicTime::Delta kDelta =
131 quic::QuicTime::Delta::FromMicroseconds(3);
132 quic::QuicTime deadline = clock_.Now() + kDelta;
133 alarm->Set(deadline);
134 EXPECT_TRUE(alarm->IsSet());
135 EXPECT_EQ(alarm->deadline(), deadline);
136 EXPECT_FALSE(delegate->fired());
137
138 alarm->Cancel();
139
140 EXPECT_FALSE(alarm->IsSet());
141 EXPECT_FALSE(delegate->fired());
142
143 // Set the timer with a shorter delta.
144 constexpr quic::QuicTime::Delta kNewDelta =
145 quic::QuicTime::Delta::FromMicroseconds(1);
146 quic::QuicTime new_deadline = clock_.Now() + kNewDelta;
147 alarm->Set(new_deadline);
148 EXPECT_TRUE(alarm->IsSet());
149 EXPECT_EQ(alarm->deadline(), new_deadline);
150 EXPECT_FALSE(delegate->fired());
151
152 // Advancing time for the shorter delay will fire the alarm.
153 runner_->FastForwardBy(kNewDelta);
154
155 EXPECT_EQ(quic::QuicTime::Zero() + kNewDelta, clock_.Now());
156 EXPECT_FALSE(alarm->IsSet());
157 EXPECT_TRUE(delegate->fired());
158
159 delegate->Clear();
160 EXPECT_FALSE(delegate->fired());
161
162 // Advancing time for the remaining of the new original delay should not cause
163 // the alarm to fire again.
164 runner_->FastForwardBy(kDelta - kNewDelta);
165
166 EXPECT_EQ(quic::QuicTime::Zero() + kDelta, clock_.Now());
167 EXPECT_FALSE(alarm->IsSet());
168 EXPECT_FALSE(delegate->fired());
169 }
170
TEST_F(QuicChromiumAlarmFactoryTest,CreateAlarmAndUpdate)171 TEST_F(QuicChromiumAlarmFactoryTest, CreateAlarmAndUpdate) {
172 TestDelegate* delegate = new TestDelegate();
173 std::unique_ptr<quic::QuicAlarm> alarm(alarm_factory_.CreateAlarm(delegate));
174
175 // Set the deadline 1µs in the future.
176 constexpr quic::QuicTime::Delta kDelta =
177 quic::QuicTime::Delta::FromMicroseconds(1);
178 quic::QuicTime deadline = clock_.Now() + kDelta;
179 alarm->Set(deadline);
180 EXPECT_TRUE(alarm->IsSet());
181 EXPECT_EQ(alarm->deadline(), deadline);
182 EXPECT_FALSE(delegate->fired());
183
184 // Update the deadline.
185 constexpr quic::QuicTime::Delta kNewDelta =
186 quic::QuicTime::Delta::FromMicroseconds(3);
187 quic::QuicTime new_deadline = clock_.Now() + kNewDelta;
188 alarm->Update(new_deadline, quic::QuicTime::Delta::FromMicroseconds(1));
189 EXPECT_TRUE(alarm->IsSet());
190 EXPECT_EQ(alarm->deadline(), new_deadline);
191 EXPECT_FALSE(delegate->fired());
192
193 // Update the alarm with another delta that is not further away from the
194 // current deadline than the granularity. The deadline should not change.
195 alarm->Update(new_deadline + quic::QuicTime::Delta::FromMicroseconds(1),
196 quic::QuicTime::Delta::FromMicroseconds(2));
197 EXPECT_TRUE(alarm->IsSet());
198 EXPECT_EQ(alarm->deadline(), new_deadline);
199 EXPECT_FALSE(delegate->fired());
200
201 // Advancing time for the first delay should not cause the alarm to fire.
202 runner_->FastForwardBy(kDelta);
203
204 EXPECT_EQ(quic::QuicTime::Zero() + kDelta, clock_.Now());
205 EXPECT_TRUE(alarm->IsSet());
206 EXPECT_FALSE(delegate->fired());
207
208 // Advancing time for the remaining of the new delay will fire the alarm.
209 runner_->FastForwardBy(kNewDelta - kDelta);
210
211 EXPECT_EQ(quic::QuicTime::Zero() + kNewDelta, clock_.Now());
212 EXPECT_FALSE(alarm->IsSet());
213 EXPECT_TRUE(delegate->fired());
214
215 // Set the alarm via an update call.
216 new_deadline = clock_.Now() + quic::QuicTime::Delta::FromMicroseconds(5);
217 alarm->Update(new_deadline, quic::QuicTime::Delta::FromMicroseconds(1));
218 EXPECT_TRUE(alarm->IsSet());
219 EXPECT_EQ(alarm->deadline(), new_deadline);
220
221 // Update it with an uninitialized time and ensure it's cancelled.
222 alarm->Update(quic::QuicTime::Zero(),
223 quic::QuicTime::Delta::FromMicroseconds(1));
224 EXPECT_FALSE(alarm->IsSet());
225 }
226
227 } // namespace
228 } // namespace net::test
229