blob: 5276aec1c48a5f1abc5d0c85705cdb6d9e5ddda6 [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
Parker Schuhe4a70d62017-12-27 20:10:20 -080029// Tests that watcher and fetcher can fetch from a sender.
30// Also tests that OnRun() works.
31TEST_P(AbstractEventLoopTest, Basic) {
32 auto loop1 = Make();
33 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -070034 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -080035
36 auto sender = loop1->MakeSender<TestMessage>("/test");
37
38 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
39
Austin Schuhbbce72d2019-05-26 15:11:46 -070040 EXPECT_FALSE(fetcher.Fetch());
41
Parker Schuhe4a70d62017-12-27 20:10:20 -080042 bool happened = false;
43
44 loop3->OnRun([&]() { happened = true; });
45
46 loop3->MakeWatcher("/test", [&](const TestMessage &message) {
47 EXPECT_EQ(message.msg_value, 200);
48 loop3->Exit();
49 });
50
Austin Schuh3578a2e2019-05-25 18:17:59 -070051 auto msg = sender.MakeMessage();
52 msg->msg_value = 200;
53 msg.Send();
54
55 EXPECT_TRUE(fetcher.Fetch());
56 ASSERT_FALSE(fetcher.get() == nullptr);
57 EXPECT_EQ(fetcher->msg_value, 200);
58
Parker Schuhe4a70d62017-12-27 20:10:20 -080059 EXPECT_FALSE(happened);
Austin Schuh44019f92019-05-19 19:58:27 -070060 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -080061 EXPECT_TRUE(happened);
62}
63
Austin Schuh3578a2e2019-05-25 18:17:59 -070064// Tests that watcher will receive all messages sent if they are sent after
65// initialization and before running.
66TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
67 auto loop1 = Make();
68 auto loop2 = MakePrimary();
69
70 auto sender = loop1->MakeSender<TestMessage>("/test");
71
72 ::std::vector<int> values;
73
74 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Austin Schuh3578a2e2019-05-25 18:17:59 -070075 values.push_back(message.msg_value);
76 if (values.size() == 2) {
77 loop2->Exit();
78 }
79 });
80
81 {
82 auto msg = sender.MakeMessage();
83 msg->msg_value = 200;
84 msg.Send();
85 }
86 {
87 auto msg = sender.MakeMessage();
88 msg->msg_value = 201;
89 msg.Send();
90 }
91
92 Run();
93
94 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
95}
96
97// Tests that watcher will not receive messages sent before the watcher is
98// created.
99TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
100 auto loop1 = Make();
101 auto loop2 = MakePrimary();
102
103 auto sender = loop1->MakeSender<TestMessage>("/test");
104
105 ::std::vector<int> values;
106
107 {
108 auto msg = sender.MakeMessage();
109 msg->msg_value = 200;
110 msg.Send();
111 }
112 {
113 auto msg = sender.MakeMessage();
114 msg->msg_value = 201;
115 msg.Send();
116 }
117
118 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
119 values.push_back(message.msg_value);
120 });
121
122 // Add a timer to actually quit.
123 auto test_timer = loop2->AddTimer([&loop2]() { loop2->Exit(); });
124 loop2->OnRun([&test_timer, &loop2]() {
125 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
126 });
127
128 Run();
129 EXPECT_EQ(0, values.size());
130}
131
Austin Schuhbbce72d2019-05-26 15:11:46 -0700132// Tests that FetchNext gets all the messages sent after it is constructed.
133TEST_P(AbstractEventLoopTest, FetchNext) {
134 auto loop1 = Make();
135 auto loop2 = MakePrimary();
136
137 auto sender = loop1->MakeSender<TestMessage>("/test");
138 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
139
140 ::std::vector<int> values;
141
142 {
143 auto msg = sender.MakeMessage();
144 msg->msg_value = 200;
145 msg.Send();
146 }
147 {
148 auto msg = sender.MakeMessage();
149 msg->msg_value = 201;
150 msg.Send();
151 }
152
153 // Add a timer to actually quit.
154 auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values]() {
155 while (fetcher.FetchNext()) {
156 values.push_back(fetcher->msg_value);
157 }
158 loop2->Exit();
159 });
160
161 loop2->OnRun([&test_timer, &loop2]() {
162 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
163 });
164
165 Run();
166 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
167}
168
169// Tests that FetchNext gets no messages sent before it is constructed.
170TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
171 auto loop1 = Make();
172 auto loop2 = MakePrimary();
173
174 auto sender = loop1->MakeSender<TestMessage>("/test");
175
176 ::std::vector<int> values;
177
178 {
179 auto msg = sender.MakeMessage();
180 msg->msg_value = 200;
181 msg.Send();
182 }
183 {
184 auto msg = sender.MakeMessage();
185 msg->msg_value = 201;
186 msg.Send();
187 }
188
189 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
190
191 // Add a timer to actually quit.
192 auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values]() {
193 while (fetcher.FetchNext()) {
194 values.push_back(fetcher->msg_value);
195 }
196 loop2->Exit();
197 });
198
199 loop2->OnRun([&test_timer, &loop2]() {
200 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
201 });
202
203 Run();
204 EXPECT_THAT(0, values.size());
205}
206
207// Tests that Fetch returns the last message created before the loop was
208// started.
209TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
210 auto loop1 = Make();
211 auto loop2 = MakePrimary();
212
213 auto sender = loop1->MakeSender<TestMessage>("/test");
214
215 ::std::vector<int> values;
216
217 {
218 auto msg = sender.MakeMessage();
219 msg->msg_value = 200;
220 msg.Send();
221 }
222 {
223 auto msg = sender.MakeMessage();
224 msg->msg_value = 201;
225 msg.Send();
226 }
227
228 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
229
230 // Add a timer to actually quit.
231 auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values]() {
232 if (fetcher.Fetch()) {
233 values.push_back(fetcher->msg_value);
234 }
235 // Do it again to make sure we don't double fetch.
236 if (fetcher.Fetch()) {
237 values.push_back(fetcher->msg_value);
238 }
239 loop2->Exit();
240 });
241
242 loop2->OnRun([&test_timer, &loop2]() {
243 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
244 });
245
246 Run();
247 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
248}
249
250// Tests that Fetch and FetchNext interleave as expected.
251TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
252 auto loop1 = Make();
253 auto loop2 = MakePrimary();
254
255 auto sender = loop1->MakeSender<TestMessage>("/test");
256
257 ::std::vector<int> values;
258
259 {
260 auto msg = sender.MakeMessage();
261 msg->msg_value = 200;
262 msg.Send();
263 }
264 {
265 auto msg = sender.MakeMessage();
266 msg->msg_value = 201;
267 msg.Send();
268 }
269
270 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
271
272 // Add a timer to actually quit.
273 auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values, &sender]() {
274 if (fetcher.Fetch()) {
275 values.push_back(fetcher->msg_value);
276 }
277
278 {
279 auto msg = sender.MakeMessage();
280 msg->msg_value = 202;
281 msg.Send();
282 }
283 {
284 auto msg = sender.MakeMessage();
285 msg->msg_value = 203;
286 msg.Send();
287 }
288 {
289 auto msg = sender.MakeMessage();
290 msg->msg_value = 204;
291 msg.Send();
292 }
293
294 if (fetcher.FetchNext()) {
295 values.push_back(fetcher->msg_value);
296 }
297
298 if (fetcher.Fetch()) {
299 values.push_back(fetcher->msg_value);
300 }
301
302 loop2->Exit();
303 });
304
305 loop2->OnRun([&test_timer, &loop2]() {
306 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
307 });
308
309 Run();
310 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
311}
312
Austin Schuh3115a202019-05-27 21:02:14 -0700313
314// Tests that FetchNext behaves correctly when we get two messages in the queue
315// but don't consume the first until after the second has been sent.
316TEST_P(AbstractEventLoopTest, FetchNextTest) {
317
318 auto send_loop = Make();
319 auto fetch_loop = Make();
320 auto sender = send_loop->MakeSender<TestMessage>("/test");
321 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
322
323 {
324 auto msg = sender.MakeMessage();
325 msg->msg_value = 100;
326 ASSERT_TRUE(msg.Send());
327 }
328
329 {
330 auto msg = sender.MakeMessage();
331 msg->msg_value = 200;
332 ASSERT_TRUE(msg.Send());
333 }
334
335 ASSERT_TRUE(fetcher.FetchNext());
336 ASSERT_NE(nullptr, fetcher.get());
337 EXPECT_EQ(100, fetcher->msg_value);
338
339 ASSERT_TRUE(fetcher.FetchNext());
340 ASSERT_NE(nullptr, fetcher.get());
341 EXPECT_EQ(200, fetcher->msg_value);
342
343 // When we run off the end of the queue, expect to still have the old message:
344 ASSERT_FALSE(fetcher.FetchNext());
345 ASSERT_NE(nullptr, fetcher.get());
346 EXPECT_EQ(200, fetcher->msg_value);
347}
348
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800349// Verify that making a fetcher and watcher for "/test" succeeds.
350TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800351 auto loop = Make();
352 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800353 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800354}
355
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800356// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800357TEST_P(AbstractEventLoopTest, TwoFetcher) {
358 auto loop = Make();
359 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800360 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800361}
362
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800363// Verify that registering a watcher twice for "/test" fails.
364TEST_P(AbstractEventLoopTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800365 auto loop = Make();
366 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800367 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
368 "/test");
369}
370
Austin Schuh3115a202019-05-27 21:02:14 -0700371// Verify that SetRuntimeRealtimePriority fails while running.
372TEST_P(AbstractEventLoopTest, SetRuntimeRealtimePriority) {
373 auto loop = MakePrimary();
374 // Confirm that runtime priority calls work when not realtime.
375 loop->SetRuntimeRealtimePriority(5);
376
377 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
378
379 EXPECT_DEATH(Run(), "realtime");
380}
381
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800382// Verify that registering a watcher and a sender for "/test" fails.
383TEST_P(AbstractEventLoopTest, WatcherAndSender) {
384 auto loop = Make();
385 auto sender = loop->MakeSender<TestMessage>("/test");
386 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
387 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800388}
389
390// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800391TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
392 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700393 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800394
Austin Schuh3578a2e2019-05-25 18:17:59 -0700395 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
396 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
397 EXPECT_EQ(message.msg_value, 200);
398 loop2->Exit();
399 });
400
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800401 auto sender = loop1->MakeSender<TestMessage>("/test2");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800402 {
403 auto msg = sender.MakeMessage();
404 msg->msg_value = 200;
405 msg.Send();
406 }
407
Austin Schuh44019f92019-05-19 19:58:27 -0700408 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800409}
410
Neil Balch229001a2018-01-07 18:22:52 -0800411// Verify that timer intervals and duration function properly.
412TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh44019f92019-05-19 19:58:27 -0700413 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800414 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
415
416 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
417 iteration_list.push_back(loop->monotonic_now());
418 });
419
420 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
421 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
422 // Testing that the timer thread waits for the event loop to start before
423 // running
424 ::std::this_thread::sleep_for(std::chrono::milliseconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700425 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800426
427 EXPECT_EQ(iteration_list.size(), 8);
428}
429
430// Verify that we can change a timer's parameters during execution.
431TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700432 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800433 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
434
435 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
436 iteration_list.push_back(loop->monotonic_now());
437 });
438
439 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
440 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
441 });
442
443
444 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
445 modifier_timer->Setup(loop->monotonic_now() +
446 ::std::chrono::milliseconds(45));
447 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700448 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800449
450 EXPECT_EQ(iteration_list.size(), 7);
451}
452
453// Verify that we can disable a timer during execution.
454TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700455 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800456 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
457
458 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
459 iteration_list.push_back(loop->monotonic_now());
460 });
461
462 auto ender_timer = loop->AddTimer([&test_timer]() {
463 test_timer->Disable();
464 });
465
466 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
467 ender_timer->Setup(loop->monotonic_now() +
468 ::std::chrono::milliseconds(45));
469 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700470 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800471
472 EXPECT_EQ(iteration_list.size(), 3);
473}
Austin Schuh7267c532019-05-19 19:55:53 -0700474
475// Verify that the send time on a message is roughly right.
476TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700477 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700478 auto loop2 = Make();
479 auto sender = loop1->MakeSender<TestMessage>("/test");
480 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
481
482 auto test_timer = loop1->AddTimer([&sender]() {
483 auto msg = sender.MakeMessage();
484 msg->msg_value = 200;
485 msg.Send();
486 });
487
488 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
489
490 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700491 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700492
493 EXPECT_TRUE(fetcher.Fetch());
494
495 monotonic_clock::duration time_offset =
496 fetcher->sent_time - (loop1->monotonic_now() - ::std::chrono::seconds(1));
497
498 EXPECT_TRUE(time_offset > ::std::chrono::milliseconds(-500))
499 << ": Got " << fetcher->sent_time.time_since_epoch().count() << " expected "
500 << loop1->monotonic_now().time_since_epoch().count();
501 EXPECT_TRUE(time_offset < ::std::chrono::milliseconds(500))
502 << ": Got " << fetcher->sent_time.time_since_epoch().count()
503 << " expected " << loop1->monotonic_now().time_since_epoch().count();
504}
505
Parker Schuhe4a70d62017-12-27 20:10:20 -0800506} // namespace testing
507} // namespace aos