blob: c74538cd41efa69d13c4f90c8f9feed8c304a1ea [file] [log] [blame]
Parker Schuhe4a70d62017-12-27 20:10:20 -08001#include "aos/events/event-loop_param_test.h"
2
Austin Schuh3578a2e2019-05-25 18:17:59 -07003#include "gmock/gmock.h"
4#include "gtest/gtest.h"
5
Parker Schuhe4a70d62017-12-27 20:10:20 -08006namespace aos {
7namespace testing {
8
9struct TestMessage : public ::aos::Message {
10 enum { kQueueLength = 100, kHash = 0x696c0cdc };
11 int msg_value;
12
Austin Schuh7267c532019-05-19 19:55:53 -070013 void Zero() {
14 ::aos::Message::Zero();
15 msg_value = 0;
16 }
Parker Schuhe4a70d62017-12-27 20:10:20 -080017 static size_t Size() { return 1 + ::aos::Message::Size(); }
18 size_t Print(char *buffer, size_t length) const;
19 TestMessage() { Zero(); }
20};
21
Neil Balch229001a2018-01-07 18:22:52 -080022// Ends the given event loop at the given time from now.
23void EndEventLoop(EventLoop *loop, ::std::chrono::milliseconds duration) {
24 auto end_timer = loop->AddTimer([loop]() { loop->Exit(); });
25 end_timer->Setup(loop->monotonic_now() +
26 ::std::chrono::milliseconds(duration));
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);
49 loop2->Exit();
50 });
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) {
92 loop2->Exit();
93 }
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.
147 auto test_timer = loop2->AddTimer([&loop2]() { loop2->Exit(); });
148 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.
178 auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values]() {
179 while (fetcher.FetchNext()) {
180 values.push_back(fetcher->msg_value);
181 }
182 loop2->Exit();
183 });
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.
216 auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values]() {
217 while (fetcher.FetchNext()) {
218 values.push_back(fetcher->msg_value);
219 }
220 loop2->Exit();
221 });
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.
255 auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values]() {
256 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 }
263 loop2->Exit();
264 });
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.
297 auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values, &sender]() {
298 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
326 loop2->Exit();
327 });
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);
442 loop2->Exit();
443 });
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
465 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
466 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
467 // Testing that the timer thread waits for the event loop to start before
468 // running
469 ::std::this_thread::sleep_for(std::chrono::milliseconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700470 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800471
472 EXPECT_EQ(iteration_list.size(), 8);
473}
474
475// Verify that we can change a timer's parameters during execution.
476TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700477 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800478 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
479
480 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
481 iteration_list.push_back(loop->monotonic_now());
482 });
483
484 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
485 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
486 });
487
488
489 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))
544 << ": Got " << fetcher->sent_time.time_since_epoch().count() << " expected "
545 << loop1->monotonic_now().time_since_epoch().count();
546 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
Parker Schuhe4a70d62017-12-27 20:10:20 -0800551} // namespace testing
552} // namespace aos