blob: 371cb78ecb1fc5b3bbf92455950a740c1ed830dd [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 Schuh81fc9cc2019-02-02 23:25:47 -0800313// Verify that making a fetcher and watcher for "/test" succeeds.
314TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800315 auto loop = Make();
316 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800317 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800318}
319
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800320// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800321TEST_P(AbstractEventLoopTest, TwoFetcher) {
322 auto loop = Make();
323 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800324 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800325}
326
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800327// Verify that registering a watcher twice for "/test" fails.
328TEST_P(AbstractEventLoopTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800329 auto loop = Make();
330 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800331 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
332 "/test");
333}
334
335// Verify that registering a watcher and a sender for "/test" fails.
336TEST_P(AbstractEventLoopTest, WatcherAndSender) {
337 auto loop = Make();
338 auto sender = loop->MakeSender<TestMessage>("/test");
339 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
340 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800341}
342
343// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800344TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
345 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700346 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800347
Austin Schuh3578a2e2019-05-25 18:17:59 -0700348 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
349 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
350 EXPECT_EQ(message.msg_value, 200);
351 loop2->Exit();
352 });
353
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800354 auto sender = loop1->MakeSender<TestMessage>("/test2");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800355 {
356 auto msg = sender.MakeMessage();
357 msg->msg_value = 200;
358 msg.Send();
359 }
360
Austin Schuh44019f92019-05-19 19:58:27 -0700361 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800362}
363
Neil Balch229001a2018-01-07 18:22:52 -0800364// Verify that timer intervals and duration function properly.
365TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh44019f92019-05-19 19:58:27 -0700366 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800367 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
368
369 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
370 iteration_list.push_back(loop->monotonic_now());
371 });
372
373 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
374 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
375 // Testing that the timer thread waits for the event loop to start before
376 // running
377 ::std::this_thread::sleep_for(std::chrono::milliseconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700378 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800379
380 EXPECT_EQ(iteration_list.size(), 8);
381}
382
383// Verify that we can change a timer's parameters during execution.
384TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700385 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800386 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
387
388 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
389 iteration_list.push_back(loop->monotonic_now());
390 });
391
392 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
393 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
394 });
395
396
397 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
398 modifier_timer->Setup(loop->monotonic_now() +
399 ::std::chrono::milliseconds(45));
400 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700401 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800402
403 EXPECT_EQ(iteration_list.size(), 7);
404}
405
406// Verify that we can disable a timer during execution.
407TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700408 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800409 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
410
411 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
412 iteration_list.push_back(loop->monotonic_now());
413 });
414
415 auto ender_timer = loop->AddTimer([&test_timer]() {
416 test_timer->Disable();
417 });
418
419 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
420 ender_timer->Setup(loop->monotonic_now() +
421 ::std::chrono::milliseconds(45));
422 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700423 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800424
425 EXPECT_EQ(iteration_list.size(), 3);
426}
Austin Schuh7267c532019-05-19 19:55:53 -0700427
428// Verify that the send time on a message is roughly right.
429TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700430 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700431 auto loop2 = Make();
432 auto sender = loop1->MakeSender<TestMessage>("/test");
433 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
434
435 auto test_timer = loop1->AddTimer([&sender]() {
436 auto msg = sender.MakeMessage();
437 msg->msg_value = 200;
438 msg.Send();
439 });
440
441 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
442
443 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700444 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700445
446 EXPECT_TRUE(fetcher.Fetch());
447
448 monotonic_clock::duration time_offset =
449 fetcher->sent_time - (loop1->monotonic_now() - ::std::chrono::seconds(1));
450
451 EXPECT_TRUE(time_offset > ::std::chrono::milliseconds(-500))
452 << ": Got " << fetcher->sent_time.time_since_epoch().count() << " expected "
453 << loop1->monotonic_now().time_since_epoch().count();
454 EXPECT_TRUE(time_offset < ::std::chrono::milliseconds(500))
455 << ": Got " << fetcher->sent_time.time_since_epoch().count()
456 << " expected " << loop1->monotonic_now().time_since_epoch().count();
457}
458
Parker Schuhe4a70d62017-12-27 20:10:20 -0800459} // namespace testing
460} // namespace aos