xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/io/quic_poll_event_loop_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 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/io/quic_poll_event_loop.h"
6 
7 #include <fcntl.h>
8 #include <unistd.h>
9 
10 #include <cerrno>
11 #include <memory>
12 #include <vector>
13 
14 #include "absl/memory/memory.h"
15 #include "quiche/quic/core/io/quic_event_loop.h"
16 #include "quiche/quic/core/quic_alarm.h"
17 #include "quiche/quic/core/quic_alarm_factory.h"
18 #include "quiche/quic/core/quic_time.h"
19 #include "quiche/quic/platform/api/quic_test.h"
20 #include "quiche/quic/test_tools/mock_clock.h"
21 
22 namespace quic {
23 
24 class QuicPollEventLoopPeer {
25  public:
ComputePollTimeout(const QuicPollEventLoop & loop,QuicTime now,QuicTime::Delta default_timeout)26   static QuicTime::Delta ComputePollTimeout(const QuicPollEventLoop& loop,
27                                             QuicTime now,
28                                             QuicTime::Delta default_timeout) {
29     return loop.ComputePollTimeout(now, default_timeout);
30   }
31 };
32 
33 }  // namespace quic
34 
35 namespace quic::test {
36 namespace {
37 
38 using testing::_;
39 using testing::AtMost;
40 using testing::ElementsAre;
41 
42 constexpr QuicSocketEventMask kAllEvents =
43     kSocketEventReadable | kSocketEventWritable | kSocketEventError;
44 constexpr QuicTime::Delta kDefaultTimeout = QuicTime::Delta::FromSeconds(100);
45 
46 class MockQuicSocketEventListener : public QuicSocketEventListener {
47  public:
48   MOCK_METHOD(void, OnSocketEvent,
49               (QuicEventLoop* /*event_loop*/, SocketFd /*fd*/,
50                QuicSocketEventMask /*events*/),
51               (override));
52 };
53 
54 class MockDelegate : public QuicAlarm::Delegate {
55  public:
GetConnectionContext()56   QuicConnectionContext* GetConnectionContext() override { return nullptr; }
57   MOCK_METHOD(void, OnAlarm, (), (override));
58 };
59 
60 class QuicPollEventLoopForTest : public QuicPollEventLoop {
61  public:
QuicPollEventLoopForTest(MockClock * clock)62   QuicPollEventLoopForTest(MockClock* clock)
63       : QuicPollEventLoop(clock), clock_(clock) {}
64 
PollSyscall(pollfd * fds,nfds_t nfds,int timeout)65   int PollSyscall(pollfd* fds, nfds_t nfds, int timeout) override {
66     timeouts_.push_back(timeout);
67     if (eintr_after_ != QuicTime::Delta::Infinite()) {
68       errno = EINTR;
69       clock_->AdvanceTime(eintr_after_);
70       eintr_after_ = QuicTime::Delta::Infinite();
71       return -1;
72     }
73     if (poll_return_after_ != QuicTime::Delta::Infinite()) {
74       clock_->AdvanceTime(poll_return_after_);
75       poll_return_after_ = QuicTime::Delta::Infinite();
76     } else {
77       clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(timeout));
78     }
79 
80     return QuicPollEventLoop::PollSyscall(fds, nfds, timeout);
81   }
82 
TriggerEintrAfter(QuicTime::Delta time)83   void TriggerEintrAfter(QuicTime::Delta time) { eintr_after_ = time; }
ReturnFromPollAfter(QuicTime::Delta time)84   void ReturnFromPollAfter(QuicTime::Delta time) { poll_return_after_ = time; }
85 
timeouts() const86   const std::vector<int>& timeouts() const { return timeouts_; }
87 
88  private:
89   MockClock* clock_;
90   QuicTime::Delta eintr_after_ = QuicTime::Delta::Infinite();
91   QuicTime::Delta poll_return_after_ = QuicTime::Delta::Infinite();
92   std::vector<int> timeouts_;
93 };
94 
95 class QuicPollEventLoopTest : public QuicTest {
96  public:
QuicPollEventLoopTest()97   QuicPollEventLoopTest()
98       : loop_(&clock_), factory_(loop_.CreateAlarmFactory()) {
99     int fds[2];
100     int result = ::pipe(fds);
101     QUICHE_CHECK(result >= 0) << "Failed to create a pipe, errno: " << errno;
102     read_fd_ = fds[0];
103     write_fd_ = fds[1];
104 
105     QUICHE_CHECK(::fcntl(read_fd_, F_SETFL,
106                          ::fcntl(read_fd_, F_GETFL) | O_NONBLOCK) == 0)
107         << "Failed to mark pipe FD non-blocking, errno: " << errno;
108     QUICHE_CHECK(::fcntl(write_fd_, F_SETFL,
109                          ::fcntl(write_fd_, F_GETFL) | O_NONBLOCK) == 0)
110         << "Failed to mark pipe FD non-blocking, errno: " << errno;
111 
112     clock_.AdvanceTime(10 * kDefaultTimeout);
113   }
114 
~QuicPollEventLoopTest()115   ~QuicPollEventLoopTest() {
116     close(read_fd_);
117     close(write_fd_);
118   }
119 
ComputePollTimeout()120   QuicTime::Delta ComputePollTimeout() {
121     return QuicPollEventLoopPeer::ComputePollTimeout(loop_, clock_.Now(),
122                                                      kDefaultTimeout);
123   }
124 
CreateAlarm()125   std::pair<std::unique_ptr<QuicAlarm>, MockDelegate*> CreateAlarm() {
126     auto delegate = std::make_unique<testing::StrictMock<MockDelegate>>();
127     MockDelegate* delegate_unowned = delegate.get();
128     auto alarm = absl::WrapUnique(factory_->CreateAlarm(delegate.release()));
129     return std::make_pair(std::move(alarm), delegate_unowned);
130   }
131 
132  protected:
133   MockClock clock_;
134   QuicPollEventLoopForTest loop_;
135   std::unique_ptr<QuicAlarmFactory> factory_;
136   int read_fd_;
137   int write_fd_;
138 };
139 
TEST_F(QuicPollEventLoopTest,NothingHappens)140 TEST_F(QuicPollEventLoopTest, NothingHappens) {
141   testing::StrictMock<MockQuicSocketEventListener> listener;
142   ASSERT_TRUE(loop_.RegisterSocket(read_fd_, kAllEvents, &listener));
143   ASSERT_TRUE(loop_.RegisterSocket(write_fd_, kAllEvents, &listener));
144 
145   // Attempt double-registration.
146   EXPECT_FALSE(loop_.RegisterSocket(write_fd_, kAllEvents, &listener));
147 
148   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
149 
150   EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable));
151   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(4));
152   // Expect no further calls.
153   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(5));
154   EXPECT_THAT(loop_.timeouts(), ElementsAre(4, 5));
155 }
156 
TEST_F(QuicPollEventLoopTest,RearmWriter)157 TEST_F(QuicPollEventLoopTest, RearmWriter) {
158   testing::StrictMock<MockQuicSocketEventListener> listener;
159   ASSERT_TRUE(loop_.RegisterSocket(write_fd_, kAllEvents, &listener));
160 
161   EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable))
162       .Times(2);
163   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
164   ASSERT_TRUE(loop_.RearmSocket(write_fd_, kSocketEventWritable));
165   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
166 }
167 
TEST_F(QuicPollEventLoopTest,Readable)168 TEST_F(QuicPollEventLoopTest, Readable) {
169   testing::StrictMock<MockQuicSocketEventListener> listener;
170   ASSERT_TRUE(loop_.RegisterSocket(read_fd_, kAllEvents, &listener));
171 
172   ASSERT_EQ(4, write(write_fd_, "test", 4));
173   EXPECT_CALL(listener, OnSocketEvent(_, read_fd_, kSocketEventReadable));
174   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
175   // Expect no further calls.
176   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
177 }
178 
TEST_F(QuicPollEventLoopTest,RearmReader)179 TEST_F(QuicPollEventLoopTest, RearmReader) {
180   testing::StrictMock<MockQuicSocketEventListener> listener;
181   ASSERT_TRUE(loop_.RegisterSocket(read_fd_, kAllEvents, &listener));
182 
183   ASSERT_EQ(4, write(write_fd_, "test", 4));
184   EXPECT_CALL(listener, OnSocketEvent(_, read_fd_, kSocketEventReadable));
185   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
186   // Expect no further calls.
187   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
188 }
189 
TEST_F(QuicPollEventLoopTest,WriterUnblocked)190 TEST_F(QuicPollEventLoopTest, WriterUnblocked) {
191   testing::StrictMock<MockQuicSocketEventListener> listener;
192   ASSERT_TRUE(loop_.RegisterSocket(write_fd_, kAllEvents, &listener));
193 
194   EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable));
195   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
196   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
197 
198   int io_result;
199   std::string data(2048, 'a');
200   do {
201     io_result = write(write_fd_, data.data(), data.size());
202   } while (io_result > 0);
203   ASSERT_EQ(errno, EAGAIN);
204 
205   // Rearm and expect no immediate calls.
206   ASSERT_TRUE(loop_.RearmSocket(write_fd_, kSocketEventWritable));
207   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
208 
209   EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable));
210   do {
211     io_result = read(read_fd_, data.data(), data.size());
212   } while (io_result > 0);
213   ASSERT_EQ(errno, EAGAIN);
214   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
215 }
216 
TEST_F(QuicPollEventLoopTest,ArtificialEvent)217 TEST_F(QuicPollEventLoopTest, ArtificialEvent) {
218   testing::StrictMock<MockQuicSocketEventListener> listener;
219   ASSERT_TRUE(loop_.RegisterSocket(read_fd_, kAllEvents, &listener));
220   ASSERT_TRUE(loop_.RegisterSocket(write_fd_, kAllEvents, &listener));
221 
222   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
223   ASSERT_TRUE(loop_.ArtificiallyNotifyEvent(read_fd_, kSocketEventReadable));
224   EXPECT_EQ(ComputePollTimeout(), QuicTime::Delta::Zero());
225 
226   {
227     testing::InSequence s;
228     EXPECT_CALL(listener, OnSocketEvent(_, read_fd_, kSocketEventReadable));
229     EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable));
230   }
231   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
232   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
233 }
234 
TEST_F(QuicPollEventLoopTest,Unregister)235 TEST_F(QuicPollEventLoopTest, Unregister) {
236   testing::StrictMock<MockQuicSocketEventListener> listener;
237   ASSERT_TRUE(loop_.RegisterSocket(write_fd_, kAllEvents, &listener));
238   ASSERT_TRUE(loop_.UnregisterSocket(write_fd_));
239 
240   // Expect nothing to happen.
241   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
242 
243   EXPECT_FALSE(loop_.UnregisterSocket(write_fd_));
244   EXPECT_FALSE(loop_.RearmSocket(write_fd_, kSocketEventWritable));
245   EXPECT_FALSE(loop_.ArtificiallyNotifyEvent(write_fd_, kSocketEventWritable));
246 }
247 
TEST_F(QuicPollEventLoopTest,UnregisterInsideEventHandler)248 TEST_F(QuicPollEventLoopTest, UnregisterInsideEventHandler) {
249   testing::StrictMock<MockQuicSocketEventListener> listener;
250   ASSERT_TRUE(loop_.RegisterSocket(read_fd_, kAllEvents, &listener));
251   ASSERT_TRUE(loop_.RegisterSocket(write_fd_, kAllEvents, &listener));
252 
253   EXPECT_CALL(listener, OnSocketEvent(_, read_fd_, kSocketEventReadable))
254       .WillOnce([this]() { ASSERT_TRUE(loop_.UnregisterSocket(write_fd_)); });
255   EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable))
256       .Times(0);
257   ASSERT_TRUE(loop_.ArtificiallyNotifyEvent(read_fd_, kSocketEventReadable));
258   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
259 }
260 
TEST_F(QuicPollEventLoopTest,EintrHandler)261 TEST_F(QuicPollEventLoopTest, EintrHandler) {
262   testing::StrictMock<MockQuicSocketEventListener> listener;
263   ASSERT_TRUE(loop_.RegisterSocket(read_fd_, kAllEvents, &listener));
264 
265   loop_.TriggerEintrAfter(QuicTime::Delta::FromMilliseconds(25));
266   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(100));
267   EXPECT_THAT(loop_.timeouts(), ElementsAre(100, 75));
268 }
269 
TEST_F(QuicPollEventLoopTest,PollReturnsEarly)270 TEST_F(QuicPollEventLoopTest, PollReturnsEarly) {
271   testing::StrictMock<MockQuicSocketEventListener> listener;
272   ASSERT_TRUE(loop_.RegisterSocket(read_fd_, kAllEvents, &listener));
273 
274   loop_.ReturnFromPollAfter(QuicTime::Delta::FromMilliseconds(25));
275   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(100));
276   EXPECT_THAT(loop_.timeouts(), ElementsAre(100, 75));
277 }
278 
TEST_F(QuicPollEventLoopTest,AlarmInFuture)279 TEST_F(QuicPollEventLoopTest, AlarmInFuture) {
280   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
281 
282   constexpr auto kAlarmTimeout = QuicTime::Delta::FromMilliseconds(5);
283   auto [alarm, delegate] = CreateAlarm();
284   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
285 
286   alarm->Set(clock_.Now() + kAlarmTimeout);
287   EXPECT_EQ(ComputePollTimeout(), kAlarmTimeout);
288 
289   EXPECT_CALL(*delegate, OnAlarm());
290   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(100));
291   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
292 }
293 
TEST_F(QuicPollEventLoopTest,AlarmsInPast)294 TEST_F(QuicPollEventLoopTest, AlarmsInPast) {
295   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
296 
297   constexpr auto kAlarmTimeout = QuicTime::Delta::FromMilliseconds(5);
298   auto [alarm1, delegate1] = CreateAlarm();
299   auto [alarm2, delegate2] = CreateAlarm();
300 
301   alarm1->Set(clock_.Now() - 2 * kAlarmTimeout);
302   alarm2->Set(clock_.Now() - kAlarmTimeout);
303 
304   {
305     testing::InSequence s;
306     EXPECT_CALL(*delegate1, OnAlarm());
307     EXPECT_CALL(*delegate2, OnAlarm());
308   }
309   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(100));
310 }
311 
TEST_F(QuicPollEventLoopTest,AlarmCancelled)312 TEST_F(QuicPollEventLoopTest, AlarmCancelled) {
313   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
314 
315   constexpr auto kAlarmTimeout = QuicTime::Delta::FromMilliseconds(5);
316   auto [alarm, delegate] = CreateAlarm();
317   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
318 
319   alarm->Set(clock_.Now() + kAlarmTimeout);
320   alarm->Cancel();
321   alarm->Set(clock_.Now() + 2 * kAlarmTimeout);
322   EXPECT_EQ(ComputePollTimeout(), kAlarmTimeout);
323 
324   EXPECT_CALL(*delegate, OnAlarm());
325   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(100));
326   EXPECT_THAT(loop_.timeouts(), ElementsAre(10));
327   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
328 }
329 
TEST_F(QuicPollEventLoopTest,AlarmCancelsAnotherAlarm)330 TEST_F(QuicPollEventLoopTest, AlarmCancelsAnotherAlarm) {
331   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
332 
333   constexpr auto kAlarmTimeout = QuicTime::Delta::FromMilliseconds(5);
334   auto [alarm1_ptr, delegate1] = CreateAlarm();
335   auto [alarm2_ptr, delegate2] = CreateAlarm();
336 
337   QuicAlarm& alarm1 = *alarm1_ptr;
338   QuicAlarm& alarm2 = *alarm2_ptr;
339   alarm1.Set(clock_.Now() - kAlarmTimeout);
340   alarm2.Set(clock_.Now() - kAlarmTimeout);
341 
342   int alarms_called = 0;
343   // Since the order in which alarms are cancelled is not well-determined, make
344   // each one cancel another.
345   EXPECT_CALL(*delegate1, OnAlarm()).Times(AtMost(1)).WillOnce([&]() {
346     alarm2.Cancel();
347     ++alarms_called;
348   });
349   EXPECT_CALL(*delegate2, OnAlarm()).Times(AtMost(1)).WillOnce([&]() {
350     alarm1.Cancel();
351     ++alarms_called;
352   });
353   loop_.RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(100));
354   EXPECT_EQ(alarms_called, 1);
355   EXPECT_EQ(ComputePollTimeout(), kDefaultTimeout);
356 }
357 
358 }  // namespace
359 }  // namespace quic::test
360