blob: 8d0d0e239c9f28050c59ac3a2e543c5f8cc4b580 [file] [log] [blame]
Alex Perrycb7da4b2019-08-28 19:35:56 -07001#include "aos/events/event_loop_param_test.h"
Parker Schuhe4a70d62017-12-27 20:10:20 -08002
Austin Schuh52d325c2019-06-23 18:59:06 -07003#include <chrono>
4
Alex Perrycb7da4b2019-08-28 19:35:56 -07005#include "aos/events/test_message_generated.h"
Austin Schuh54cf95f2019-11-29 13:14:18 -08006#include "aos/flatbuffer_merge.h"
7#include "glog/logging.h"
Tyler Chatow67ddb032020-01-12 14:30:04 -08008#include "gmock/gmock.h"
9#include "gtest/gtest.h"
Austin Schuh9fe68f72019-08-10 19:32:03 -070010
Parker Schuhe4a70d62017-12-27 20:10:20 -080011namespace aos {
12namespace testing {
Austin Schuh52d325c2019-06-23 18:59:06 -070013namespace {
14namespace chrono = ::std::chrono;
15} // namespace
Parker Schuhe4a70d62017-12-27 20:10:20 -080016
Austin Schuh6b6dfa52019-06-12 20:16:20 -070017// Tests that watcher can receive messages from a sender.
Parker Schuhe4a70d62017-12-27 20:10:20 -080018// Also tests that OnRun() works.
19TEST_P(AbstractEventLoopTest, Basic) {
20 auto loop1 = Make();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070021 auto loop2 = MakePrimary();
22
Alex Perrycb7da4b2019-08-28 19:35:56 -070023 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
Austin Schuh6b6dfa52019-06-12 20:16:20 -070024
25 bool happened = false;
26
27 loop2->OnRun([&]() {
28 happened = true;
29
Alex Perrycb7da4b2019-08-28 19:35:56 -070030 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
31 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
32 builder.add_value(200);
33 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -070034 });
35
36 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070037 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -070038 this->Exit();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070039 });
40
41 EXPECT_FALSE(happened);
42 Run();
43 EXPECT_TRUE(happened);
44}
45
Brian Silverman341b57e2020-06-23 16:23:18 -070046// Tests that watcher can receive messages from a sender, sent via SendDetached.
47TEST_P(AbstractEventLoopTest, BasicSendDetached) {
48 auto loop1 = Make();
49 auto loop2 = MakePrimary();
50
51 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
52
53 FlatbufferDetachedBuffer<TestMessage> detached =
54 flatbuffers::DetachedBuffer();
55 {
56 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
57 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
58 builder.add_value(100);
59 detached = msg.Detach(builder.Finish());
60 }
61 detached = flatbuffers::DetachedBuffer();
62 {
63 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
64 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
65 builder.add_value(200);
66 detached = msg.Detach(builder.Finish());
67 }
68 ASSERT_TRUE(sender.SendDetached(std::move(detached)));
69
70 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
71 ASSERT_TRUE(fetcher.Fetch());
72 EXPECT_EQ(fetcher->value(), 200);
73}
74
Brian Silverman6b8a3c32020-03-06 11:26:14 -080075// Verifies that a no-arg watcher will not have a data pointer.
76TEST_P(AbstractEventLoopTest, NoArgNoData) {
77 auto loop1 = Make();
78 auto loop2 = MakePrimary();
79
80 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
81
82 bool happened = false;
83
84 loop2->OnRun([&]() {
85 happened = true;
86
87 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
88 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
89 ASSERT_TRUE(msg.Send(builder.Finish()));
90 });
91
92 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
93 EXPECT_GT(loop2->context().size, 0u);
94 EXPECT_EQ(nullptr, loop2->context().data);
95 this->Exit();
96 });
97
98 EXPECT_FALSE(happened);
99 Run();
100 EXPECT_TRUE(happened);
101}
102
Brian Silverman454bc112020-03-05 14:21:25 -0800103// Tests that no-arg watcher can receive messages from a sender.
104// Also tests that OnRun() works.
105TEST_P(AbstractEventLoopTest, BasicNoArg) {
106 auto loop1 = Make();
107 auto loop2 = MakePrimary();
108
109 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
110
111 bool happened = false;
112
113 loop2->OnRun([&]() {
114 happened = true;
115
116 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
117 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
118 builder.add_value(200);
119 ASSERT_TRUE(msg.Send(builder.Finish()));
120 });
121
122 aos::Fetcher<TestMessage> fetcher = loop2->MakeFetcher<TestMessage>("/test");
123 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
124 ASSERT_TRUE(fetcher.Fetch());
125 EXPECT_EQ(fetcher->value(), 200);
126 this->Exit();
127 });
128
129 EXPECT_FALSE(happened);
130 Run();
131 EXPECT_TRUE(happened);
132}
133
134// Tests that a watcher can be created with an std::function.
135TEST_P(AbstractEventLoopTest, BasicFunction) {
136 auto loop1 = Make();
137 auto loop2 = MakePrimary();
138
139 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
140
141 bool happened = false;
142
143 loop2->OnRun([&]() {
144 happened = true;
145
146 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
147 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
148 builder.add_value(200);
149 ASSERT_TRUE(msg.Send(builder.Finish()));
150 });
151
152 loop2->MakeWatcher("/test", std::function<void(const TestMessage &)>(
153 [&](const TestMessage &message) {
154 EXPECT_EQ(message.value(), 200);
155 this->Exit();
156 }));
157
158 EXPECT_FALSE(happened);
159 Run();
160 EXPECT_TRUE(happened);
161}
162
Brian Silverman0fc69932020-01-24 21:54:02 -0800163// Tests that watcher can receive messages from two senders.
164// Also tests that OnRun() works.
165TEST_P(AbstractEventLoopTest, BasicTwoSenders) {
166 auto loop1 = Make();
167 auto loop2 = MakePrimary();
168
169 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
170 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
171
172 bool happened = false;
173
174 loop2->OnRun([&]() {
175 happened = true;
176
177 {
178 aos::Sender<TestMessage>::Builder msg = sender1.MakeBuilder();
179 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
180 builder.add_value(200);
181 ASSERT_TRUE(msg.Send(builder.Finish()));
182 }
183 {
184 aos::Sender<TestMessage>::Builder msg = sender2.MakeBuilder();
185 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
186 builder.add_value(200);
187 ASSERT_TRUE(msg.Send(builder.Finish()));
188 }
189 });
190
191 int messages_received = 0;
192 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
193 EXPECT_EQ(message.value(), 200);
194 this->Exit();
195 ++messages_received;
196 });
197
198 EXPECT_FALSE(happened);
199 Run();
200 EXPECT_TRUE(happened);
201 EXPECT_EQ(messages_received, 2);
202}
203
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700204// Tests that a fetcher can fetch from a sender.
205// Also tests that OnRun() works.
206TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
207 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800208 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700209 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800210
211 auto sender = loop1->MakeSender<TestMessage>("/test");
212
213 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
214
Austin Schuhbbce72d2019-05-26 15:11:46 -0700215 EXPECT_FALSE(fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -0800216 EXPECT_EQ(fetcher.get(), nullptr);
217
Austin Schuhad154822019-12-27 15:45:13 -0800218 EXPECT_EQ(fetcher.context().monotonic_event_time, monotonic_clock::min_time);
219 EXPECT_EQ(fetcher.context().monotonic_remote_time, monotonic_clock::min_time);
220 EXPECT_EQ(fetcher.context().realtime_event_time, realtime_clock::min_time);
221 EXPECT_EQ(fetcher.context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800222 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
223 EXPECT_EQ(fetcher.context().size, 0u);
224 EXPECT_EQ(fetcher.context().data, nullptr);
Austin Schuhbbce72d2019-05-26 15:11:46 -0700225
Alex Perrycb7da4b2019-08-28 19:35:56 -0700226 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
227 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
228 builder.add_value(200);
229 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700230
231 EXPECT_TRUE(fetcher.Fetch());
232 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700233 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -0800234
235 const chrono::milliseconds kEpsilon(100);
236
Austin Schuhad154822019-12-27 15:45:13 -0800237 const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
238 const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
239 EXPECT_EQ(fetcher.context().monotonic_event_time,
240 fetcher.context().monotonic_remote_time);
241 EXPECT_EQ(fetcher.context().realtime_event_time,
242 fetcher.context().realtime_remote_time);
243
244 EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
245 EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
246 EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
247 EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800248 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
249 EXPECT_EQ(fetcher.context().size, 20u);
250 EXPECT_NE(fetcher.context().data, nullptr);
Parker Schuhe4a70d62017-12-27 20:10:20 -0800251}
252
Austin Schuh3578a2e2019-05-25 18:17:59 -0700253// Tests that watcher will receive all messages sent if they are sent after
254// initialization and before running.
255TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
256 auto loop1 = Make();
257 auto loop2 = MakePrimary();
258
259 auto sender = loop1->MakeSender<TestMessage>("/test");
260
261 ::std::vector<int> values;
262
263 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700264 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700265 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700266 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700267 }
268 });
269
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700270 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -0700271 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700272 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
273 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
274 builder.add_value(199);
275 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700276 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700277
278 loop2->OnRun([&]() {
279 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700280 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
281 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
282 builder.add_value(200);
283 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700284 }
285 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700286 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
287 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
288 builder.add_value(201);
289 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700290 }
291 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700292
293 Run();
294
295 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
296}
297
298// Tests that watcher will not receive messages sent before the watcher is
299// created.
300TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
301 auto loop1 = Make();
302 auto loop2 = MakePrimary();
303
304 auto sender = loop1->MakeSender<TestMessage>("/test");
305
306 ::std::vector<int> values;
307
308 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700309 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
310 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
311 builder.add_value(200);
312 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700313 }
314 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700315 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
316 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
317 builder.add_value(201);
318 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700319 }
320
321 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700322 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700323 });
324
325 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700326 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700327 loop2->OnRun([&test_timer, &loop2]() {
328 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
329 });
330
331 Run();
332 EXPECT_EQ(0, values.size());
333}
334
Austin Schuhbbce72d2019-05-26 15:11:46 -0700335// Tests that FetchNext gets all the messages sent after it is constructed.
336TEST_P(AbstractEventLoopTest, FetchNext) {
337 auto loop1 = Make();
338 auto loop2 = MakePrimary();
339
340 auto sender = loop1->MakeSender<TestMessage>("/test");
341 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
342
343 ::std::vector<int> values;
344
345 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700346 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
347 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
348 builder.add_value(200);
349 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700350 }
351 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700352 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
353 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
354 builder.add_value(201);
355 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700356 }
357
358 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700359 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700360 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700361 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700362 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700363 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700364 });
365
366 loop2->OnRun([&test_timer, &loop2]() {
367 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
368 });
369
370 Run();
371 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
372}
373
374// Tests that FetchNext gets no messages sent before it is constructed.
375TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
376 auto loop1 = Make();
377 auto loop2 = MakePrimary();
378
379 auto sender = loop1->MakeSender<TestMessage>("/test");
380
381 ::std::vector<int> values;
382
383 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700384 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
385 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
386 builder.add_value(200);
387 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700388 }
389 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700390 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
391 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
392 builder.add_value(201);
393 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700394 }
395
396 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
397
398 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700399 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700400 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700401 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700402 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700403 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700404 });
405
406 loop2->OnRun([&test_timer, &loop2]() {
407 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
408 });
409
410 Run();
411 EXPECT_THAT(0, values.size());
412}
413
414// Tests that Fetch returns the last message created before the loop was
415// started.
416TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
417 auto loop1 = Make();
418 auto loop2 = MakePrimary();
419
420 auto sender = loop1->MakeSender<TestMessage>("/test");
421
422 ::std::vector<int> values;
423
424 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700425 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
426 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
427 builder.add_value(200);
428 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700429 }
430 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700431 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
432 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
433 builder.add_value(201);
434 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700435 }
436
437 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
438
439 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700440 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700441 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700442 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700443 }
444 // Do it again to make sure we don't double fetch.
445 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700446 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700447 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700448 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700449 });
450
451 loop2->OnRun([&test_timer, &loop2]() {
452 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
453 });
454
455 Run();
456 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
457}
458
459// Tests that Fetch and FetchNext interleave as expected.
460TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
461 auto loop1 = Make();
462 auto loop2 = MakePrimary();
463
464 auto sender = loop1->MakeSender<TestMessage>("/test");
465
466 ::std::vector<int> values;
467
468 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700469 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
470 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
471 builder.add_value(200);
472 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700473 }
474 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700475 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
476 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
477 builder.add_value(201);
478 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700479 }
480
481 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
482
483 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700484 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700485 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700486 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700487 }
488
489 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700490 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
491 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
492 builder.add_value(202);
493 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700494 }
495 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700496 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
497 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
498 builder.add_value(203);
499 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700500 }
501 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700502 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
503 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
504 builder.add_value(204);
505 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700506 }
507
508 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700509 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700510 }
511
512 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700513 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700514 }
515
Austin Schuh9fe68f72019-08-10 19:32:03 -0700516 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700517 });
518
519 loop2->OnRun([&test_timer, &loop2]() {
520 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
521 });
522
523 Run();
524 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
525}
526
Austin Schuh3115a202019-05-27 21:02:14 -0700527// Tests that FetchNext behaves correctly when we get two messages in the queue
528// but don't consume the first until after the second has been sent.
529TEST_P(AbstractEventLoopTest, FetchNextTest) {
Austin Schuh3115a202019-05-27 21:02:14 -0700530 auto send_loop = Make();
531 auto fetch_loop = Make();
532 auto sender = send_loop->MakeSender<TestMessage>("/test");
533 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
534
535 {
Tyler Chatow67ddb032020-01-12 14:30:04 -0800536 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
537 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
538 builder.add_value(100);
539 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700540 }
541
542 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700543 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
544 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
545 builder.add_value(200);
546 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700547 }
548
549 ASSERT_TRUE(fetcher.FetchNext());
550 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700551 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700552
553 ASSERT_TRUE(fetcher.FetchNext());
554 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700555 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700556
557 // When we run off the end of the queue, expect to still have the old message:
558 ASSERT_FALSE(fetcher.FetchNext());
559 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700560 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700561}
562
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800563// Verify that making a fetcher and watcher for "/test" succeeds.
564TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800565 auto loop = Make();
566 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800567 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800568}
569
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800570// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800571TEST_P(AbstractEventLoopTest, TwoFetcher) {
572 auto loop = Make();
573 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800574 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800575}
576
Alex Perrycb7da4b2019-08-28 19:35:56 -0700577// Verify that registering a watcher for an invalid channel name dies.
578TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
579 auto loop = Make();
580 EXPECT_DEATH(
581 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
582 "/test/invalid");
Brian Silverman454bc112020-03-05 14:21:25 -0800583 EXPECT_DEATH(
584 { loop->MakeNoArgWatcher<TestMessage>("/test/invalid", [&]() {}); },
585 "/test/invalid");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700586}
587
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800588// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700589TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800590 auto loop = Make();
591 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800592 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
593 "/test");
Brian Silverman454bc112020-03-05 14:21:25 -0800594 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
595}
596
597// Verify that registering a no-arg watcher twice for "/test" fails.
598TEST_P(AbstractEventLoopDeathTest, TwoNoArgWatcher) {
599 auto loop = Make();
600 loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {});
601 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
602 "/test");
603 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800604}
605
Austin Schuh3115a202019-05-27 21:02:14 -0700606// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700607TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700608 auto loop = MakePrimary();
609 // Confirm that runtime priority calls work when not realtime.
610 loop->SetRuntimeRealtimePriority(5);
611
612 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
613
614 EXPECT_DEATH(Run(), "realtime");
615}
616
Brian Silverman6a54ff32020-04-28 16:41:39 -0700617// Verify that SetRuntimeAffinity fails while running.
618TEST_P(AbstractEventLoopDeathTest, SetRuntimeAffinity) {
619 auto loop = MakePrimary();
620 // Confirm that runtime priority calls work when not running.
621 loop->SetRuntimeAffinity(MakeCpusetFromCpus({0}));
622
623 loop->OnRun([&]() { loop->SetRuntimeAffinity(MakeCpusetFromCpus({1})); });
624
625 EXPECT_DEATH(Run(), "Cannot set affinity while running");
626}
627
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800628// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700629TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800630 auto loop = Make();
631 auto sender = loop->MakeSender<TestMessage>("/test");
632 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
633 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800634}
635
Austin Schuhe516ab02020-05-06 21:37:04 -0700636// Verify that creating too many senders fails.
637TEST_P(AbstractEventLoopDeathTest, TooManySenders) {
638 auto loop = Make();
639 std::vector<aos::Sender<TestMessage>> senders;
640 for (int i = 0; i < 10; ++i) {
641 senders.emplace_back(loop->MakeSender<TestMessage>("/test"));
642 }
643 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); },
644 "Failed to create sender on \\{ \"name\": \"/test\", \"type\": "
645 "\"aos.TestMessage\" \\}, too many senders.");
646}
647
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700648// Verify that we can't create a sender inside OnRun.
649TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
650 auto loop1 = MakePrimary();
651
652 loop1->OnRun(
653 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
654
655 EXPECT_DEATH(Run(), "running");
656}
657
658// Verify that we can't create a watcher inside OnRun.
659TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
660 auto loop1 = MakePrimary();
661
662 loop1->OnRun(
663 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
664
665 EXPECT_DEATH(Run(), "running");
666}
667
Brian Silverman454bc112020-03-05 14:21:25 -0800668// Verify that we can't create a no-arg watcher inside OnRun.
669TEST_P(AbstractEventLoopDeathTest, NoArgWatcherInOnRun) {
670 auto loop1 = MakePrimary();
671
672 loop1->OnRun(
673 [&]() { loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {}); });
674
675 EXPECT_DEATH(Run(), "running");
676}
677
Parker Schuhe4a70d62017-12-27 20:10:20 -0800678// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800679TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
680 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700681 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800682
Austin Schuh3578a2e2019-05-25 18:17:59 -0700683 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
684 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700685 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700686 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700687 });
688
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800689 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700690
691 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700692 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
693 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
694 builder.add_value(200);
695 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700696 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800697
Austin Schuh44019f92019-05-19 19:58:27 -0700698 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800699}
700
Neil Balch229001a2018-01-07 18:22:52 -0800701// Verify that timer intervals and duration function properly.
702TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800703 // Force a slower rate so we are guarenteed to have reports for our timer.
704 FLAGS_timing_report_ms = 2000;
705
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800706 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800707
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800708 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800709 auto loop2 = Make();
710
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800711 ::std::vector<::aos::monotonic_clock::time_point> times;
712 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
713
Austin Schuh39788ff2019-12-01 18:22:57 -0800714 Fetcher<timing::Report> report_fetcher =
715 loop2->MakeFetcher<timing::Report>("/aos");
716 EXPECT_FALSE(report_fetcher.Fetch());
717
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800718 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
719 times.push_back(loop->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800720 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
721 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
722 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800723 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
724 EXPECT_EQ(loop->context().size, 0u);
725 EXPECT_EQ(loop->context().data, nullptr);
726
Austin Schuhad154822019-12-27 15:45:13 -0800727 expected_times.push_back(loop->context().monotonic_event_time);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800728 if (times.size() == kCount) {
729 this->Exit();
730 }
Neil Balch229001a2018-01-07 18:22:52 -0800731 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800732 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800733
Austin Schuh39788ff2019-12-01 18:22:57 -0800734 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700735 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800736 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
737
Austin Schuh44019f92019-05-19 19:58:27 -0700738 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800739
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800740 // Confirm that we got both the right number of samples, and it's odd.
741 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
742 EXPECT_EQ(times.size(), expected_times.size());
743 EXPECT_EQ((times.size() % 2), 1);
744
745 // Grab the middle sample.
746 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
747
748 // Add up all the delays of all the times.
749 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
750 for (const ::aos::monotonic_clock::time_point time : times) {
751 sum += time - average_time;
752 }
753
754 // Average and add to the middle to find the average time.
755 sum /= times.size();
756 average_time += sum;
757
758 // Compute the offset from the average and the expected average. It
759 // should be pretty close to 0.
760 const ::aos::monotonic_clock::duration remainder =
761 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
762
763 const chrono::milliseconds kEpsilon(100);
764 EXPECT_LT(remainder, +kEpsilon);
765 EXPECT_GT(remainder, -kEpsilon);
766
767 // Make sure that the average duration is close to 1 second.
768 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
769 times.front())
770 .count() /
771 static_cast<double>(times.size() - 1),
772 1.0, 0.1);
773
774 // Confirm that the ideal wakeup times increment correctly.
775 for (size_t i = 1; i < expected_times.size(); ++i) {
776 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
777 }
778
779 for (size_t i = 0; i < expected_times.size(); ++i) {
780 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
781 chrono::seconds(0));
782 }
783
784 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
785 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800786
787 // And, since we are here, check that the timing report makes sense.
788 // Start by looking for our event loop's timing.
789 FlatbufferDetachedBuffer<timing::Report> report =
790 FlatbufferDetachedBuffer<timing::Report>::Empty();
791 while (report_fetcher.FetchNext()) {
792 if (report_fetcher->name()->string_view() == "primary") {
793 report = CopyFlatBuffer(report_fetcher.get());
794 }
795 }
796
797 // Confirm that we have the right number of reports, and the contents are
798 // sane.
Ravago Jonescf453ab2020-05-06 21:14:53 -0700799 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -0800800
801 EXPECT_EQ(report.message().name()->string_view(), "primary");
802
803 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -0800804 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -0800805
806 ASSERT_NE(report.message().timers(), nullptr);
807 EXPECT_EQ(report.message().timers()->size(), 2);
808
809 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
810 "Test loop");
811 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
812
813 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
814 "timing_reports");
815 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
816
817 // Make sure there is a single phased loop report with our report in it.
818 ASSERT_EQ(report.message().phased_loops(), nullptr);
Neil Balch229001a2018-01-07 18:22:52 -0800819}
820
821// Verify that we can change a timer's parameters during execution.
822TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700823 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800824 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
825
826 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
827 iteration_list.push_back(loop->monotonic_now());
828 });
829
830 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
831 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
832 });
833
Neil Balch229001a2018-01-07 18:22:52 -0800834 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
835 modifier_timer->Setup(loop->monotonic_now() +
836 ::std::chrono::milliseconds(45));
837 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700838 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800839
840 EXPECT_EQ(iteration_list.size(), 7);
841}
842
843// Verify that we can disable a timer during execution.
844TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700845 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800846 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
847
848 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
849 iteration_list.push_back(loop->monotonic_now());
850 });
851
Tyler Chatow67ddb032020-01-12 14:30:04 -0800852 auto ender_timer = loop->AddTimer([&test_timer]() { test_timer->Disable(); });
Neil Balch229001a2018-01-07 18:22:52 -0800853
854 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
Tyler Chatow67ddb032020-01-12 14:30:04 -0800855 ender_timer->Setup(loop->monotonic_now() + ::std::chrono::milliseconds(45));
Neil Balch229001a2018-01-07 18:22:52 -0800856 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700857 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800858
859 EXPECT_EQ(iteration_list.size(), 3);
860}
Austin Schuh7267c532019-05-19 19:55:53 -0700861
Brian Silvermanbd405c02020-06-23 16:25:23 -0700862// Verify that we can disable a timer during execution of another timer
863// scheduled for the same time, with one ordering of creation for the timers.
864//
865// Also schedule some more events to reshuffle the heap in EventLoop used for
866// tracking events to change up the order. This used to segfault
867// SimulatedEventLoop.
868TEST_P(AbstractEventLoopTest, TimerDisableOther) {
869 for (bool creation_order : {true, false}) {
870 for (bool setup_order : {true, false}) {
871 for (int shuffle_events = 0; shuffle_events < 5; ++shuffle_events) {
872 auto loop = MakePrimary();
873 aos::TimerHandler *test_timer, *ender_timer;
874 if (creation_order) {
875 test_timer = loop->AddTimer([]() {});
876 ender_timer =
877 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
878 } else {
879 ender_timer =
880 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
881 test_timer = loop->AddTimer([]() {});
882 }
883
884 const auto start = loop->monotonic_now();
885
886 for (int i = 0; i < shuffle_events; ++i) {
887 loop->AddTimer([]() {})->Setup(start + std::chrono::milliseconds(10));
888 }
889
890 if (setup_order) {
891 test_timer->Setup(start + ::std::chrono::milliseconds(20));
892 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
893 } else {
894 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
895 test_timer->Setup(start + ::std::chrono::milliseconds(20));
896 }
897 EndEventLoop(loop.get(), ::std::chrono::milliseconds(40));
898 Run();
899 }
900 }
901 }
902}
903
Austin Schuh54cf95f2019-11-29 13:14:18 -0800904// Verifies that the event loop implementations detect when Channel is not a
905// pointer into confguration()
906TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
907 auto loop = MakePrimary();
908
Tyler Chatow67ddb032020-01-12 14:30:04 -0800909 const Channel *channel = configuration::GetChannel(
910 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
Austin Schuh54cf95f2019-11-29 13:14:18 -0800911
912 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
913
914 EXPECT_DEATH(
915 { loop->MakeRawSender(&channel_copy.message()); },
916 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
917
918 EXPECT_DEATH(
919 { loop->MakeRawFetcher(&channel_copy.message()); },
920 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
921
922 EXPECT_DEATH(
923 {
924 loop->MakeRawWatcher(&channel_copy.message(),
925 [](const Context, const void *) {});
926 },
927 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
928}
929
Brian Silverman454bc112020-03-05 14:21:25 -0800930// Verify that the send time on a message is roughly right when using a watcher.
Austin Schuh7267c532019-05-19 19:55:53 -0700931TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700932 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700933 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -0800934 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -0700935 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
936
937 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700938 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
939 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
940 builder.add_value(200);
941 ASSERT_TRUE(msg.Send(builder.Finish()));
942 });
943
Austin Schuhad154822019-12-27 15:45:13 -0800944 bool triggered = false;
Brian Silverman454bc112020-03-05 14:21:25 -0800945 loop1->MakeWatcher("/test", [&](const TestMessage &msg) {
Austin Schuhad154822019-12-27 15:45:13 -0800946 // Confirm that the data pointer makes sense from a watcher, and all the
947 // timestamps look right.
948 EXPECT_GT(&msg, loop1->context().data);
949 EXPECT_EQ(loop1->context().monotonic_remote_time,
950 loop1->context().monotonic_event_time);
951 EXPECT_EQ(loop1->context().realtime_remote_time,
952 loop1->context().realtime_event_time);
953
954 const aos::monotonic_clock::time_point monotonic_now =
955 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -0800956 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -0800957
958 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
959 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
960 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
961 monotonic_now);
962 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
963 realtime_now);
964
Brian Silvermaneaa41d62020-07-08 19:47:35 -0700965 EXPECT_LT(&msg, reinterpret_cast<const void *>(
966 reinterpret_cast<const char *>(loop1->context().data) +
Austin Schuhad154822019-12-27 15:45:13 -0800967 loop1->context().size));
968 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -0700969 });
970
971 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
972
973 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700974 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700975
Austin Schuhad154822019-12-27 15:45:13 -0800976 EXPECT_TRUE(triggered);
977
Brian Silverman454bc112020-03-05 14:21:25 -0800978 ASSERT_TRUE(fetcher.Fetch());
979
980 monotonic_clock::duration monotonic_time_offset =
981 fetcher.context().monotonic_event_time -
982 (loop1->monotonic_now() - ::std::chrono::seconds(1));
983 realtime_clock::duration realtime_time_offset =
984 fetcher.context().realtime_event_time -
985 (loop1->realtime_now() - ::std::chrono::seconds(1));
986
987 EXPECT_EQ(fetcher.context().realtime_event_time,
988 fetcher.context().realtime_remote_time);
989 EXPECT_EQ(fetcher.context().monotonic_event_time,
990 fetcher.context().monotonic_remote_time);
991
992 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
993 << ": Got "
994 << fetcher.context().monotonic_event_time.time_since_epoch().count()
995 << " expected " << loop1->monotonic_now().time_since_epoch().count();
996 // Confirm that the data pointer makes sense.
997 EXPECT_GT(fetcher.get(), fetcher.context().data);
998 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -0700999 reinterpret_cast<const void *>(
1000 reinterpret_cast<const char *>(fetcher.context().data) +
Brian Silverman454bc112020-03-05 14:21:25 -08001001 fetcher.context().size));
1002 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1003 << ": Got "
1004 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1005 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1006
1007 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1008 << ": Got "
1009 << fetcher.context().realtime_event_time.time_since_epoch().count()
1010 << " expected " << loop1->realtime_now().time_since_epoch().count();
1011 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1012 << ": Got "
1013 << fetcher.context().realtime_event_time.time_since_epoch().count()
1014 << " expected " << loop1->realtime_now().time_since_epoch().count();
1015}
1016
1017// Verify that the send time on a message is roughly right when using a no-arg
1018// watcher. To get a message, we need to use a fetcher to actually access the
1019// message. This is also the main use case for no-arg fetchers.
1020TEST_P(AbstractEventLoopTest, MessageSendTimeNoArg) {
1021 auto loop1 = MakePrimary();
1022 auto loop2 = Make();
1023 auto sender = loop2->MakeSender<TestMessage>("/test");
1024 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1025
1026 auto test_timer = loop1->AddTimer([&sender]() {
1027 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1028 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1029 builder.add_value(200);
1030 ASSERT_TRUE(msg.Send(builder.Finish()));
1031 });
1032
1033 bool triggered = false;
1034 loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {
1035 // Confirm that we can indeed use a fetcher on this channel from this
1036 // context, and it results in a sane data pointer and timestamps.
1037 ASSERT_TRUE(fetcher.Fetch());
1038
1039 EXPECT_EQ(loop1->context().monotonic_remote_time,
1040 loop1->context().monotonic_event_time);
1041 EXPECT_EQ(loop1->context().realtime_remote_time,
1042 loop1->context().realtime_event_time);
1043
1044 const aos::monotonic_clock::time_point monotonic_now =
1045 loop1->monotonic_now();
1046 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
1047
1048 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1049 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1050 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1051 monotonic_now);
1052 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1053 realtime_now);
1054
1055 triggered = true;
1056 });
1057
1058 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1059
1060 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
1061 Run();
1062
1063 ASSERT_TRUE(triggered);
Austin Schuh7267c532019-05-19 19:55:53 -07001064
Alex Perrycb7da4b2019-08-28 19:35:56 -07001065 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001066 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001067 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1068 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001069 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001070 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -07001071
Austin Schuhad154822019-12-27 15:45:13 -08001072 EXPECT_EQ(fetcher.context().realtime_event_time,
1073 fetcher.context().realtime_remote_time);
1074 EXPECT_EQ(fetcher.context().monotonic_event_time,
1075 fetcher.context().monotonic_remote_time);
1076
Alex Perrycb7da4b2019-08-28 19:35:56 -07001077 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1078 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001079 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -07001080 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001081 // Confirm that the data pointer makes sense.
1082 EXPECT_GT(fetcher.get(), fetcher.context().data);
1083 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001084 reinterpret_cast<const void *>(
1085 reinterpret_cast<const char *>(fetcher.context().data) +
Alex Perrycb7da4b2019-08-28 19:35:56 -07001086 fetcher.context().size));
1087 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1088 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001089 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -07001090 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001091
1092 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1093 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001094 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001095 << " expected " << loop1->realtime_now().time_since_epoch().count();
1096 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1097 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001098 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001099 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -07001100}
1101
Austin Schuh52d325c2019-06-23 18:59:06 -07001102// Tests that a couple phased loops run in a row result in the correct offset
1103// and period.
1104TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -08001105 // Force a slower rate so we are guarenteed to have reports for our phased
1106 // loop.
1107 FLAGS_timing_report_ms = 2000;
1108
Austin Schuh52d325c2019-06-23 18:59:06 -07001109 const chrono::milliseconds kOffset = chrono::milliseconds(400);
1110 const int kCount = 5;
1111
1112 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -08001113 auto loop2 = Make();
1114
1115 Fetcher<timing::Report> report_fetcher =
1116 loop2->MakeFetcher<timing::Report>("/aos");
1117 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001118
1119 // Collect up a couple of samples.
1120 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001121 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -07001122
1123 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -08001124 loop1
1125 ->AddPhasedLoop(
1126 [&times, &expected_times, &loop1, this](int count) {
1127 EXPECT_EQ(count, 1);
1128 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -08001129 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -08001130
Austin Schuhad154822019-12-27 15:45:13 -08001131 EXPECT_EQ(loop1->context().monotonic_remote_time,
1132 monotonic_clock::min_time);
1133 EXPECT_EQ(loop1->context().realtime_event_time,
1134 realtime_clock::min_time);
1135 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -08001136 realtime_clock::min_time);
1137 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
1138 EXPECT_EQ(loop1->context().size, 0u);
1139 EXPECT_EQ(loop1->context().data, nullptr);
1140
1141 if (times.size() == kCount) {
1142 LOG(INFO) << "Exiting";
1143 this->Exit();
1144 }
1145 },
1146 chrono::seconds(1), kOffset)
1147 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -07001148
1149 // Add a delay to make sure that delay during startup doesn't result in a
1150 // "missed cycle".
1151 SleepFor(chrono::seconds(2));
1152
1153 Run();
1154
1155 // Confirm that we got both the right number of samples, and it's odd.
1156 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001157 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -07001158 EXPECT_EQ((times.size() % 2), 1);
1159
1160 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001161 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -07001162
1163 // Add up all the delays of all the times.
1164 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1165 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001166 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -07001167 }
1168
1169 // Average and add to the middle to find the average time.
1170 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001171 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -07001172
1173 // Compute the offset from the start of the second of the average time. This
1174 // should be pretty close to the offset.
1175 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001176 average_time.time_since_epoch() -
1177 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001178
1179 const chrono::milliseconds kEpsilon(100);
1180 EXPECT_LT(remainder, kOffset + kEpsilon);
1181 EXPECT_GT(remainder, kOffset - kEpsilon);
1182
1183 // Make sure that the average duration is close to 1 second.
1184 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1185 times.front())
1186 .count() /
1187 static_cast<double>(times.size() - 1),
1188 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001189
1190 // Confirm that the ideal wakeup times increment correctly.
1191 for (size_t i = 1; i < expected_times.size(); ++i) {
1192 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1193 }
1194
1195 for (size_t i = 0; i < expected_times.size(); ++i) {
1196 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1197 kOffset);
1198 }
1199
1200 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1201 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001202
1203 // And, since we are here, check that the timing report makes sense.
1204 // Start by looking for our event loop's timing.
1205 FlatbufferDetachedBuffer<timing::Report> report =
1206 FlatbufferDetachedBuffer<timing::Report>::Empty();
1207 while (report_fetcher.FetchNext()) {
1208 if (report_fetcher->name()->string_view() == "primary") {
1209 report = CopyFlatBuffer(report_fetcher.get());
1210 }
1211 }
1212
Ravago Jonescf453ab2020-05-06 21:14:53 -07001213 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001214
1215 EXPECT_EQ(report.message().name()->string_view(), "primary");
1216
1217 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001218 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001219
1220 ASSERT_NE(report.message().timers(), nullptr);
1221 EXPECT_EQ(report.message().timers()->size(), 1);
1222
1223 // Make sure there is a single phased loop report with our report in it.
1224 ASSERT_NE(report.message().phased_loops(), nullptr);
1225 ASSERT_EQ(report.message().phased_loops()->size(), 1);
1226 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
1227 "Test loop");
1228 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
1229}
1230
1231// Tests that senders count correctly in the timing report.
1232TEST_P(AbstractEventLoopTest, SenderTimingReport) {
1233 FLAGS_timing_report_ms = 1000;
1234 auto loop1 = MakePrimary();
1235
1236 auto loop2 = Make("watcher_loop");
1237 loop2->MakeWatcher("/test", [](const TestMessage &) {});
1238
1239 auto loop3 = Make();
1240
1241 Fetcher<timing::Report> report_fetcher =
1242 loop3->MakeFetcher<timing::Report>("/aos");
1243 EXPECT_FALSE(report_fetcher.Fetch());
1244
1245 auto sender = loop1->MakeSender<TestMessage>("/test");
1246
1247 // Add a timer to actually quit.
1248 auto test_timer = loop1->AddTimer([&sender]() {
1249 for (int i = 0; i < 10; ++i) {
1250 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1251 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1252 builder.add_value(200 + i);
1253 ASSERT_TRUE(msg.Send(builder.Finish()));
1254 }
1255 });
1256
1257 // Quit after 1 timing report, mid way through the next cycle.
1258 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1259
1260 loop1->OnRun([&test_timer, &loop1]() {
1261 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1262 });
1263
1264 Run();
1265
1266 // And, since we are here, check that the timing report makes sense.
1267 // Start by looking for our event loop's timing.
1268 FlatbufferDetachedBuffer<timing::Report> primary_report =
1269 FlatbufferDetachedBuffer<timing::Report>::Empty();
1270 while (report_fetcher.FetchNext()) {
1271 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1272 if (report_fetcher->name()->string_view() == "primary") {
1273 primary_report = CopyFlatBuffer(report_fetcher.get());
1274 }
1275 }
1276
Ravago Jonescf453ab2020-05-06 21:14:53 -07001277 LOG(INFO) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001278
1279 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1280
1281 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001282 EXPECT_EQ(primary_report.message().senders()->size(), 3);
Austin Schuh39788ff2019-12-01 18:22:57 -08001283
1284 // Confirm that the sender looks sane.
1285 EXPECT_EQ(
1286 loop1->configuration()
1287 ->channels()
1288 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1289 ->name()
1290 ->string_view(),
1291 "/test");
1292 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1293
1294 // Confirm that the timing primary_report sender looks sane.
1295 EXPECT_EQ(
1296 loop1->configuration()
1297 ->channels()
1298 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1299 ->name()
1300 ->string_view(),
1301 "/aos");
1302 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1303
1304 ASSERT_NE(primary_report.message().timers(), nullptr);
1305 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1306
1307 // Make sure there are no phased loops or watchers.
1308 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1309 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1310}
1311
1312// Tests that senders count correctly in the timing report.
1313TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1314 FLAGS_timing_report_ms = 1000;
1315 auto loop1 = MakePrimary();
1316 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1317
1318 auto loop2 = Make("sender_loop");
1319
1320 auto loop3 = Make();
1321
1322 Fetcher<timing::Report> report_fetcher =
1323 loop3->MakeFetcher<timing::Report>("/aos");
1324 EXPECT_FALSE(report_fetcher.Fetch());
1325
1326 auto sender = loop2->MakeSender<TestMessage>("/test");
1327
1328 // Add a timer to actually quit.
1329 auto test_timer = loop1->AddTimer([&sender]() {
1330 for (int i = 0; i < 10; ++i) {
1331 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1332 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1333 builder.add_value(200 + i);
1334 ASSERT_TRUE(msg.Send(builder.Finish()));
1335 }
1336 });
1337
1338 // Quit after 1 timing report, mid way through the next cycle.
1339 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1340
1341 loop1->OnRun([&test_timer, &loop1]() {
1342 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1343 });
1344
1345 Run();
1346
1347 // And, since we are here, check that the timing report makes sense.
1348 // Start by looking for our event loop's timing.
1349 FlatbufferDetachedBuffer<timing::Report> primary_report =
1350 FlatbufferDetachedBuffer<timing::Report>::Empty();
1351 while (report_fetcher.FetchNext()) {
1352 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1353 if (report_fetcher->name()->string_view() == "primary") {
1354 primary_report = CopyFlatBuffer(report_fetcher.get());
1355 }
1356 }
1357
1358 // Check the watcher report.
Ravago Jonescf453ab2020-05-06 21:14:53 -07001359 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001360
1361 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1362
1363 // Just the timing report timer.
1364 ASSERT_NE(primary_report.message().timers(), nullptr);
1365 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1366
1367 // No phased loops
1368 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1369
1370 ASSERT_NE(primary_report.message().watchers(), nullptr);
1371 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1372 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1373}
1374
1375// Tests that fetchers count correctly in the timing report.
1376TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1377 FLAGS_timing_report_ms = 1000;
1378 auto loop1 = MakePrimary();
1379 auto loop2 = Make("sender_loop");
1380
1381 auto loop3 = Make();
1382
1383 Fetcher<timing::Report> report_fetcher =
1384 loop3->MakeFetcher<timing::Report>("/aos");
1385 EXPECT_FALSE(report_fetcher.Fetch());
1386
1387 auto sender = loop2->MakeSender<TestMessage>("/test");
1388 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1389 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1390 fetcher1.Fetch();
1391 fetcher2.Fetch();
1392
1393 // Add a timer to actually quit.
1394 auto test_timer = loop1->AddTimer([&sender]() {
1395 for (int i = 0; i < 10; ++i) {
1396 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1397 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1398 builder.add_value(200 + i);
1399 ASSERT_TRUE(msg.Send(builder.Finish()));
1400 }
1401 });
1402
1403 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1404 fetcher1.Fetch();
1405 while (fetcher2.FetchNext()) {
1406 }
1407 });
1408
1409 // Quit after 1 timing report, mid way through the next cycle.
1410 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1411
1412 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1413 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1414 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1415 });
1416
1417 Run();
1418
1419 // And, since we are here, check that the timing report makes sense.
1420 // Start by looking for our event loop's timing.
1421 FlatbufferDetachedBuffer<timing::Report> primary_report =
1422 FlatbufferDetachedBuffer<timing::Report>::Empty();
1423 while (report_fetcher.FetchNext()) {
1424 if (report_fetcher->name()->string_view() == "primary") {
1425 primary_report = CopyFlatBuffer(report_fetcher.get());
1426 }
1427 }
1428
Ravago Jonescf453ab2020-05-06 21:14:53 -07001429 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001430
1431 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1432
1433 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001434 EXPECT_EQ(primary_report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001435
1436 ASSERT_NE(primary_report.message().timers(), nullptr);
1437 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1438
1439 // Make sure there are no phased loops or watchers.
1440 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1441 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1442
1443 // Now look at the fetchrs.
1444 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1445 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1446
1447 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1448 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1449 0.1);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001450 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(), 0.1);
1451 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(), 0.1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001452 EXPECT_EQ(primary_report.message()
1453 .fetchers()
1454 ->Get(0)
1455 ->latency()
1456 ->standard_deviation(),
1457 0.0);
1458
1459 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001460}
1461
Austin Schuh67420a42019-12-21 21:55:04 -08001462// Tests that a raw watcher and raw fetcher can receive messages from a raw
1463// sender without messing up offsets.
1464TEST_P(AbstractEventLoopTest, RawBasic) {
1465 auto loop1 = Make();
1466 auto loop2 = MakePrimary();
1467 auto loop3 = Make();
1468
1469 const std::string kData("971 is the best");
1470
1471 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001472 loop1->MakeRawSender(configuration::GetChannel(
1473 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001474
1475 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001476 loop3->MakeRawFetcher(configuration::GetChannel(
1477 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001478
1479 loop2->OnRun(
1480 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1481
1482 bool happened = false;
1483 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001484 configuration::GetChannel(loop2->configuration(), "/test",
1485 "aos.TestMessage", "", nullptr),
Austin Schuh67420a42019-12-21 21:55:04 -08001486 [this, &kData, &fetcher, &happened](const Context &context,
1487 const void *message) {
1488 happened = true;
1489 EXPECT_EQ(std::string_view(kData),
1490 std::string_view(reinterpret_cast<const char *>(message),
1491 context.size));
1492 EXPECT_EQ(std::string_view(kData),
1493 std::string_view(reinterpret_cast<const char *>(context.data),
1494 context.size));
1495
1496 ASSERT_TRUE(fetcher->Fetch());
1497
1498 EXPECT_EQ(std::string_view(kData),
1499 std::string_view(
1500 reinterpret_cast<const char *>(fetcher->context().data),
1501 fetcher->context().size));
1502
1503 this->Exit();
1504 });
1505
1506 EXPECT_FALSE(happened);
1507 Run();
1508 EXPECT_TRUE(happened);
1509}
1510
Austin Schuhad154822019-12-27 15:45:13 -08001511// Tests that a raw watcher and raw fetcher can receive messages from a raw
1512// sender with remote times filled out.
1513TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1514 auto loop1 = Make();
1515 auto loop2 = MakePrimary();
1516 auto loop3 = Make();
1517
1518 const std::string kData("971 is the best");
1519
1520 const aos::monotonic_clock::time_point monotonic_remote_time =
1521 aos::monotonic_clock::time_point(chrono::seconds(1501));
1522 const aos::realtime_clock::time_point realtime_remote_time =
1523 aos::realtime_clock::time_point(chrono::seconds(3132));
1524
1525 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001526 loop1->MakeRawSender(configuration::GetChannel(
1527 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001528
1529 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001530 loop3->MakeRawFetcher(configuration::GetChannel(
1531 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001532
1533 loop2->OnRun([&]() {
1534 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1535 realtime_remote_time));
1536 });
1537
1538 bool happened = false;
1539 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001540 configuration::GetChannel(loop2->configuration(), "/test",
1541 "aos.TestMessage", "", nullptr),
Austin Schuhad154822019-12-27 15:45:13 -08001542 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1543 const Context &context, const void * /*message*/) {
1544 happened = true;
1545 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1546 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1547
1548 ASSERT_TRUE(fetcher->Fetch());
1549 EXPECT_EQ(monotonic_remote_time,
1550 fetcher->context().monotonic_remote_time);
1551 EXPECT_EQ(realtime_remote_time,
1552 fetcher->context().realtime_remote_time);
1553
1554 this->Exit();
1555 });
1556
1557 EXPECT_FALSE(happened);
1558 Run();
1559 EXPECT_TRUE(happened);
1560}
1561
1562// Tests that a raw sender fills out sent data.
1563TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1564 auto loop1 = MakePrimary();
1565
1566 const std::string kData("971 is the best");
1567
1568 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001569 loop1->MakeRawSender(configuration::GetChannel(
1570 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001571
Tyler Chatow67ddb032020-01-12 14:30:04 -08001572 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
1573 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001574
1575 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1576
1577 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1578 EXPECT_LE(sender->monotonic_sent_time(),
1579 monotonic_now + chrono::milliseconds(100));
1580 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1581 EXPECT_LE(sender->realtime_sent_time(),
1582 realtime_now + chrono::milliseconds(100));
1583 EXPECT_EQ(sender->sent_queue_index(), 0u);
1584
1585 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1586
1587 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1588 EXPECT_LE(sender->monotonic_sent_time(),
1589 monotonic_now + chrono::milliseconds(100));
1590 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1591 EXPECT_LE(sender->realtime_sent_time(),
1592 realtime_now + chrono::milliseconds(100));
1593 EXPECT_EQ(sender->sent_queue_index(), 1u);
1594}
1595
Austin Schuh217a9782019-12-21 23:02:50 -08001596// Tests that not setting up nodes results in no node.
1597TEST_P(AbstractEventLoopTest, NoNode) {
1598 auto loop1 = Make();
1599 auto loop2 = MakePrimary();
1600
1601 EXPECT_EQ(loop1->node(), nullptr);
1602 EXPECT_EQ(loop2->node(), nullptr);
1603}
1604
1605// Tests that setting up nodes results in node being set.
1606TEST_P(AbstractEventLoopTest, Node) {
1607 EnableNodes("me");
1608
1609 auto loop1 = Make();
1610 auto loop2 = MakePrimary();
1611
1612 EXPECT_NE(loop1->node(), nullptr);
1613 EXPECT_NE(loop2->node(), nullptr);
1614}
1615
1616// Tests that watchers work with a node setup.
1617TEST_P(AbstractEventLoopTest, NodeWatcher) {
1618 EnableNodes("me");
1619
1620 auto loop1 = Make();
1621 auto loop2 = Make();
1622 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08001623 loop2->MakeRawWatcher(
1624 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1625 nullptr),
1626 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001627}
1628
Brian Silverman454bc112020-03-05 14:21:25 -08001629// Tests that no-arg watchers work with a node setup.
1630TEST_P(AbstractEventLoopTest, NodeNoArgWatcher) {
1631 EnableNodes("me");
1632
1633 auto loop1 = Make();
1634 auto loop2 = Make();
1635 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1636 loop2->MakeRawNoArgWatcher(
1637 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1638 nullptr),
1639 [](const Context &) {});
1640}
1641
Austin Schuh217a9782019-12-21 23:02:50 -08001642// Tests that fetcher work with a node setup.
1643TEST_P(AbstractEventLoopTest, NodeFetcher) {
1644 EnableNodes("me");
1645 auto loop1 = Make();
1646
1647 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08001648 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1649 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001650}
1651
1652// Tests that sender work with a node setup.
1653TEST_P(AbstractEventLoopTest, NodeSender) {
1654 EnableNodes("me");
1655 auto loop1 = Make();
1656
1657 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1658}
1659
1660// Tests that watchers fail when created on the wrong node.
1661TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
1662 EnableNodes("them");
1663
1664 auto loop1 = Make();
1665 auto loop2 = Make();
1666 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
1667 "node");
1668 EXPECT_DEATH(
1669 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001670 loop2->MakeRawWatcher(
1671 configuration::GetChannel(configuration(), "/test",
1672 "aos.TestMessage", "", nullptr),
1673 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001674 },
1675 "node");
Brian Silverman454bc112020-03-05 14:21:25 -08001676 EXPECT_DEATH({ loop1->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1677 "node");
1678 EXPECT_DEATH(
1679 {
1680 loop2->MakeRawNoArgWatcher(
1681 configuration::GetChannel(configuration(), "/test",
1682 "aos.TestMessage", "", nullptr),
1683 [](const Context &) {});
1684 },
1685 "node");
Austin Schuh217a9782019-12-21 23:02:50 -08001686}
1687
1688// Tests that fetchers fail when created on the wrong node.
1689TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
1690 EnableNodes("them");
1691 auto loop1 = Make();
1692
1693 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
1694 "node");
1695 EXPECT_DEATH(
1696 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001697 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1698 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001699 },
1700 "node");
1701}
1702
1703// Tests that senders fail when created on the wrong node.
1704TEST_P(AbstractEventLoopDeathTest, NodeSender) {
1705 EnableNodes("them");
1706 auto loop1 = Make();
1707
1708 EXPECT_DEATH(
1709 {
1710 aos::Sender<TestMessage> sender =
1711 loop1->MakeSender<TestMessage>("/test");
1712 },
1713 "node");
1714
1715 // Note: Creating raw senders is always supported. Right now, this lets us
1716 // use them to create message_gateway.
1717}
1718
Brian Silverman341b57e2020-06-23 16:23:18 -07001719// Tests creating multiple Builders from a single Sender at the same time.
1720TEST_P(AbstractEventLoopDeathTest, MultipleBuilders) {
1721 auto loop1 = Make();
1722 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1723
1724 { auto builder = sender.MakeBuilder(); }
1725 {
1726 auto builder = sender.MakeBuilder();
1727 builder.MakeBuilder<TestMessage>().Finish();
1728 }
1729 {
1730 // Creating this after the first one was destroyed should be fine.
1731 auto builder = sender.MakeBuilder();
1732 builder.MakeBuilder<TestMessage>().Finish();
1733 // But not a second one.
1734 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
1735 "May not overwrite in-use allocator");
1736 }
1737
1738 FlatbufferDetachedBuffer<TestMessage> detached =
1739 flatbuffers::DetachedBuffer();
1740 {
1741 auto builder = sender.MakeBuilder();
1742 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
1743 }
1744 {
1745 // This is the second one, after the detached one, so it should fail.
1746 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
1747 "May not overwrite in-use allocator");
1748 }
1749
1750 // Clear the detached one, and then we should be able to create another.
1751 detached = flatbuffers::DetachedBuffer();
1752 {
1753 auto builder = sender.MakeBuilder();
1754 builder.MakeBuilder<TestMessage>().Finish();
1755 }
1756
1757 // And then detach another one.
1758 {
1759 auto builder = sender.MakeBuilder();
1760 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
1761 }
1762}
1763
1764// Tests sending a buffer detached from a different builder.
1765TEST_P(AbstractEventLoopDeathTest, WrongDetachedBuffer) {
1766 auto loop1 = Make();
1767 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
1768 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
1769
1770 auto builder = sender1.MakeBuilder();
1771 FlatbufferDetachedBuffer<TestMessage> detached =
1772 builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
1773 EXPECT_DEATH(sender2.SendDetached(std::move(detached)),
1774 "May only send the buffer detached from this Sender");
1775}
1776
Parker Schuhe4a70d62017-12-27 20:10:20 -08001777} // namespace testing
1778} // namespace aos