blob: 04343cca9099470e4fb8bd0ee31baab424324cd6 [file] [log] [blame]
Parker Schuhe4a70d62017-12-27 20:10:20 -08001#include "aos/events/event-loop_param_test.h"
2
Austin Schuh52d325c2019-06-23 18:59:06 -07003#include <chrono>
4
Austin Schuh3578a2e2019-05-25 18:17:59 -07005#include "gmock/gmock.h"
6#include "gtest/gtest.h"
7
Austin Schuhf257f3c2019-10-27 21:00:43 -07008#include "glog/logging.h"
Austin Schuh9fe68f72019-08-10 19:32:03 -07009
Parker Schuhe4a70d62017-12-27 20:10:20 -080010namespace aos {
11namespace testing {
Austin Schuh52d325c2019-06-23 18:59:06 -070012namespace {
13namespace chrono = ::std::chrono;
14} // namespace
Parker Schuhe4a70d62017-12-27 20:10:20 -080015
16struct TestMessage : public ::aos::Message {
17 enum { kQueueLength = 100, kHash = 0x696c0cdc };
18 int msg_value;
19
Austin Schuh7267c532019-05-19 19:55:53 -070020 void Zero() {
21 ::aos::Message::Zero();
22 msg_value = 0;
23 }
Parker Schuhe4a70d62017-12-27 20:10:20 -080024 static size_t Size() { return 1 + ::aos::Message::Size(); }
25 size_t Print(char *buffer, size_t length) const;
26 TestMessage() { Zero(); }
27};
28
Austin Schuh6b6dfa52019-06-12 20:16:20 -070029// Tests that watcher can receive messages from a sender.
Parker Schuhe4a70d62017-12-27 20:10:20 -080030// Also tests that OnRun() works.
31TEST_P(AbstractEventLoopTest, Basic) {
32 auto loop1 = Make();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070033 auto loop2 = MakePrimary();
34
35 auto sender = loop1->MakeSender<TestMessage>("/test");
36
37 bool happened = false;
38
39 loop2->OnRun([&]() {
40 happened = true;
41
42 auto msg = sender.MakeMessage();
43 msg->msg_value = 200;
44 msg.Send();
45 });
46
47 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
48 EXPECT_EQ(message.msg_value, 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -070049 this->Exit();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070050 });
51
52 EXPECT_FALSE(happened);
53 Run();
54 EXPECT_TRUE(happened);
55}
56
57// Tests that a fetcher can fetch from a sender.
58// Also tests that OnRun() works.
59TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
60 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -080061 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -070062 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -080063
64 auto sender = loop1->MakeSender<TestMessage>("/test");
65
66 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
67
Austin Schuhbbce72d2019-05-26 15:11:46 -070068 EXPECT_FALSE(fetcher.Fetch());
69
Austin Schuh3578a2e2019-05-25 18:17:59 -070070 auto msg = sender.MakeMessage();
71 msg->msg_value = 200;
72 msg.Send();
73
74 EXPECT_TRUE(fetcher.Fetch());
75 ASSERT_FALSE(fetcher.get() == nullptr);
76 EXPECT_EQ(fetcher->msg_value, 200);
Parker Schuhe4a70d62017-12-27 20:10:20 -080077}
78
Austin Schuh3578a2e2019-05-25 18:17:59 -070079// Tests that watcher will receive all messages sent if they are sent after
80// initialization and before running.
81TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
82 auto loop1 = Make();
83 auto loop2 = MakePrimary();
84
85 auto sender = loop1->MakeSender<TestMessage>("/test");
86
87 ::std::vector<int> values;
88
89 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Austin Schuh3578a2e2019-05-25 18:17:59 -070090 values.push_back(message.msg_value);
91 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -070092 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -070093 }
94 });
95
Austin Schuh6b6dfa52019-06-12 20:16:20 -070096 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -070097 {
98 auto msg = sender.MakeMessage();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070099 msg->msg_value = 199;
Austin Schuh3578a2e2019-05-25 18:17:59 -0700100 msg.Send();
101 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700102
103 loop2->OnRun([&]() {
104 {
105 auto msg = sender.MakeMessage();
106 msg->msg_value = 200;
107 msg.Send();
108 }
109 {
110 auto msg = sender.MakeMessage();
111 msg->msg_value = 201;
112 msg.Send();
113 }
114 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700115
116 Run();
117
118 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
119}
120
121// Tests that watcher will not receive messages sent before the watcher is
122// created.
123TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
124 auto loop1 = Make();
125 auto loop2 = MakePrimary();
126
127 auto sender = loop1->MakeSender<TestMessage>("/test");
128
129 ::std::vector<int> values;
130
131 {
132 auto msg = sender.MakeMessage();
133 msg->msg_value = 200;
134 msg.Send();
135 }
136 {
137 auto msg = sender.MakeMessage();
138 msg->msg_value = 201;
139 msg.Send();
140 }
141
142 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
143 values.push_back(message.msg_value);
144 });
145
146 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700147 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700148 loop2->OnRun([&test_timer, &loop2]() {
149 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
150 });
151
152 Run();
153 EXPECT_EQ(0, values.size());
154}
155
Austin Schuhbbce72d2019-05-26 15:11:46 -0700156// Tests that FetchNext gets all the messages sent after it is constructed.
157TEST_P(AbstractEventLoopTest, FetchNext) {
158 auto loop1 = Make();
159 auto loop2 = MakePrimary();
160
161 auto sender = loop1->MakeSender<TestMessage>("/test");
162 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
163
164 ::std::vector<int> values;
165
166 {
167 auto msg = sender.MakeMessage();
168 msg->msg_value = 200;
169 msg.Send();
170 }
171 {
172 auto msg = sender.MakeMessage();
173 msg->msg_value = 201;
174 msg.Send();
175 }
176
177 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700178 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700179 while (fetcher.FetchNext()) {
180 values.push_back(fetcher->msg_value);
181 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700182 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700183 });
184
185 loop2->OnRun([&test_timer, &loop2]() {
186 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
187 });
188
189 Run();
190 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
191}
192
193// Tests that FetchNext gets no messages sent before it is constructed.
194TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
195 auto loop1 = Make();
196 auto loop2 = MakePrimary();
197
198 auto sender = loop1->MakeSender<TestMessage>("/test");
199
200 ::std::vector<int> values;
201
202 {
203 auto msg = sender.MakeMessage();
204 msg->msg_value = 200;
205 msg.Send();
206 }
207 {
208 auto msg = sender.MakeMessage();
209 msg->msg_value = 201;
210 msg.Send();
211 }
212
213 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
214
215 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700216 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700217 while (fetcher.FetchNext()) {
218 values.push_back(fetcher->msg_value);
219 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700220 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700221 });
222
223 loop2->OnRun([&test_timer, &loop2]() {
224 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
225 });
226
227 Run();
228 EXPECT_THAT(0, values.size());
229}
230
231// Tests that Fetch returns the last message created before the loop was
232// started.
233TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
234 auto loop1 = Make();
235 auto loop2 = MakePrimary();
236
237 auto sender = loop1->MakeSender<TestMessage>("/test");
238
239 ::std::vector<int> values;
240
241 {
242 auto msg = sender.MakeMessage();
243 msg->msg_value = 200;
244 msg.Send();
245 }
246 {
247 auto msg = sender.MakeMessage();
248 msg->msg_value = 201;
249 msg.Send();
250 }
251
252 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
253
254 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700255 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700256 if (fetcher.Fetch()) {
257 values.push_back(fetcher->msg_value);
258 }
259 // Do it again to make sure we don't double fetch.
260 if (fetcher.Fetch()) {
261 values.push_back(fetcher->msg_value);
262 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700263 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700264 });
265
266 loop2->OnRun([&test_timer, &loop2]() {
267 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
268 });
269
270 Run();
271 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
272}
273
274// Tests that Fetch and FetchNext interleave as expected.
275TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
276 auto loop1 = Make();
277 auto loop2 = MakePrimary();
278
279 auto sender = loop1->MakeSender<TestMessage>("/test");
280
281 ::std::vector<int> values;
282
283 {
284 auto msg = sender.MakeMessage();
285 msg->msg_value = 200;
286 msg.Send();
287 }
288 {
289 auto msg = sender.MakeMessage();
290 msg->msg_value = 201;
291 msg.Send();
292 }
293
294 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
295
296 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700297 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700298 if (fetcher.Fetch()) {
299 values.push_back(fetcher->msg_value);
300 }
301
302 {
303 auto msg = sender.MakeMessage();
304 msg->msg_value = 202;
305 msg.Send();
306 }
307 {
308 auto msg = sender.MakeMessage();
309 msg->msg_value = 203;
310 msg.Send();
311 }
312 {
313 auto msg = sender.MakeMessage();
314 msg->msg_value = 204;
315 msg.Send();
316 }
317
318 if (fetcher.FetchNext()) {
319 values.push_back(fetcher->msg_value);
320 }
321
322 if (fetcher.Fetch()) {
323 values.push_back(fetcher->msg_value);
324 }
325
Austin Schuh9fe68f72019-08-10 19:32:03 -0700326 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700327 });
328
329 loop2->OnRun([&test_timer, &loop2]() {
330 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
331 });
332
333 Run();
334 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
335}
336
Austin Schuh3115a202019-05-27 21:02:14 -0700337
338// Tests that FetchNext behaves correctly when we get two messages in the queue
339// but don't consume the first until after the second has been sent.
340TEST_P(AbstractEventLoopTest, FetchNextTest) {
341
342 auto send_loop = Make();
343 auto fetch_loop = Make();
344 auto sender = send_loop->MakeSender<TestMessage>("/test");
345 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
346
347 {
348 auto msg = sender.MakeMessage();
349 msg->msg_value = 100;
350 ASSERT_TRUE(msg.Send());
351 }
352
353 {
354 auto msg = sender.MakeMessage();
355 msg->msg_value = 200;
356 ASSERT_TRUE(msg.Send());
357 }
358
359 ASSERT_TRUE(fetcher.FetchNext());
360 ASSERT_NE(nullptr, fetcher.get());
361 EXPECT_EQ(100, fetcher->msg_value);
362
363 ASSERT_TRUE(fetcher.FetchNext());
364 ASSERT_NE(nullptr, fetcher.get());
365 EXPECT_EQ(200, fetcher->msg_value);
366
367 // When we run off the end of the queue, expect to still have the old message:
368 ASSERT_FALSE(fetcher.FetchNext());
369 ASSERT_NE(nullptr, fetcher.get());
370 EXPECT_EQ(200, fetcher->msg_value);
371}
372
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800373// Verify that making a fetcher and watcher for "/test" succeeds.
374TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800375 auto loop = Make();
376 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800377 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800378}
379
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800380// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800381TEST_P(AbstractEventLoopTest, TwoFetcher) {
382 auto loop = Make();
383 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800384 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800385}
386
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800387// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700388TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800389 auto loop = Make();
390 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800391 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
392 "/test");
393}
394
Austin Schuh3115a202019-05-27 21:02:14 -0700395// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700396TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700397 auto loop = MakePrimary();
398 // Confirm that runtime priority calls work when not realtime.
399 loop->SetRuntimeRealtimePriority(5);
400
401 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
402
403 EXPECT_DEATH(Run(), "realtime");
404}
405
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800406// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700407TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800408 auto loop = Make();
409 auto sender = loop->MakeSender<TestMessage>("/test");
410 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
411 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800412}
413
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700414// Verify that we can't create a sender inside OnRun.
415TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
416 auto loop1 = MakePrimary();
417
418 loop1->OnRun(
419 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
420
421 EXPECT_DEATH(Run(), "running");
422}
423
424// Verify that we can't create a watcher inside OnRun.
425TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
426 auto loop1 = MakePrimary();
427
428 loop1->OnRun(
429 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
430
431 EXPECT_DEATH(Run(), "running");
432}
433
Parker Schuhe4a70d62017-12-27 20:10:20 -0800434// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800435TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
436 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700437 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800438
Austin Schuh3578a2e2019-05-25 18:17:59 -0700439 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
440 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
441 EXPECT_EQ(message.msg_value, 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700442 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700443 });
444
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800445 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700446
447 loop2->OnRun([&]() {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800448 auto msg = sender.MakeMessage();
449 msg->msg_value = 200;
450 msg.Send();
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700451 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800452
Austin Schuh44019f92019-05-19 19:58:27 -0700453 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800454}
455
Neil Balch229001a2018-01-07 18:22:52 -0800456// Verify that timer intervals and duration function properly.
457TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh44019f92019-05-19 19:58:27 -0700458 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800459 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
460
461 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
462 iteration_list.push_back(loop->monotonic_now());
463 });
464
Austin Schuh52d325c2019-06-23 18:59:06 -0700465 // TODO(austin): This should be an error... Should be done in OnRun only.
Neil Balch229001a2018-01-07 18:22:52 -0800466 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
467 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
468 // Testing that the timer thread waits for the event loop to start before
469 // running
470 ::std::this_thread::sleep_for(std::chrono::milliseconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700471 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800472
473 EXPECT_EQ(iteration_list.size(), 8);
474}
475
476// Verify that we can change a timer's parameters during execution.
477TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700478 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800479 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
480
481 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
482 iteration_list.push_back(loop->monotonic_now());
483 });
484
485 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
486 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
487 });
488
Neil Balch229001a2018-01-07 18:22:52 -0800489 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
490 modifier_timer->Setup(loop->monotonic_now() +
491 ::std::chrono::milliseconds(45));
492 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700493 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800494
495 EXPECT_EQ(iteration_list.size(), 7);
496}
497
498// Verify that we can disable a timer during execution.
499TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700500 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800501 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
502
503 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
504 iteration_list.push_back(loop->monotonic_now());
505 });
506
507 auto ender_timer = loop->AddTimer([&test_timer]() {
508 test_timer->Disable();
509 });
510
511 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
512 ender_timer->Setup(loop->monotonic_now() +
513 ::std::chrono::milliseconds(45));
514 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700515 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800516
517 EXPECT_EQ(iteration_list.size(), 3);
518}
Austin Schuh7267c532019-05-19 19:55:53 -0700519
520// Verify that the send time on a message is roughly right.
521TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700522 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700523 auto loop2 = Make();
524 auto sender = loop1->MakeSender<TestMessage>("/test");
525 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
526
527 auto test_timer = loop1->AddTimer([&sender]() {
528 auto msg = sender.MakeMessage();
529 msg->msg_value = 200;
530 msg.Send();
531 });
532
533 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
534
535 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700536 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700537
538 EXPECT_TRUE(fetcher.Fetch());
539
540 monotonic_clock::duration time_offset =
541 fetcher->sent_time - (loop1->monotonic_now() - ::std::chrono::seconds(1));
542
543 EXPECT_TRUE(time_offset > ::std::chrono::milliseconds(-500))
Austin Schuh52d325c2019-06-23 18:59:06 -0700544 << ": Got " << fetcher->sent_time.time_since_epoch().count()
545 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -0700546 EXPECT_TRUE(time_offset < ::std::chrono::milliseconds(500))
547 << ": Got " << fetcher->sent_time.time_since_epoch().count()
548 << " expected " << loop1->monotonic_now().time_since_epoch().count();
549}
550
Austin Schuh52d325c2019-06-23 18:59:06 -0700551// Tests that a couple phased loops run in a row result in the correct offset
552// and period.
553TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
554 const chrono::milliseconds kOffset = chrono::milliseconds(400);
555 const int kCount = 5;
556
557 auto loop1 = MakePrimary();
558
559 // Collect up a couple of samples.
560 ::std::vector<::aos::monotonic_clock::time_point> times;
561
562 // Run kCount iterations.
563 loop1->AddPhasedLoop(
Austin Schuh9fe68f72019-08-10 19:32:03 -0700564 [&times, &loop1, this](int count) {
Austin Schuh52d325c2019-06-23 18:59:06 -0700565 EXPECT_EQ(count, 1);
566 times.push_back(loop1->monotonic_now());
Austin Schuhf257f3c2019-10-27 21:00:43 -0700567 LOG(INFO) << times.size();
Austin Schuh52d325c2019-06-23 18:59:06 -0700568 if (times.size() == kCount) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700569 this->Exit();
Austin Schuh52d325c2019-06-23 18:59:06 -0700570 }
571 },
572 chrono::seconds(1), kOffset);
573
574 // Add a delay to make sure that delay during startup doesn't result in a
575 // "missed cycle".
576 SleepFor(chrono::seconds(2));
577
578 Run();
579
580 // Confirm that we got both the right number of samples, and it's odd.
581 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
582 EXPECT_EQ((times.size() % 2), 1);
583
584 // Grab the middle sample.
585 ::aos::monotonic_clock::time_point middle_time = times[times.size() / 2 + 1];
586
587 // Add up all the delays of all the times.
588 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
589 for (const ::aos::monotonic_clock::time_point time : times) {
590 sum += time - middle_time;
591 }
592
593 // Average and add to the middle to find the average time.
594 sum /= times.size();
595 middle_time += sum;
596
597 // Compute the offset from the start of the second of the average time. This
598 // should be pretty close to the offset.
599 const ::aos::monotonic_clock::duration remainder =
600 middle_time.time_since_epoch() -
601 chrono::duration_cast<chrono::seconds>(middle_time.time_since_epoch());
602
603 const chrono::milliseconds kEpsilon(100);
604 EXPECT_LT(remainder, kOffset + kEpsilon);
605 EXPECT_GT(remainder, kOffset - kEpsilon);
606
607 // Make sure that the average duration is close to 1 second.
608 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
609 times.front())
610 .count() /
611 static_cast<double>(times.size() - 1),
612 1.0, 0.1);
613}
614
Austin Schuh1fa7f392019-06-30 14:52:23 -0700615// Verify that sending lots and lots of messages and using FetchNext gets a
616// contiguous block of messages and doesn't crash.
617// TODO(austin): We should store the same number of messages in simulation and
618// reality.
619TEST_P(AbstractEventLoopTest, LotsOfSends) {
620 auto loop1 = MakePrimary();
621 auto loop2 = Make();
622 auto sender = loop1->MakeSender<TestMessage>("/test");
623 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
624
Austin Schuh9fe68f72019-08-10 19:32:03 -0700625 auto test_timer = loop1->AddTimer([&sender, &fetcher, this]() {
Austin Schuh1fa7f392019-06-30 14:52:23 -0700626 for (int i = 0; i < 100000; ++i) {
627 auto msg = sender.MakeMessage();
628 msg->msg_value = i;
629 msg.Send();
630 }
631
632 int last = 0;
633 if (fetcher.FetchNext()) {
634 last = fetcher->msg_value;
635 }
636 while (fetcher.FetchNext()) {
637 EXPECT_EQ(last + 1, fetcher->msg_value);
638 ++last;
639 }
640
Austin Schuh9fe68f72019-08-10 19:32:03 -0700641 this->Exit();
Austin Schuh1fa7f392019-06-30 14:52:23 -0700642 });
643
644 loop1->OnRun([&test_timer, &loop1]() {
645 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::milliseconds(10));
646 });
647
648 Run();
649}
650
Parker Schuhe4a70d62017-12-27 20:10:20 -0800651} // namespace testing
652} // namespace aos