blob: d3d21ac14f4e583fd801863d8c8233fa2c92cb7b [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>
Brian Silverman4f4e0612020-08-12 19:54:41 -07004#include <unordered_map>
5#include <unordered_set>
Austin Schuh52d325c2019-06-23 18:59:06 -07006
Austin Schuh54cf95f2019-11-29 13:14:18 -08007#include "aos/flatbuffer_merge.h"
Austin Schuhcc6070c2020-10-10 20:25:56 -07008#include "aos/realtime.h"
Austin Schuh54cf95f2019-11-29 13:14:18 -08009#include "glog/logging.h"
Tyler Chatow67ddb032020-01-12 14:30:04 -080010#include "gmock/gmock.h"
11#include "gtest/gtest.h"
Austin Schuh9fe68f72019-08-10 19:32:03 -070012
Parker Schuhe4a70d62017-12-27 20:10:20 -080013namespace aos {
14namespace testing {
Austin Schuh52d325c2019-06-23 18:59:06 -070015namespace {
16namespace chrono = ::std::chrono;
17} // namespace
Parker Schuhe4a70d62017-12-27 20:10:20 -080018
Brian Silverman4f4e0612020-08-12 19:54:41 -070019::std::unique_ptr<EventLoop> AbstractEventLoopTest::Make(
20 std::string_view name) {
21 std::string name_copy(name);
22 if (name == "") {
23 name_copy = "loop";
24 name_copy += std::to_string(event_loop_count_);
25 }
26 ++event_loop_count_;
Austin Schuh6bae8252021-02-07 22:01:49 -080027 auto result = factory_->Make(name_copy);
28 if (do_timing_reports() == DoTimingReports::kNo) {
29 result->SkipTimingReport();
30 }
31 return result;
Brian Silverman4f4e0612020-08-12 19:54:41 -070032}
33
34void AbstractEventLoopTest::VerifyBuffers(
35 int number_buffers,
36 std::vector<std::reference_wrapper<const Fetcher<TestMessage>>> fetchers,
37 std::vector<std::reference_wrapper<const Sender<TestMessage>>> senders) {
38 // The buffers which are in a sender.
39 std::unordered_set<int> in_sender;
40 for (const Sender<TestMessage> &sender : senders) {
41 const int this_buffer = sender.buffer_index();
42 CHECK_GE(this_buffer, 0);
43 CHECK_LT(this_buffer, number_buffers);
44 CHECK(in_sender.insert(this_buffer).second) << ": " << this_buffer;
45 }
46
47 if (read_method() != ReadMethod::PIN) {
48 // If we're not using PIN, we can't really verify anything about what
49 // buffers the fetchers have.
50 return;
51 }
52
53 // Mapping from TestMessage::value to buffer index.
54 std::unordered_map<int, int> fetcher_values;
55 for (const Fetcher<TestMessage> &fetcher : fetchers) {
56 if (!fetcher.get()) {
57 continue;
58 }
59 const int this_buffer = fetcher.context().buffer_index;
60 CHECK_GE(this_buffer, 0);
61 CHECK_LT(this_buffer, number_buffers);
62 CHECK(in_sender.count(this_buffer) == 0) << ": " << this_buffer;
63 const auto insert_result = fetcher_values.insert(
64 std::make_pair(fetcher.get()->value(), this_buffer));
65 if (!insert_result.second) {
66 CHECK_EQ(this_buffer, insert_result.first->second);
67 }
68 }
69}
70
Austin Schuh6b6dfa52019-06-12 20:16:20 -070071// Tests that watcher can receive messages from a sender.
Parker Schuhe4a70d62017-12-27 20:10:20 -080072// Also tests that OnRun() works.
73TEST_P(AbstractEventLoopTest, Basic) {
74 auto loop1 = Make();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070075 auto loop2 = MakePrimary();
76
Alex Perrycb7da4b2019-08-28 19:35:56 -070077 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
Austin Schuh6b6dfa52019-06-12 20:16:20 -070078
79 bool happened = false;
80
81 loop2->OnRun([&]() {
82 happened = true;
83
Alex Perrycb7da4b2019-08-28 19:35:56 -070084 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
85 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
86 builder.add_value(200);
87 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -070088 });
89
90 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070091 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -070092 this->Exit();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070093 });
94
95 EXPECT_FALSE(happened);
96 Run();
97 EXPECT_TRUE(happened);
98}
99
Brian Silverman341b57e2020-06-23 16:23:18 -0700100// Tests that watcher can receive messages from a sender, sent via SendDetached.
101TEST_P(AbstractEventLoopTest, BasicSendDetached) {
102 auto loop1 = Make();
103 auto loop2 = MakePrimary();
104
105 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
106
107 FlatbufferDetachedBuffer<TestMessage> detached =
108 flatbuffers::DetachedBuffer();
109 {
110 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
111 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
112 builder.add_value(100);
113 detached = msg.Detach(builder.Finish());
114 }
115 detached = flatbuffers::DetachedBuffer();
116 {
117 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
118 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
119 builder.add_value(200);
120 detached = msg.Detach(builder.Finish());
121 }
122 ASSERT_TRUE(sender.SendDetached(std::move(detached)));
123
124 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
125 ASSERT_TRUE(fetcher.Fetch());
126 EXPECT_EQ(fetcher->value(), 200);
127}
128
Brian Silverman6b8a3c32020-03-06 11:26:14 -0800129// Verifies that a no-arg watcher will not have a data pointer.
130TEST_P(AbstractEventLoopTest, NoArgNoData) {
131 auto loop1 = Make();
132 auto loop2 = MakePrimary();
133
134 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
135
136 bool happened = false;
137
138 loop2->OnRun([&]() {
139 happened = true;
140
141 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
142 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
143 ASSERT_TRUE(msg.Send(builder.Finish()));
144 });
145
146 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
147 EXPECT_GT(loop2->context().size, 0u);
148 EXPECT_EQ(nullptr, loop2->context().data);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700149 EXPECT_EQ(-1, loop2->context().buffer_index);
Brian Silverman6b8a3c32020-03-06 11:26:14 -0800150 this->Exit();
151 });
152
153 EXPECT_FALSE(happened);
154 Run();
155 EXPECT_TRUE(happened);
156}
157
Brian Silverman454bc112020-03-05 14:21:25 -0800158// Tests that no-arg watcher can receive messages from a sender.
159// Also tests that OnRun() works.
160TEST_P(AbstractEventLoopTest, BasicNoArg) {
161 auto loop1 = Make();
162 auto loop2 = MakePrimary();
163
164 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
165
166 bool happened = false;
167
168 loop2->OnRun([&]() {
169 happened = true;
170
171 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
172 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
173 builder.add_value(200);
174 ASSERT_TRUE(msg.Send(builder.Finish()));
175 });
176
177 aos::Fetcher<TestMessage> fetcher = loop2->MakeFetcher<TestMessage>("/test");
178 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
179 ASSERT_TRUE(fetcher.Fetch());
180 EXPECT_EQ(fetcher->value(), 200);
181 this->Exit();
182 });
183
184 EXPECT_FALSE(happened);
185 Run();
186 EXPECT_TRUE(happened);
187}
188
189// Tests that a watcher can be created with an std::function.
190TEST_P(AbstractEventLoopTest, BasicFunction) {
191 auto loop1 = Make();
192 auto loop2 = MakePrimary();
193
194 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
195
196 bool happened = false;
197
198 loop2->OnRun([&]() {
199 happened = true;
200
201 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
202 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
203 builder.add_value(200);
204 ASSERT_TRUE(msg.Send(builder.Finish()));
205 });
206
207 loop2->MakeWatcher("/test", std::function<void(const TestMessage &)>(
208 [&](const TestMessage &message) {
209 EXPECT_EQ(message.value(), 200);
210 this->Exit();
211 }));
212
213 EXPECT_FALSE(happened);
214 Run();
215 EXPECT_TRUE(happened);
216}
217
Brian Silverman0fc69932020-01-24 21:54:02 -0800218// Tests that watcher can receive messages from two senders.
219// Also tests that OnRun() works.
220TEST_P(AbstractEventLoopTest, BasicTwoSenders) {
221 auto loop1 = Make();
222 auto loop2 = MakePrimary();
223
224 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
225 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
226
227 bool happened = false;
228
229 loop2->OnRun([&]() {
230 happened = true;
231
232 {
233 aos::Sender<TestMessage>::Builder msg = sender1.MakeBuilder();
234 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
235 builder.add_value(200);
236 ASSERT_TRUE(msg.Send(builder.Finish()));
237 }
238 {
239 aos::Sender<TestMessage>::Builder msg = sender2.MakeBuilder();
240 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
241 builder.add_value(200);
242 ASSERT_TRUE(msg.Send(builder.Finish()));
243 }
244 });
245
246 int messages_received = 0;
247 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
248 EXPECT_EQ(message.value(), 200);
249 this->Exit();
250 ++messages_received;
251 });
252
253 EXPECT_FALSE(happened);
254 Run();
255 EXPECT_TRUE(happened);
256 EXPECT_EQ(messages_received, 2);
257}
258
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700259// Tests that a fetcher can fetch from a sender.
260// Also tests that OnRun() works.
261TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
262 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800263 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700264 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800265
266 auto sender = loop1->MakeSender<TestMessage>("/test");
267
268 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
269
Austin Schuhbbce72d2019-05-26 15:11:46 -0700270 EXPECT_FALSE(fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -0800271 EXPECT_EQ(fetcher.get(), nullptr);
272
Austin Schuhad154822019-12-27 15:45:13 -0800273 EXPECT_EQ(fetcher.context().monotonic_event_time, monotonic_clock::min_time);
274 EXPECT_EQ(fetcher.context().monotonic_remote_time, monotonic_clock::min_time);
275 EXPECT_EQ(fetcher.context().realtime_event_time, realtime_clock::min_time);
276 EXPECT_EQ(fetcher.context().realtime_remote_time, realtime_clock::min_time);
Austin Schuha9012be2021-07-21 15:19:11 -0700277 EXPECT_EQ(fetcher.context().source_boot_uuid, UUID::Zero());
Austin Schuh39788ff2019-12-01 18:22:57 -0800278 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
279 EXPECT_EQ(fetcher.context().size, 0u);
280 EXPECT_EQ(fetcher.context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700281 EXPECT_EQ(fetcher.context().buffer_index, -1);
Austin Schuhbbce72d2019-05-26 15:11:46 -0700282
Alex Perrycb7da4b2019-08-28 19:35:56 -0700283 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
284 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
285 builder.add_value(200);
286 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700287
288 EXPECT_TRUE(fetcher.Fetch());
289 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700290 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -0800291
292 const chrono::milliseconds kEpsilon(100);
293
Austin Schuhad154822019-12-27 15:45:13 -0800294 const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
295 const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
296 EXPECT_EQ(fetcher.context().monotonic_event_time,
297 fetcher.context().monotonic_remote_time);
298 EXPECT_EQ(fetcher.context().realtime_event_time,
299 fetcher.context().realtime_remote_time);
300
301 EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
302 EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
303 EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
304 EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
Austin Schuha9012be2021-07-21 15:19:11 -0700305 EXPECT_EQ(fetcher.context().source_boot_uuid, loop2->boot_uuid());
Austin Schuh39788ff2019-12-01 18:22:57 -0800306 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
307 EXPECT_EQ(fetcher.context().size, 20u);
308 EXPECT_NE(fetcher.context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700309 if (read_method() == ReadMethod::PIN) {
310 EXPECT_GE(fetcher.context().buffer_index, 0);
311 EXPECT_LT(fetcher.context().buffer_index,
312 loop2->NumberBuffers(fetcher.channel()));
313 } else {
314 EXPECT_EQ(fetcher.context().buffer_index, -1);
315 }
Parker Schuhe4a70d62017-12-27 20:10:20 -0800316}
317
Austin Schuh3578a2e2019-05-25 18:17:59 -0700318// Tests that watcher will receive all messages sent if they are sent after
319// initialization and before running.
320TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
321 auto loop1 = Make();
322 auto loop2 = MakePrimary();
323
324 auto sender = loop1->MakeSender<TestMessage>("/test");
325
326 ::std::vector<int> values;
327
328 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700329 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700330 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700331 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700332 }
333 });
334
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700335 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -0700336 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700337 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
338 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
339 builder.add_value(199);
340 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700341 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700342
343 loop2->OnRun([&]() {
344 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700345 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
346 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
347 builder.add_value(200);
348 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700349 }
350 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700351 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
352 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
353 builder.add_value(201);
354 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700355 }
356 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700357
358 Run();
359
360 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
361}
362
363// Tests that watcher will not receive messages sent before the watcher is
364// created.
365TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
366 auto loop1 = Make();
367 auto loop2 = MakePrimary();
368
369 auto sender = loop1->MakeSender<TestMessage>("/test");
370
371 ::std::vector<int> values;
372
373 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700374 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
375 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
376 builder.add_value(200);
377 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700378 }
379 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700380 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
381 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
382 builder.add_value(201);
383 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700384 }
385
386 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700387 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700388 });
389
390 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700391 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700392 loop2->OnRun([&test_timer, &loop2]() {
393 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
394 });
395
396 Run();
397 EXPECT_EQ(0, values.size());
398}
399
Austin Schuhbbce72d2019-05-26 15:11:46 -0700400// Tests that FetchNext gets all the messages sent after it is constructed.
401TEST_P(AbstractEventLoopTest, FetchNext) {
402 auto loop1 = Make();
403 auto loop2 = MakePrimary();
404
405 auto sender = loop1->MakeSender<TestMessage>("/test");
406 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
407
408 ::std::vector<int> values;
409
410 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700411 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
412 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
413 builder.add_value(200);
414 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700415 }
416 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700417 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
418 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
419 builder.add_value(201);
420 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700421 }
422
423 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700424 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700425 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700426 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700427 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700428 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700429 });
430
431 loop2->OnRun([&test_timer, &loop2]() {
432 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
433 });
434
435 Run();
436 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
437}
438
439// Tests that FetchNext gets no messages sent before it is constructed.
440TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
441 auto loop1 = Make();
442 auto loop2 = MakePrimary();
443
444 auto sender = loop1->MakeSender<TestMessage>("/test");
445
446 ::std::vector<int> values;
447
448 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700449 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
450 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
451 builder.add_value(200);
452 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700453 }
454 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700455 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
456 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
457 builder.add_value(201);
458 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700459 }
460
461 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
462
463 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700464 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700465 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700466 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700467 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700468 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700469 });
470
471 loop2->OnRun([&test_timer, &loop2]() {
472 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
473 });
474
475 Run();
476 EXPECT_THAT(0, values.size());
477}
478
479// Tests that Fetch returns the last message created before the loop was
480// started.
481TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
482 auto loop1 = Make();
483 auto loop2 = MakePrimary();
484
485 auto sender = loop1->MakeSender<TestMessage>("/test");
486
487 ::std::vector<int> values;
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(200);
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(201);
499 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700500 }
501
502 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
503
504 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700505 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700506 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700507 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700508 }
509 // Do it again to make sure we don't double fetch.
510 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700511 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700512 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700513 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700514 });
515
516 loop2->OnRun([&test_timer, &loop2]() {
517 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
518 });
519
520 Run();
521 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
522}
523
524// Tests that Fetch and FetchNext interleave as expected.
525TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
526 auto loop1 = Make();
527 auto loop2 = MakePrimary();
528
529 auto sender = loop1->MakeSender<TestMessage>("/test");
530
531 ::std::vector<int> values;
532
533 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700534 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
535 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
536 builder.add_value(200);
537 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700538 }
539 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700540 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
541 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
542 builder.add_value(201);
543 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700544 }
545
546 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
547
548 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700549 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700550 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700551 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700552 }
553
554 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700555 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
556 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
557 builder.add_value(202);
558 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700559 }
560 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700561 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
562 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
563 builder.add_value(203);
564 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700565 }
566 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700567 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
568 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
569 builder.add_value(204);
570 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700571 }
572
573 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700574 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700575 }
576
577 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700578 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700579 }
580
Austin Schuh9fe68f72019-08-10 19:32:03 -0700581 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700582 });
583
584 loop2->OnRun([&test_timer, &loop2]() {
585 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
586 });
587
588 Run();
589 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
590}
591
Austin Schuh3115a202019-05-27 21:02:14 -0700592// Tests that FetchNext behaves correctly when we get two messages in the queue
593// but don't consume the first until after the second has been sent.
594TEST_P(AbstractEventLoopTest, FetchNextTest) {
Austin Schuh3115a202019-05-27 21:02:14 -0700595 auto send_loop = Make();
596 auto fetch_loop = Make();
597 auto sender = send_loop->MakeSender<TestMessage>("/test");
598 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
599
600 {
Tyler Chatow67ddb032020-01-12 14:30:04 -0800601 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
602 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
603 builder.add_value(100);
604 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700605 }
606
607 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700608 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
609 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
610 builder.add_value(200);
611 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700612 }
613
614 ASSERT_TRUE(fetcher.FetchNext());
615 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700616 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700617
618 ASSERT_TRUE(fetcher.FetchNext());
619 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700620 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700621
622 // When we run off the end of the queue, expect to still have the old message:
623 ASSERT_FALSE(fetcher.FetchNext());
624 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700625 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700626}
627
Brian Silverman77162972020-08-12 19:52:40 -0700628// Verify that a fetcher still holds its data, even after falling behind.
629TEST_P(AbstractEventLoopTest, FetcherBehindData) {
630 auto send_loop = Make();
631 auto fetch_loop = Make();
632 auto sender = send_loop->MakeSender<TestMessage>("/test");
633 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
634 {
635 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
636 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
637 builder.add_value(1);
638 ASSERT_TRUE(msg.Send(builder.Finish()));
639 }
640 ASSERT_TRUE(fetcher.Fetch());
641 EXPECT_EQ(1, fetcher.get()->value());
642 for (int i = 0; i < 300; ++i) {
643 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
644 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
645 builder.add_value(i + 2);
646 ASSERT_TRUE(msg.Send(builder.Finish()));
647 }
648 EXPECT_EQ(1, fetcher.get()->value());
649}
650
651// Try a bunch of orderings of operations with fetchers and senders. Verify that
652// all the fetchers have the correct data at each step.
653TEST_P(AbstractEventLoopTest, FetcherPermutations) {
654 for (int max_save = 0; max_save < 5; ++max_save) {
655 SCOPED_TRACE("max_save=" + std::to_string(max_save));
656
657 auto send_loop = Make();
658 auto fetch_loop = Make();
659 auto sender = send_loop->MakeSender<TestMessage>("/test");
660 const auto send_message = [&sender](int i) {
661 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
662 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
663 builder.add_value(i);
664 ASSERT_TRUE(msg.Send(builder.Finish()));
665 };
666 std::vector<Fetcher<TestMessage>> fetchers;
667 for (int i = 0; i < 10; ++i) {
668 fetchers.emplace_back(fetch_loop->MakeFetcher<TestMessage>("/test"));
669 }
670 send_message(1);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700671 const auto verify_buffers = [&]() {
672 std::vector<std::reference_wrapper<const Fetcher<TestMessage>>>
673 fetchers_copy;
674 for (const auto &fetcher : fetchers) {
675 fetchers_copy.emplace_back(fetcher);
676 }
677 std::vector<std::reference_wrapper<const Sender<TestMessage>>>
678 senders_copy;
679 senders_copy.emplace_back(sender);
680 VerifyBuffers(send_loop->NumberBuffers(sender.channel()), fetchers_copy,
681 senders_copy);
682 };
Brian Silverman77162972020-08-12 19:52:40 -0700683 for (auto &fetcher : fetchers) {
684 ASSERT_TRUE(fetcher.Fetch());
Brian Silverman4f4e0612020-08-12 19:54:41 -0700685 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700686 EXPECT_EQ(1, fetcher.get()->value());
687 }
688
689 for (int save = 1; save <= max_save; ++save) {
690 SCOPED_TRACE("save=" + std::to_string(save));
691 send_message(100 + save);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700692 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700693 for (size_t i = 0; i < fetchers.size() - save; ++i) {
694 SCOPED_TRACE("fetcher=" + std::to_string(i));
695 ASSERT_TRUE(fetchers[i].Fetch());
Brian Silverman4f4e0612020-08-12 19:54:41 -0700696 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700697 EXPECT_EQ(100 + save, fetchers[i].get()->value());
698 }
699 for (size_t i = fetchers.size() - save; i < fetchers.size() - 1; ++i) {
700 SCOPED_TRACE("fetcher=" + std::to_string(i));
701 EXPECT_EQ(100 + (fetchers.size() - 1 - i), fetchers[i].get()->value());
702 }
703 EXPECT_EQ(1, fetchers.back().get()->value());
704 }
705
706 for (int i = 0; i < 300; ++i) {
707 send_message(200 + i);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700708 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700709 }
710
711 for (size_t i = 0; i < fetchers.size() - max_save; ++i) {
712 SCOPED_TRACE("fetcher=" + std::to_string(i));
713 if (max_save > 0) {
714 EXPECT_EQ(100 + max_save, fetchers[i].get()->value());
715 } else {
716 EXPECT_EQ(1, fetchers[i].get()->value());
717 }
718 }
719 for (size_t i = fetchers.size() - max_save; i < fetchers.size() - 1; ++i) {
720 SCOPED_TRACE("fetcher=" + std::to_string(i));
721 EXPECT_EQ(100 + (fetchers.size() - 1 - i), fetchers[i].get()->value());
722 }
723 EXPECT_EQ(1, fetchers.back().get()->value());
724 }
725}
726
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800727// Verify that making a fetcher and watcher for "/test" succeeds.
728TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800729 auto loop = Make();
730 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800731 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800732}
733
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800734// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800735TEST_P(AbstractEventLoopTest, TwoFetcher) {
736 auto loop = Make();
737 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800738 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800739}
740
Alex Perrycb7da4b2019-08-28 19:35:56 -0700741// Verify that registering a watcher for an invalid channel name dies.
742TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
743 auto loop = Make();
744 EXPECT_DEATH(
745 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
746 "/test/invalid");
Brian Silverman454bc112020-03-05 14:21:25 -0800747 EXPECT_DEATH(
748 { loop->MakeNoArgWatcher<TestMessage>("/test/invalid", [&]() {}); },
749 "/test/invalid");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700750}
751
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800752// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700753TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800754 auto loop = Make();
755 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800756 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
757 "/test");
Brian Silverman454bc112020-03-05 14:21:25 -0800758 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
759}
760
761// Verify that registering a no-arg watcher twice for "/test" fails.
762TEST_P(AbstractEventLoopDeathTest, TwoNoArgWatcher) {
763 auto loop = Make();
764 loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {});
765 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
766 "/test");
767 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800768}
769
Austin Schuh3115a202019-05-27 21:02:14 -0700770// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700771TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700772 auto loop = MakePrimary();
773 // Confirm that runtime priority calls work when not realtime.
774 loop->SetRuntimeRealtimePriority(5);
775
776 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
777
778 EXPECT_DEATH(Run(), "realtime");
779}
780
Brian Silverman6a54ff32020-04-28 16:41:39 -0700781// Verify that SetRuntimeAffinity fails while running.
782TEST_P(AbstractEventLoopDeathTest, SetRuntimeAffinity) {
Austin Schuhde973292021-10-12 18:09:49 -0700783 const cpu_set_t available = GetCurrentThreadAffinity();
784 int first_cpu = -1;
785 for (int i = 0; i < CPU_SETSIZE; ++i) {
786 if (CPU_ISSET(i, &available)) {
787 first_cpu = i;
788 break;
789 continue;
790 }
791 }
792 CHECK_NE(first_cpu, -1) << ": Default affinity has no CPUs?";
793
Brian Silverman6a54ff32020-04-28 16:41:39 -0700794 auto loop = MakePrimary();
795 // Confirm that runtime priority calls work when not running.
Austin Schuhde973292021-10-12 18:09:49 -0700796 loop->SetRuntimeAffinity(MakeCpusetFromCpus({first_cpu}));
Brian Silverman6a54ff32020-04-28 16:41:39 -0700797
Austin Schuhde973292021-10-12 18:09:49 -0700798 loop->OnRun(
799 [&]() { loop->SetRuntimeAffinity(MakeCpusetFromCpus({first_cpu})); });
Brian Silverman6a54ff32020-04-28 16:41:39 -0700800
801 EXPECT_DEATH(Run(), "Cannot set affinity while running");
802}
803
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800804// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700805TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800806 auto loop = Make();
807 auto sender = loop->MakeSender<TestMessage>("/test");
808 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
809 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800810}
811
Austin Schuhe516ab02020-05-06 21:37:04 -0700812// Verify that creating too many senders fails.
813TEST_P(AbstractEventLoopDeathTest, TooManySenders) {
814 auto loop = Make();
815 std::vector<aos::Sender<TestMessage>> senders;
816 for (int i = 0; i < 10; ++i) {
817 senders.emplace_back(loop->MakeSender<TestMessage>("/test"));
818 }
819 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); },
820 "Failed to create sender on \\{ \"name\": \"/test\", \"type\": "
Brian Silverman77162972020-08-12 19:52:40 -0700821 "\"aos.TestMessage\"[^}]*\\ }, too many senders.");
822}
823
824// Verify that creating too many fetchers fails.
825TEST_P(AbstractEventLoopDeathTest, TooManyFetchers) {
826 if (read_method() != ReadMethod::PIN) {
827 // Other read methods don't limit the number of readers, so just skip this.
828 return;
829 }
830
831 auto loop = Make();
832 std::vector<aos::Fetcher<TestMessage>> fetchers;
833 for (int i = 0; i < 10; ++i) {
834 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
835 }
836 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
837 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
838 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
839}
840
841// Verify that creating too many fetchers, split between two event loops, fails.
842TEST_P(AbstractEventLoopDeathTest, TooManyFetchersTwoLoops) {
843 if (read_method() != ReadMethod::PIN) {
844 // Other read methods don't limit the number of readers, so just skip this.
845 return;
846 }
847
848 auto loop = Make();
849 auto loop2 = Make();
850 std::vector<aos::Fetcher<TestMessage>> fetchers;
851 for (int i = 0; i < 5; ++i) {
852 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
853 fetchers.emplace_back(loop2->MakeFetcher<TestMessage>("/test"));
854 }
855 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
856 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
857 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
858}
859
860// Verify that creating too many watchers fails.
861TEST_P(AbstractEventLoopDeathTest, TooManyWatchers) {
862 if (read_method() != ReadMethod::PIN) {
863 // Other read methods don't limit the number of readers, so just skip this.
864 return;
865 }
866
867 std::vector<std::unique_ptr<EventLoop>> loops;
868 for (int i = 0; i < 10; ++i) {
869 loops.emplace_back(Make());
870 loops.back()->MakeWatcher("/test", [](const TestMessage &) {});
871 }
872 EXPECT_DEATH({ Make()->MakeWatcher("/test", [](const TestMessage &) {}); },
873 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
874 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
875}
876
877// Verify that creating too many watchers and fetchers combined fails.
878TEST_P(AbstractEventLoopDeathTest, TooManyWatchersAndFetchers) {
879 if (read_method() != ReadMethod::PIN) {
880 // Other read methods don't limit the number of readers, so just skip this.
881 return;
882 }
883
884 auto loop = Make();
885 std::vector<aos::Fetcher<TestMessage>> fetchers;
886 std::vector<std::unique_ptr<EventLoop>> loops;
887 for (int i = 0; i < 5; ++i) {
888 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
889 loops.emplace_back(Make());
890 loops.back()->MakeWatcher("/test", [](const TestMessage &) {});
891 }
892 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
893 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
894 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
Austin Schuhe516ab02020-05-06 21:37:04 -0700895}
896
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700897// Verify that we can't create a sender inside OnRun.
898TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
899 auto loop1 = MakePrimary();
900
901 loop1->OnRun(
902 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
903
904 EXPECT_DEATH(Run(), "running");
905}
906
907// Verify that we can't create a watcher inside OnRun.
908TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
909 auto loop1 = MakePrimary();
910
911 loop1->OnRun(
912 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
913
914 EXPECT_DEATH(Run(), "running");
915}
916
Brian Silverman454bc112020-03-05 14:21:25 -0800917// Verify that we can't create a no-arg watcher inside OnRun.
918TEST_P(AbstractEventLoopDeathTest, NoArgWatcherInOnRun) {
919 auto loop1 = MakePrimary();
920
921 loop1->OnRun(
922 [&]() { loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {}); });
923
924 EXPECT_DEATH(Run(), "running");
925}
926
Parker Schuhe4a70d62017-12-27 20:10:20 -0800927// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800928TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
929 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700930 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800931
Austin Schuh3578a2e2019-05-25 18:17:59 -0700932 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
933 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700934 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700935 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700936 });
937
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800938 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700939
940 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700941 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
942 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
943 builder.add_value(200);
944 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700945 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800946
Austin Schuh44019f92019-05-19 19:58:27 -0700947 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800948}
949
Neil Balch229001a2018-01-07 18:22:52 -0800950// Verify that timer intervals and duration function properly.
951TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Stephan Pleines3dce7ea2021-06-22 13:19:26 -0700952 // Force a slower rate so we are guaranteed to have reports for our timer.
Austin Schuh39788ff2019-12-01 18:22:57 -0800953 FLAGS_timing_report_ms = 2000;
954
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800955 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800956
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800957 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800958 auto loop2 = Make();
959
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800960 ::std::vector<::aos::monotonic_clock::time_point> times;
961 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
962
Austin Schuh39788ff2019-12-01 18:22:57 -0800963 Fetcher<timing::Report> report_fetcher =
964 loop2->MakeFetcher<timing::Report>("/aos");
965 EXPECT_FALSE(report_fetcher.Fetch());
966
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800967 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
968 times.push_back(loop->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800969 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
970 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
971 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
Austin Schuha9012be2021-07-21 15:19:11 -0700972 EXPECT_EQ(loop->context().source_boot_uuid, loop->boot_uuid());
Austin Schuh39788ff2019-12-01 18:22:57 -0800973 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
974 EXPECT_EQ(loop->context().size, 0u);
975 EXPECT_EQ(loop->context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700976 EXPECT_EQ(loop->context().buffer_index, -1);
Austin Schuh39788ff2019-12-01 18:22:57 -0800977
Austin Schuhad154822019-12-27 15:45:13 -0800978 expected_times.push_back(loop->context().monotonic_event_time);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800979 if (times.size() == kCount) {
980 this->Exit();
981 }
Neil Balch229001a2018-01-07 18:22:52 -0800982 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800983 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800984
Austin Schuh39788ff2019-12-01 18:22:57 -0800985 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700986 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800987 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
988
Austin Schuh44019f92019-05-19 19:58:27 -0700989 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800990
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800991 // Confirm that we got both the right number of samples, and it's odd.
Stephan Pleines3dce7ea2021-06-22 13:19:26 -0700992 ASSERT_EQ(times.size(), static_cast<size_t>(kCount));
993 ASSERT_EQ(times.size(), expected_times.size());
994 ASSERT_EQ((times.size() % 2), 1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800995
996 // Grab the middle sample.
997 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
998
999 // Add up all the delays of all the times.
1000 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1001 for (const ::aos::monotonic_clock::time_point time : times) {
1002 sum += time - average_time;
1003 }
1004
1005 // Average and add to the middle to find the average time.
1006 sum /= times.size();
1007 average_time += sum;
1008
1009 // Compute the offset from the average and the expected average. It
1010 // should be pretty close to 0.
1011 const ::aos::monotonic_clock::duration remainder =
1012 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
1013
1014 const chrono::milliseconds kEpsilon(100);
1015 EXPECT_LT(remainder, +kEpsilon);
1016 EXPECT_GT(remainder, -kEpsilon);
1017
1018 // Make sure that the average duration is close to 1 second.
1019 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1020 times.front())
1021 .count() /
1022 static_cast<double>(times.size() - 1),
1023 1.0, 0.1);
1024
1025 // Confirm that the ideal wakeup times increment correctly.
1026 for (size_t i = 1; i < expected_times.size(); ++i) {
1027 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1028 }
1029
1030 for (size_t i = 0; i < expected_times.size(); ++i) {
1031 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
1032 chrono::seconds(0));
1033 }
1034
1035 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1036 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001037
Austin Schuh6bae8252021-02-07 22:01:49 -08001038 if (do_timing_reports() == DoTimingReports::kYes) {
1039 // And, since we are here, check that the timing report makes sense.
1040 // Start by looking for our event loop's timing.
1041 FlatbufferDetachedBuffer<timing::Report> report =
1042 FlatbufferDetachedBuffer<timing::Report>::Empty();
1043 while (report_fetcher.FetchNext()) {
1044 if (report_fetcher->name()->string_view() == "primary") {
1045 report = CopyFlatBuffer(report_fetcher.get());
1046 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001047 }
Austin Schuh6bae8252021-02-07 22:01:49 -08001048
1049 // Confirm that we have the right number of reports, and the contents are
1050 // sane.
1051 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
1052
1053 EXPECT_EQ(report.message().name()->string_view(), "primary");
1054
1055 ASSERT_NE(report.message().senders(), nullptr);
1056 EXPECT_EQ(report.message().senders()->size(), 2);
1057
1058 ASSERT_NE(report.message().timers(), nullptr);
1059 EXPECT_EQ(report.message().timers()->size(), 2);
1060
1061 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
1062 "Test loop");
1063 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
1064
1065 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
1066 "timing_reports");
1067 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
1068
1069 // Make sure there is a single phased loop report with our report in it.
1070 ASSERT_EQ(report.message().phased_loops(), nullptr);
1071 } else {
1072 ASSERT_FALSE(report_fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -08001073 }
Neil Balch229001a2018-01-07 18:22:52 -08001074}
1075
1076// Verify that we can change a timer's parameters during execution.
1077TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -07001078 auto loop = MakePrimary();
Austin Schuhd892f102021-10-12 18:01:46 -07001079 loop->SetRuntimeRealtimePriority(1);
Austin Schuh7f20f512021-01-31 17:56:16 -08001080 std::vector<monotonic_clock::time_point> iteration_list;
Neil Balch229001a2018-01-07 18:22:52 -08001081
1082 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
Austin Schuh7f20f512021-01-31 17:56:16 -08001083 iteration_list.push_back(loop->context().monotonic_event_time);
Neil Balch229001a2018-01-07 18:22:52 -08001084 });
1085
Austin Schuh7f20f512021-01-31 17:56:16 -08001086 monotonic_clock::time_point s;
1087 auto modifier_timer = loop->AddTimer([&test_timer, &s]() {
Austin Schuhd892f102021-10-12 18:01:46 -07001088 test_timer->Setup(s + chrono::milliseconds(1750),
1089 chrono::milliseconds(600));
Neil Balch229001a2018-01-07 18:22:52 -08001090 });
1091
Austin Schuh7f20f512021-01-31 17:56:16 -08001092 s = loop->monotonic_now();
Austin Schuhd892f102021-10-12 18:01:46 -07001093 test_timer->Setup(s, chrono::milliseconds(500));
1094 modifier_timer->Setup(s + chrono::milliseconds(1250));
1095 EndEventLoop(loop.get(), chrono::milliseconds(3950));
Austin Schuh44019f92019-05-19 19:58:27 -07001096 Run();
Neil Balch229001a2018-01-07 18:22:52 -08001097
Austin Schuhd892f102021-10-12 18:01:46 -07001098 EXPECT_THAT(
1099 iteration_list,
1100 ::testing::ElementsAre(
1101 s, s + chrono::milliseconds(500), s + chrono::milliseconds(1000),
1102 s + chrono::milliseconds(1750), s + chrono::milliseconds(2350),
1103 s + chrono::milliseconds(2950), s + chrono::milliseconds(3550)));
Neil Balch229001a2018-01-07 18:22:52 -08001104}
1105
1106// Verify that we can disable a timer during execution.
1107TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -07001108 auto loop = MakePrimary();
Austin Schuhd892f102021-10-12 18:01:46 -07001109 loop->SetRuntimeRealtimePriority(1);
Neil Balch229001a2018-01-07 18:22:52 -08001110 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
1111
1112 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
Austin Schuhd892f102021-10-12 18:01:46 -07001113 iteration_list.push_back(loop->context().monotonic_event_time);
Neil Balch229001a2018-01-07 18:22:52 -08001114 });
1115
Tyler Chatow67ddb032020-01-12 14:30:04 -08001116 auto ender_timer = loop->AddTimer([&test_timer]() { test_timer->Disable(); });
Neil Balch229001a2018-01-07 18:22:52 -08001117
Austin Schuhd892f102021-10-12 18:01:46 -07001118 monotonic_clock::time_point s = loop->monotonic_now();
1119 test_timer->Setup(s, ::std::chrono::milliseconds(70));
1120 ender_timer->Setup(s + ::std::chrono::milliseconds(200));
1121 EndEventLoop(loop.get(), ::std::chrono::milliseconds(350));
Austin Schuh44019f92019-05-19 19:58:27 -07001122 Run();
Neil Balch229001a2018-01-07 18:22:52 -08001123
Austin Schuhd892f102021-10-12 18:01:46 -07001124 EXPECT_THAT(iteration_list,
1125 ::testing::ElementsAre(s, s + chrono::milliseconds(70),
1126 s + chrono::milliseconds(140)));
Neil Balch229001a2018-01-07 18:22:52 -08001127}
Austin Schuh7267c532019-05-19 19:55:53 -07001128
Brian Silvermanaf9a4d82020-10-06 15:10:58 -07001129// Verify that a timer can disable itself.
1130//
1131// TODO(Brian): Do something similar with phased loops, both with a quick
1132// handler and a handler that would miss a cycle except it got deferred. Current
1133// behavior doing that is a mess.
1134TEST_P(AbstractEventLoopTest, TimerDisableSelf) {
1135 auto loop = MakePrimary();
1136
1137 int count = 0;
1138 aos::TimerHandler *test_timer;
1139 test_timer = loop->AddTimer([&count, &test_timer]() {
1140 ++count;
1141 test_timer->Disable();
1142 });
1143
1144 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
1145 EndEventLoop(loop.get(), ::std::chrono::milliseconds(80));
1146 Run();
1147
1148 EXPECT_EQ(count, 1);
1149}
1150
Brian Silvermanbd405c02020-06-23 16:25:23 -07001151// Verify that we can disable a timer during execution of another timer
1152// scheduled for the same time, with one ordering of creation for the timers.
1153//
1154// Also schedule some more events to reshuffle the heap in EventLoop used for
1155// tracking events to change up the order. This used to segfault
1156// SimulatedEventLoop.
1157TEST_P(AbstractEventLoopTest, TimerDisableOther) {
1158 for (bool creation_order : {true, false}) {
1159 for (bool setup_order : {true, false}) {
1160 for (int shuffle_events = 0; shuffle_events < 5; ++shuffle_events) {
1161 auto loop = MakePrimary();
1162 aos::TimerHandler *test_timer, *ender_timer;
1163 if (creation_order) {
1164 test_timer = loop->AddTimer([]() {});
1165 ender_timer =
1166 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1167 } else {
1168 ender_timer =
1169 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1170 test_timer = loop->AddTimer([]() {});
1171 }
1172
1173 const auto start = loop->monotonic_now();
1174
1175 for (int i = 0; i < shuffle_events; ++i) {
1176 loop->AddTimer([]() {})->Setup(start + std::chrono::milliseconds(10));
1177 }
1178
1179 if (setup_order) {
1180 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1181 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1182 } else {
1183 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1184 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1185 }
1186 EndEventLoop(loop.get(), ::std::chrono::milliseconds(40));
1187 Run();
1188 }
1189 }
1190 }
1191}
1192
Austin Schuh54cf95f2019-11-29 13:14:18 -08001193// Verifies that the event loop implementations detect when Channel is not a
Brian Silverman631b6262021-11-10 12:25:08 -08001194// pointer into configuration(), or a name doesn't map to a channel in
1195// configuration().
Austin Schuh54cf95f2019-11-29 13:14:18 -08001196TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
1197 auto loop = MakePrimary();
1198
Tyler Chatow67ddb032020-01-12 14:30:04 -08001199 const Channel *channel = configuration::GetChannel(
1200 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
Austin Schuh54cf95f2019-11-29 13:14:18 -08001201
1202 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
1203
1204 EXPECT_DEATH(
Brian Silverman631b6262021-11-10 12:25:08 -08001205 loop->MakeRawSender(&channel_copy.message()),
Austin Schuh54cf95f2019-11-29 13:14:18 -08001206 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1207
1208 EXPECT_DEATH(
Brian Silverman631b6262021-11-10 12:25:08 -08001209 loop->MakeSender<TestMessage>("/testbad"),
1210 "Channel \\{ \"name\": \"/testbad\", \"type\": \"aos.TestMessage\" \\}"
1211 " not found in config");
1212
1213 EXPECT_FALSE(loop->TryMakeSender<TestMessage>("/testbad"));
1214
1215 EXPECT_DEATH(
1216 loop->MakeRawFetcher(&channel_copy.message()),
Austin Schuh54cf95f2019-11-29 13:14:18 -08001217 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1218
1219 EXPECT_DEATH(
Brian Silverman631b6262021-11-10 12:25:08 -08001220 loop->MakeFetcher<TestMessage>("/testbad"),
1221 "Channel \\{ \"name\": \"/testbad\", \"type\": \"aos.TestMessage\" \\}"
1222 " not found in config");
1223
1224 EXPECT_FALSE(loop->TryMakeFetcher<TestMessage>("/testbad").valid());
1225
1226 EXPECT_DEATH(
Austin Schuh54cf95f2019-11-29 13:14:18 -08001227 {
1228 loop->MakeRawWatcher(&channel_copy.message(),
1229 [](const Context, const void *) {});
1230 },
1231 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
Brian Silverman631b6262021-11-10 12:25:08 -08001232
1233 EXPECT_DEATH(
1234 { loop->MakeWatcher("/testbad", [](const TestMessage &) {}); },
1235 "Channel \\{ \"name\": \"/testbad\", \"type\": \"aos.TestMessage\" \\}"
1236 " not found in config");
1237}
1238
1239// Verifies that the event loop handles a channel which is not readable or
1240// writable on the current node nicely.
1241TEST_P(AbstractEventLoopDeathTest, InaccessibleChannel) {
1242 EnableNodes("me");
1243 auto loop = MakePrimary("me");
1244 auto loop2 = Make("them");
1245
1246 const Channel *channel = configuration::GetChannel(
1247 loop->configuration(), "/test_noforward", "aos.TestMessage", "", nullptr);
1248
1249 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
1250
1251 EXPECT_DEATH(
1252 loop2->MakeSender<TestMessage>("/test_forward"),
1253 "Channel"
1254 " \\{ \"name\": \"/test_forward\", \"type\": \"aos.TestMessage\" \\}"
1255 " is not able to be sent on this node");
1256
1257 EXPECT_FALSE(loop2->TryMakeSender<TestMessage>("/test_forward"));
1258
1259 EXPECT_DEATH(
1260 loop2->MakeRawFetcher(channel),
1261 "Channel"
1262 " \\{ \"name\": \"/test_noforward\", \"type\": \"aos.TestMessage\" \\}"
1263 " is not able to be fetched on this node");
1264
1265 EXPECT_DEATH(
1266 loop2->MakeFetcher<TestMessage>("/test_noforward"),
1267 "Channel"
1268 " \\{ \"name\": \"/test_noforward\", \"type\": \"aos.TestMessage\" \\}"
1269 " is not able to be fetched on this node");
1270
1271 EXPECT_FALSE(loop2->TryMakeFetcher<TestMessage>("/test_noforward").valid());
1272
1273 EXPECT_DEATH(
1274 { loop2->MakeRawWatcher(channel, [](const Context, const void *) {}); },
1275 "\\{ \"name\": \"/test_noforward\", \"type\": \"aos.TestMessage\", "
1276 "\"source_node\": \"them\" \\}"
1277 " is not able to be watched on this node");
1278
1279 EXPECT_DEATH(
1280 { loop2->MakeWatcher("/test_noforward", [](const TestMessage &) {}); },
1281 "\\{ \"name\": \"/test_noforward\", \"type\": \"aos.TestMessage\", "
1282 "\"source_node\": \"them\" \\}"
1283 " is not able to be watched on this node");
Austin Schuh54cf95f2019-11-29 13:14:18 -08001284}
1285
Austin Schuhd54780b2020-10-03 16:26:02 -07001286// Verifies that the event loop implementations detect when Channel has an
1287// invalid alignment.
1288TEST_P(AbstractEventLoopDeathTest, InvalidChannelAlignment) {
1289 const char *const kError = "multiple of alignment";
1290 InvalidChannelAlignment();
1291
1292 auto loop = MakePrimary();
1293
1294 const Channel *channel = configuration::GetChannel(
1295 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
1296
1297 EXPECT_DEATH({ loop->MakeRawSender(channel); }, kError);
1298 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); }, kError);
1299
1300 EXPECT_DEATH({ loop->MakeRawFetcher(channel); }, kError);
1301 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); }, kError);
1302
1303 EXPECT_DEATH(
1304 { loop->MakeRawWatcher(channel, [](const Context &, const void *) {}); },
1305 kError);
1306 EXPECT_DEATH({ loop->MakeRawNoArgWatcher(channel, [](const Context &) {}); },
1307 kError);
1308
1309 EXPECT_DEATH({ loop->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1310 kError);
1311 EXPECT_DEATH({ loop->MakeWatcher("/test", [](const TestMessage &) {}); },
1312 kError);
1313}
1314
Brian Silverman454bc112020-03-05 14:21:25 -08001315// Verify that the send time on a message is roughly right when using a watcher.
Austin Schuh7267c532019-05-19 19:55:53 -07001316TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -07001317 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -07001318 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -08001319 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -07001320 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
1321
1322 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -07001323 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1324 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1325 builder.add_value(200);
1326 ASSERT_TRUE(msg.Send(builder.Finish()));
1327 });
1328
Austin Schuhad154822019-12-27 15:45:13 -08001329 bool triggered = false;
Brian Silverman454bc112020-03-05 14:21:25 -08001330 loop1->MakeWatcher("/test", [&](const TestMessage &msg) {
Austin Schuhad154822019-12-27 15:45:13 -08001331 // Confirm that the data pointer makes sense from a watcher, and all the
1332 // timestamps look right.
1333 EXPECT_GT(&msg, loop1->context().data);
1334 EXPECT_EQ(loop1->context().monotonic_remote_time,
1335 loop1->context().monotonic_event_time);
1336 EXPECT_EQ(loop1->context().realtime_remote_time,
1337 loop1->context().realtime_event_time);
Austin Schuha9012be2021-07-21 15:19:11 -07001338 EXPECT_EQ(loop1->context().source_boot_uuid, loop1->boot_uuid());
Austin Schuhad154822019-12-27 15:45:13 -08001339
1340 const aos::monotonic_clock::time_point monotonic_now =
1341 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -08001342 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001343
1344 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1345 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1346 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1347 monotonic_now);
1348 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1349 realtime_now);
1350
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001351 EXPECT_LT(&msg, reinterpret_cast<const void *>(
1352 reinterpret_cast<const char *>(loop1->context().data) +
Austin Schuhad154822019-12-27 15:45:13 -08001353 loop1->context().size));
Brian Silverman4f4e0612020-08-12 19:54:41 -07001354 if (read_method() == ReadMethod::PIN) {
1355 EXPECT_GE(loop1->context().buffer_index, 0);
1356 EXPECT_LT(loop1->context().buffer_index,
1357 loop1->NumberBuffers(
1358 configuration::GetChannel(loop1->configuration(), "/test",
1359 "aos.TestMessage", "", nullptr)));
1360 } else {
1361 EXPECT_EQ(-1, loop1->context().buffer_index);
1362 }
Austin Schuhad154822019-12-27 15:45:13 -08001363 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -07001364 });
1365
1366 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1367
1368 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -07001369 Run();
Austin Schuh7267c532019-05-19 19:55:53 -07001370
Austin Schuhad154822019-12-27 15:45:13 -08001371 EXPECT_TRUE(triggered);
1372
Brian Silverman454bc112020-03-05 14:21:25 -08001373 ASSERT_TRUE(fetcher.Fetch());
1374
1375 monotonic_clock::duration monotonic_time_offset =
1376 fetcher.context().monotonic_event_time -
1377 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1378 realtime_clock::duration realtime_time_offset =
1379 fetcher.context().realtime_event_time -
1380 (loop1->realtime_now() - ::std::chrono::seconds(1));
1381
1382 EXPECT_EQ(fetcher.context().realtime_event_time,
1383 fetcher.context().realtime_remote_time);
1384 EXPECT_EQ(fetcher.context().monotonic_event_time,
1385 fetcher.context().monotonic_remote_time);
Austin Schuha9012be2021-07-21 15:19:11 -07001386 EXPECT_EQ(fetcher.context().source_boot_uuid, loop1->boot_uuid());
Brian Silverman454bc112020-03-05 14:21:25 -08001387
1388 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1389 << ": Got "
1390 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1391 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1392 // Confirm that the data pointer makes sense.
1393 EXPECT_GT(fetcher.get(), fetcher.context().data);
1394 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001395 reinterpret_cast<const void *>(
1396 reinterpret_cast<const char *>(fetcher.context().data) +
Brian Silverman454bc112020-03-05 14:21:25 -08001397 fetcher.context().size));
1398 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1399 << ": Got "
1400 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1401 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1402
1403 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1404 << ": Got "
1405 << fetcher.context().realtime_event_time.time_since_epoch().count()
1406 << " expected " << loop1->realtime_now().time_since_epoch().count();
1407 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1408 << ": Got "
1409 << fetcher.context().realtime_event_time.time_since_epoch().count()
1410 << " expected " << loop1->realtime_now().time_since_epoch().count();
1411}
1412
1413// Verify that the send time on a message is roughly right when using a no-arg
1414// watcher. To get a message, we need to use a fetcher to actually access the
1415// message. This is also the main use case for no-arg fetchers.
1416TEST_P(AbstractEventLoopTest, MessageSendTimeNoArg) {
1417 auto loop1 = MakePrimary();
1418 auto loop2 = Make();
1419 auto sender = loop2->MakeSender<TestMessage>("/test");
1420 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1421
1422 auto test_timer = loop1->AddTimer([&sender]() {
1423 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1424 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1425 builder.add_value(200);
1426 ASSERT_TRUE(msg.Send(builder.Finish()));
1427 });
1428
1429 bool triggered = false;
1430 loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {
1431 // Confirm that we can indeed use a fetcher on this channel from this
1432 // context, and it results in a sane data pointer and timestamps.
1433 ASSERT_TRUE(fetcher.Fetch());
1434
1435 EXPECT_EQ(loop1->context().monotonic_remote_time,
1436 loop1->context().monotonic_event_time);
1437 EXPECT_EQ(loop1->context().realtime_remote_time,
1438 loop1->context().realtime_event_time);
Austin Schuha9012be2021-07-21 15:19:11 -07001439 EXPECT_EQ(loop1->context().source_boot_uuid, loop1->boot_uuid());
Brian Silverman454bc112020-03-05 14:21:25 -08001440
1441 const aos::monotonic_clock::time_point monotonic_now =
1442 loop1->monotonic_now();
1443 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
1444
1445 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1446 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1447 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1448 monotonic_now);
1449 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1450 realtime_now);
1451
1452 triggered = true;
1453 });
1454
1455 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1456
1457 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
1458 Run();
1459
1460 ASSERT_TRUE(triggered);
Austin Schuh7267c532019-05-19 19:55:53 -07001461
Alex Perrycb7da4b2019-08-28 19:35:56 -07001462 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001463 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001464 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1465 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001466 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001467 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -07001468
Austin Schuhad154822019-12-27 15:45:13 -08001469 EXPECT_EQ(fetcher.context().realtime_event_time,
1470 fetcher.context().realtime_remote_time);
1471 EXPECT_EQ(fetcher.context().monotonic_event_time,
1472 fetcher.context().monotonic_remote_time);
Austin Schuha9012be2021-07-21 15:19:11 -07001473 EXPECT_EQ(fetcher.context().source_boot_uuid, loop1->boot_uuid());
Austin Schuhad154822019-12-27 15:45:13 -08001474
Alex Perrycb7da4b2019-08-28 19:35:56 -07001475 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1476 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001477 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -07001478 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001479 // Confirm that the data pointer makes sense.
1480 EXPECT_GT(fetcher.get(), fetcher.context().data);
1481 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001482 reinterpret_cast<const void *>(
1483 reinterpret_cast<const char *>(fetcher.context().data) +
Alex Perrycb7da4b2019-08-28 19:35:56 -07001484 fetcher.context().size));
1485 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1486 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001487 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -07001488 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001489
1490 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1491 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001492 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001493 << " expected " << loop1->realtime_now().time_since_epoch().count();
1494 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1495 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001496 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001497 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -07001498}
1499
Austin Schuh52d325c2019-06-23 18:59:06 -07001500// Tests that a couple phased loops run in a row result in the correct offset
1501// and period.
1502TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Stephan Pleines3dce7ea2021-06-22 13:19:26 -07001503 // Force a slower rate so we are guaranteed to have reports for our phased
Austin Schuh39788ff2019-12-01 18:22:57 -08001504 // loop.
1505 FLAGS_timing_report_ms = 2000;
1506
Austin Schuh52d325c2019-06-23 18:59:06 -07001507 const chrono::milliseconds kOffset = chrono::milliseconds(400);
1508 const int kCount = 5;
1509
1510 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -08001511 auto loop2 = Make();
1512
1513 Fetcher<timing::Report> report_fetcher =
1514 loop2->MakeFetcher<timing::Report>("/aos");
1515 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001516
1517 // Collect up a couple of samples.
1518 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001519 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -07001520
1521 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -08001522 loop1
1523 ->AddPhasedLoop(
1524 [&times, &expected_times, &loop1, this](int count) {
1525 EXPECT_EQ(count, 1);
1526 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -08001527 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -08001528
Austin Schuhad154822019-12-27 15:45:13 -08001529 EXPECT_EQ(loop1->context().monotonic_remote_time,
1530 monotonic_clock::min_time);
Austin Schuha9012be2021-07-21 15:19:11 -07001531 EXPECT_EQ(loop1->context().source_boot_uuid, loop1->boot_uuid());
Austin Schuhad154822019-12-27 15:45:13 -08001532 EXPECT_EQ(loop1->context().realtime_event_time,
1533 realtime_clock::min_time);
1534 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -08001535 realtime_clock::min_time);
1536 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
1537 EXPECT_EQ(loop1->context().size, 0u);
1538 EXPECT_EQ(loop1->context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -07001539 EXPECT_EQ(loop1->context().buffer_index, -1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001540
1541 if (times.size() == kCount) {
1542 LOG(INFO) << "Exiting";
1543 this->Exit();
1544 }
1545 },
1546 chrono::seconds(1), kOffset)
1547 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -07001548
1549 // Add a delay to make sure that delay during startup doesn't result in a
1550 // "missed cycle".
1551 SleepFor(chrono::seconds(2));
1552
1553 Run();
1554
1555 // Confirm that we got both the right number of samples, and it's odd.
Stephan Pleines3dce7ea2021-06-22 13:19:26 -07001556 ASSERT_EQ(times.size(), static_cast<size_t>(kCount));
1557 ASSERT_EQ(times.size(), expected_times.size());
1558 ASSERT_EQ((times.size() % 2), 1);
Austin Schuh52d325c2019-06-23 18:59:06 -07001559
1560 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001561 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -07001562
1563 // Add up all the delays of all the times.
1564 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1565 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001566 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -07001567 }
1568
1569 // Average and add to the middle to find the average time.
1570 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001571 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -07001572
1573 // Compute the offset from the start of the second of the average time. This
1574 // should be pretty close to the offset.
1575 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001576 average_time.time_since_epoch() -
1577 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001578
1579 const chrono::milliseconds kEpsilon(100);
1580 EXPECT_LT(remainder, kOffset + kEpsilon);
1581 EXPECT_GT(remainder, kOffset - kEpsilon);
1582
1583 // Make sure that the average duration is close to 1 second.
1584 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1585 times.front())
1586 .count() /
1587 static_cast<double>(times.size() - 1),
1588 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001589
1590 // Confirm that the ideal wakeup times increment correctly.
1591 for (size_t i = 1; i < expected_times.size(); ++i) {
1592 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1593 }
1594
1595 for (size_t i = 0; i < expected_times.size(); ++i) {
1596 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1597 kOffset);
1598 }
1599
1600 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1601 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001602
Austin Schuh6bae8252021-02-07 22:01:49 -08001603 if (do_timing_reports() == DoTimingReports::kYes) {
1604 // And, since we are here, check that the timing report makes sense.
1605 // Start by looking for our event loop's timing.
1606 FlatbufferDetachedBuffer<timing::Report> report =
1607 FlatbufferDetachedBuffer<timing::Report>::Empty();
1608 while (report_fetcher.FetchNext()) {
1609 if (report_fetcher->name()->string_view() == "primary") {
1610 report = CopyFlatBuffer(report_fetcher.get());
1611 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001612 }
Austin Schuh6bae8252021-02-07 22:01:49 -08001613
1614 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
1615
1616 EXPECT_EQ(report.message().name()->string_view(), "primary");
1617
1618 ASSERT_NE(report.message().senders(), nullptr);
1619 EXPECT_EQ(report.message().senders()->size(), 2);
1620
1621 ASSERT_NE(report.message().timers(), nullptr);
1622 EXPECT_EQ(report.message().timers()->size(), 1);
1623
1624 // Make sure there is a single phased loop report with our report in it.
1625 ASSERT_NE(report.message().phased_loops(), nullptr);
1626 ASSERT_EQ(report.message().phased_loops()->size(), 1);
1627 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
1628 "Test loop");
1629 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
1630 } else {
1631 ASSERT_FALSE(report_fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -08001632 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001633}
1634
Milind Upadhyay42589bb2021-05-19 20:05:16 -07001635// Tests that a phased loop responds correctly to a changing offset.
1636TEST_P(AbstractEventLoopTest, PhasedLoopChangingOffsetTest) {
1637 // Force a slower rate so we are guaranteed to have reports for our phased
1638 // loop.
1639 FLAGS_timing_report_ms = 2000;
1640
1641 const chrono::milliseconds kOffset = chrono::milliseconds(400);
1642 const chrono::milliseconds kInterval = chrono::milliseconds(1000);
1643 const int kCount = 5;
1644
1645 auto loop1 = MakePrimary();
1646
1647 // Collect up a couple of samples.
1648 ::std::vector<::aos::monotonic_clock::time_point> times;
1649 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
1650
1651 PhasedLoopHandler *phased_loop;
1652
1653 // Run kCount iterations.
1654 phased_loop = loop1->AddPhasedLoop(
1655 [&phased_loop, &times, &expected_times, &loop1, this, kOffset,
1656 kInterval](int count) {
1657 EXPECT_EQ(count, 1);
1658 times.push_back(loop1->monotonic_now());
1659
1660 expected_times.push_back(loop1->context().monotonic_event_time);
1661
1662 phased_loop->set_interval_and_offset(
1663 kInterval, kOffset - chrono::milliseconds(times.size()));
1664 LOG(INFO) << "new offset: "
1665 << (kOffset - chrono::milliseconds(times.size())).count();
1666
1667 if (times.size() == kCount) {
1668 LOG(INFO) << "Exiting";
1669 this->Exit();
1670 }
1671 },
1672 kInterval, kOffset);
1673 phased_loop->set_name("Test loop");
1674
1675 // Add a delay to make sure that delay during startup doesn't result in a
1676 // "missed cycle".
1677 SleepFor(chrono::seconds(2));
1678
1679 Run();
1680 // Confirm that we got both the right number of samples, and it's odd.
1681 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
1682 EXPECT_EQ(times.size(), expected_times.size());
1683 EXPECT_EQ((times.size() % 2), 1);
1684
1685 // Grab the middle sample.
1686 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
1687
1688 // Add up all the delays of all the times.
1689 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1690 for (const ::aos::monotonic_clock::time_point time : times) {
1691 sum += time - average_time;
1692 }
1693
1694 // Average and add to the middle to find the average time.
1695 sum /= times.size();
1696 average_time += sum;
1697
1698 // Compute the offset from the start of the second of the average time. This
1699 // should be pretty close to the offset.
1700 const ::aos::monotonic_clock::duration remainder =
1701 average_time.time_since_epoch() -
1702 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
1703
1704 const chrono::milliseconds kEpsilon(100);
1705 EXPECT_LT(remainder, kOffset + kEpsilon);
1706 EXPECT_GT(remainder, kOffset - kEpsilon);
1707
1708 // Make sure that the average duration is close to 1 second.
1709 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1710 times.front())
1711 .count() /
1712 static_cast<double>(times.size() - 1),
1713 1.0, 0.1);
1714
1715 // Confirm that the ideal wakeup times increment correctly.
1716 for (size_t i = 1; i < expected_times.size(); ++i) {
1717 LOG(INFO) << i - 1 << ": " << expected_times[i - 1] << ", " << i << ": "
1718 << expected_times[i];
1719 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1) -
1720 chrono::milliseconds(1));
1721 }
1722
1723 for (size_t i = 0; i < expected_times.size(); ++i) {
1724 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1725 kOffset - chrono::milliseconds(i));
1726 }
1727
1728 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1729 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
1730}
1731
Austin Schuh39788ff2019-12-01 18:22:57 -08001732// Tests that senders count correctly in the timing report.
1733TEST_P(AbstractEventLoopTest, SenderTimingReport) {
1734 FLAGS_timing_report_ms = 1000;
1735 auto loop1 = MakePrimary();
1736
1737 auto loop2 = Make("watcher_loop");
1738 loop2->MakeWatcher("/test", [](const TestMessage &) {});
1739
1740 auto loop3 = Make();
1741
1742 Fetcher<timing::Report> report_fetcher =
1743 loop3->MakeFetcher<timing::Report>("/aos");
1744 EXPECT_FALSE(report_fetcher.Fetch());
1745
1746 auto sender = loop1->MakeSender<TestMessage>("/test");
1747
1748 // Add a timer to actually quit.
1749 auto test_timer = loop1->AddTimer([&sender]() {
1750 for (int i = 0; i < 10; ++i) {
1751 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1752 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1753 builder.add_value(200 + i);
1754 ASSERT_TRUE(msg.Send(builder.Finish()));
1755 }
1756 });
1757
1758 // Quit after 1 timing report, mid way through the next cycle.
1759 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1760
1761 loop1->OnRun([&test_timer, &loop1]() {
1762 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1763 });
1764
1765 Run();
1766
Austin Schuh6bae8252021-02-07 22:01:49 -08001767 if (do_timing_reports() == DoTimingReports::kYes) {
1768 // And, since we are here, check that the timing report makes sense.
1769 // Start by looking for our event loop's timing.
1770 FlatbufferDetachedBuffer<timing::Report> primary_report =
1771 FlatbufferDetachedBuffer<timing::Report>::Empty();
1772 while (report_fetcher.FetchNext()) {
Austin Schuh8902fa52021-03-14 22:39:24 -07001773 VLOG(1) << "Report " << FlatbufferToJson(report_fetcher.get());
Austin Schuh6bae8252021-02-07 22:01:49 -08001774 if (report_fetcher->name()->string_view() == "primary") {
1775 primary_report = CopyFlatBuffer(report_fetcher.get());
1776 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001777 }
Austin Schuh6bae8252021-02-07 22:01:49 -08001778
Austin Schuh8902fa52021-03-14 22:39:24 -07001779 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh6bae8252021-02-07 22:01:49 -08001780
1781 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1782
1783 ASSERT_NE(primary_report.message().senders(), nullptr);
1784 EXPECT_EQ(primary_report.message().senders()->size(), 3);
1785
1786 // Confirm that the sender looks sane.
1787 EXPECT_EQ(
1788 loop1->configuration()
1789 ->channels()
1790 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1791 ->name()
1792 ->string_view(),
1793 "/test");
1794 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1795
1796 // Confirm that the timing primary_report sender looks sane.
1797 EXPECT_EQ(
1798 loop1->configuration()
1799 ->channels()
1800 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1801 ->name()
1802 ->string_view(),
1803 "/aos");
1804 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1805
1806 ASSERT_NE(primary_report.message().timers(), nullptr);
1807 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1808
1809 // Make sure there are no phased loops or watchers.
1810 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1811 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1812 } else {
1813 ASSERT_FALSE(report_fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -08001814 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001815}
1816
1817// Tests that senders count correctly in the timing report.
1818TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1819 FLAGS_timing_report_ms = 1000;
1820 auto loop1 = MakePrimary();
1821 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1822
1823 auto loop2 = Make("sender_loop");
1824
1825 auto loop3 = Make();
1826
1827 Fetcher<timing::Report> report_fetcher =
1828 loop3->MakeFetcher<timing::Report>("/aos");
1829 EXPECT_FALSE(report_fetcher.Fetch());
1830
1831 auto sender = loop2->MakeSender<TestMessage>("/test");
1832
1833 // Add a timer to actually quit.
1834 auto test_timer = loop1->AddTimer([&sender]() {
1835 for (int i = 0; i < 10; ++i) {
1836 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1837 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1838 builder.add_value(200 + i);
1839 ASSERT_TRUE(msg.Send(builder.Finish()));
1840 }
1841 });
1842
1843 // Quit after 1 timing report, mid way through the next cycle.
1844 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1845
1846 loop1->OnRun([&test_timer, &loop1]() {
1847 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1848 });
1849
1850 Run();
1851
Austin Schuh6bae8252021-02-07 22:01:49 -08001852 if (do_timing_reports() == DoTimingReports::kYes) {
1853 // And, since we are here, check that the timing report makes sense.
1854 // Start by looking for our event loop's timing.
1855 FlatbufferDetachedBuffer<timing::Report> primary_report =
1856 FlatbufferDetachedBuffer<timing::Report>::Empty();
1857 while (report_fetcher.FetchNext()) {
1858 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1859 if (report_fetcher->name()->string_view() == "primary") {
1860 primary_report = CopyFlatBuffer(report_fetcher.get());
1861 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001862 }
Austin Schuh6bae8252021-02-07 22:01:49 -08001863
1864 // Check the watcher report.
1865 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
1866
1867 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1868
1869 // Just the timing report timer.
1870 ASSERT_NE(primary_report.message().timers(), nullptr);
1871 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1872
1873 // No phased loops
1874 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1875
1876 ASSERT_NE(primary_report.message().watchers(), nullptr);
1877 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1878 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1879 } else {
1880 ASSERT_FALSE(report_fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -08001881 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001882}
1883
1884// Tests that fetchers count correctly in the timing report.
1885TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1886 FLAGS_timing_report_ms = 1000;
1887 auto loop1 = MakePrimary();
1888 auto loop2 = Make("sender_loop");
1889
1890 auto loop3 = Make();
1891
1892 Fetcher<timing::Report> report_fetcher =
1893 loop3->MakeFetcher<timing::Report>("/aos");
1894 EXPECT_FALSE(report_fetcher.Fetch());
1895
1896 auto sender = loop2->MakeSender<TestMessage>("/test");
1897 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1898 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1899 fetcher1.Fetch();
1900 fetcher2.Fetch();
1901
1902 // Add a timer to actually quit.
1903 auto test_timer = loop1->AddTimer([&sender]() {
1904 for (int i = 0; i < 10; ++i) {
1905 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1906 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1907 builder.add_value(200 + i);
1908 ASSERT_TRUE(msg.Send(builder.Finish()));
1909 }
1910 });
1911
1912 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1913 fetcher1.Fetch();
1914 while (fetcher2.FetchNext()) {
1915 }
1916 });
1917
1918 // Quit after 1 timing report, mid way through the next cycle.
1919 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1920
1921 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1922 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1923 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1924 });
1925
1926 Run();
1927
Austin Schuh6bae8252021-02-07 22:01:49 -08001928 if (do_timing_reports() == DoTimingReports::kYes) {
1929 // And, since we are here, check that the timing report makes sense.
1930 // Start by looking for our event loop's timing.
1931 FlatbufferDetachedBuffer<timing::Report> primary_report =
1932 FlatbufferDetachedBuffer<timing::Report>::Empty();
1933 while (report_fetcher.FetchNext()) {
1934 if (report_fetcher->name()->string_view() == "primary") {
1935 primary_report = CopyFlatBuffer(report_fetcher.get());
1936 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001937 }
Austin Schuh6bae8252021-02-07 22:01:49 -08001938
1939 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
1940
1941 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1942
1943 ASSERT_NE(primary_report.message().senders(), nullptr);
1944 EXPECT_EQ(primary_report.message().senders()->size(), 2);
1945
1946 ASSERT_NE(primary_report.message().timers(), nullptr);
1947 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1948
1949 // Make sure there are no phased loops or watchers.
1950 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1951 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1952
1953 // Now look at the fetchrs.
1954 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1955 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1956
1957 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1958 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1959 0.1);
1960 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(),
1961 0.1);
1962 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(),
1963 0.1);
1964 EXPECT_EQ(primary_report.message()
1965 .fetchers()
1966 ->Get(0)
1967 ->latency()
1968 ->standard_deviation(),
1969 0.0);
1970
1971 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
1972 } else {
1973 ASSERT_FALSE(report_fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -08001974 }
Austin Schuh52d325c2019-06-23 18:59:06 -07001975}
1976
Austin Schuh67420a42019-12-21 21:55:04 -08001977// Tests that a raw watcher and raw fetcher can receive messages from a raw
1978// sender without messing up offsets.
1979TEST_P(AbstractEventLoopTest, RawBasic) {
1980 auto loop1 = Make();
1981 auto loop2 = MakePrimary();
1982 auto loop3 = Make();
1983
Austin Schuha9df9ad2021-06-16 14:49:39 -07001984 const FlatbufferDetachedBuffer<TestMessage> kMessage =
1985 JsonToFlatbuffer<TestMessage>("{}");
Austin Schuh67420a42019-12-21 21:55:04 -08001986
1987 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001988 loop1->MakeRawSender(configuration::GetChannel(
1989 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001990
1991 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001992 loop3->MakeRawFetcher(configuration::GetChannel(
1993 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001994
Austin Schuha9df9ad2021-06-16 14:49:39 -07001995 loop2->OnRun([&]() {
1996 EXPECT_TRUE(sender->Send(kMessage.span().data(), kMessage.span().size()));
1997 });
Austin Schuh67420a42019-12-21 21:55:04 -08001998
1999 bool happened = false;
2000 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08002001 configuration::GetChannel(loop2->configuration(), "/test",
2002 "aos.TestMessage", "", nullptr),
Austin Schuha9df9ad2021-06-16 14:49:39 -07002003 [this, &kMessage, &fetcher, &happened](const Context &context,
2004 const void *message) {
Austin Schuh67420a42019-12-21 21:55:04 -08002005 happened = true;
Austin Schuha9df9ad2021-06-16 14:49:39 -07002006 EXPECT_EQ(
2007 kMessage.span(),
2008 absl::Span<const uint8_t>(
2009 reinterpret_cast<const uint8_t *>(message), context.size));
2010 EXPECT_EQ(message, context.data);
Austin Schuh67420a42019-12-21 21:55:04 -08002011
2012 ASSERT_TRUE(fetcher->Fetch());
2013
Austin Schuha9df9ad2021-06-16 14:49:39 -07002014 EXPECT_EQ(kMessage.span(),
2015 absl::Span<const uint8_t>(reinterpret_cast<const uint8_t *>(
2016 fetcher->context().data),
2017 fetcher->context().size));
Austin Schuh67420a42019-12-21 21:55:04 -08002018
2019 this->Exit();
2020 });
2021
2022 EXPECT_FALSE(happened);
2023 Run();
2024 EXPECT_TRUE(happened);
2025}
2026
Austin Schuhad154822019-12-27 15:45:13 -08002027// Tests that a raw watcher and raw fetcher can receive messages from a raw
Brian Silvermanbf889922021-11-10 12:41:57 -08002028// sender without messing up offsets, using the RawSpan overload.
2029TEST_P(AbstractEventLoopTest, RawBasicSharedSpan) {
2030 auto loop1 = Make();
2031 auto loop2 = MakePrimary();
2032 auto loop3 = Make();
2033
2034 const FlatbufferDetachedBuffer<TestMessage> kMessage =
2035 JsonToFlatbuffer<TestMessage>("{}");
2036
2037 std::unique_ptr<aos::RawSender> sender =
2038 loop1->MakeRawSender(configuration::GetChannel(
2039 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
2040
2041 std::unique_ptr<aos::RawFetcher> fetcher =
2042 loop3->MakeRawFetcher(configuration::GetChannel(
2043 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
2044
2045 loop2->OnRun([&]() {
2046 EXPECT_TRUE(sender->Send(std::make_shared<absl::Span<const uint8_t>>(
2047 kMessage.span().data(), kMessage.span().size())));
2048 });
2049
2050 bool happened = false;
2051 loop2->MakeRawWatcher(
2052 configuration::GetChannel(loop2->configuration(), "/test",
2053 "aos.TestMessage", "", nullptr),
2054 [this, &kMessage, &fetcher, &happened](const Context &context,
2055 const void *message) {
2056 happened = true;
2057 EXPECT_EQ(
2058 kMessage.span(),
2059 absl::Span<const uint8_t>(
2060 reinterpret_cast<const uint8_t *>(message), context.size));
2061 EXPECT_EQ(message, context.data);
2062
2063 ASSERT_TRUE(fetcher->Fetch());
2064
2065 EXPECT_EQ(kMessage.span(),
2066 absl::Span<const uint8_t>(reinterpret_cast<const uint8_t *>(
2067 fetcher->context().data),
2068 fetcher->context().size));
2069
2070 this->Exit();
2071 });
2072
2073 EXPECT_FALSE(happened);
2074 Run();
2075 EXPECT_TRUE(happened);
2076}
2077
2078// Tests that a raw watcher and raw fetcher can receive messages from a raw
Austin Schuhad154822019-12-27 15:45:13 -08002079// sender with remote times filled out.
2080TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
2081 auto loop1 = Make();
2082 auto loop2 = MakePrimary();
2083 auto loop3 = Make();
2084
Austin Schuha9df9ad2021-06-16 14:49:39 -07002085 const FlatbufferDetachedBuffer<TestMessage> kMessage =
2086 JsonToFlatbuffer<TestMessage>("{}");
Austin Schuhad154822019-12-27 15:45:13 -08002087
2088 const aos::monotonic_clock::time_point monotonic_remote_time =
2089 aos::monotonic_clock::time_point(chrono::seconds(1501));
2090 const aos::realtime_clock::time_point realtime_remote_time =
2091 aos::realtime_clock::time_point(chrono::seconds(3132));
Austin Schuhb5c6f972021-03-14 21:53:07 -07002092 const uint32_t remote_queue_index = 0x254971;
Austin Schuha9012be2021-07-21 15:19:11 -07002093 const UUID source_boot_uuid = UUID::Random();
Austin Schuhad154822019-12-27 15:45:13 -08002094
2095 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08002096 loop1->MakeRawSender(configuration::GetChannel(
2097 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08002098
2099 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08002100 loop3->MakeRawFetcher(configuration::GetChannel(
2101 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08002102
2103 loop2->OnRun([&]() {
Austin Schuha9df9ad2021-06-16 14:49:39 -07002104 EXPECT_TRUE(sender->Send(kMessage.span().data(), kMessage.span().size(),
2105 monotonic_remote_time, realtime_remote_time,
Austin Schuha9012be2021-07-21 15:19:11 -07002106 remote_queue_index, source_boot_uuid));
Austin Schuhad154822019-12-27 15:45:13 -08002107 });
2108
2109 bool happened = false;
2110 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08002111 configuration::GetChannel(loop2->configuration(), "/test",
2112 "aos.TestMessage", "", nullptr),
Austin Schuha9012be2021-07-21 15:19:11 -07002113 [this, monotonic_remote_time, realtime_remote_time, source_boot_uuid,
Austin Schuhb5c6f972021-03-14 21:53:07 -07002114 remote_queue_index, &fetcher,
2115 &happened](const Context &context, const void * /*message*/) {
Austin Schuhad154822019-12-27 15:45:13 -08002116 happened = true;
2117 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
2118 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
Austin Schuha9012be2021-07-21 15:19:11 -07002119 EXPECT_EQ(source_boot_uuid, context.source_boot_uuid);
Austin Schuhb5c6f972021-03-14 21:53:07 -07002120 EXPECT_EQ(remote_queue_index, context.remote_queue_index);
Austin Schuhad154822019-12-27 15:45:13 -08002121
2122 ASSERT_TRUE(fetcher->Fetch());
2123 EXPECT_EQ(monotonic_remote_time,
2124 fetcher->context().monotonic_remote_time);
2125 EXPECT_EQ(realtime_remote_time,
2126 fetcher->context().realtime_remote_time);
2127
2128 this->Exit();
2129 });
2130
2131 EXPECT_FALSE(happened);
2132 Run();
2133 EXPECT_TRUE(happened);
2134}
2135
2136// Tests that a raw sender fills out sent data.
2137TEST_P(AbstractEventLoopTest, RawSenderSentData) {
2138 auto loop1 = MakePrimary();
2139
Austin Schuha9df9ad2021-06-16 14:49:39 -07002140 const FlatbufferDetachedBuffer<TestMessage> kMessage =
2141 JsonToFlatbuffer<TestMessage>("{}");
Austin Schuhad154822019-12-27 15:45:13 -08002142
2143 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08002144 loop1->MakeRawSender(configuration::GetChannel(
2145 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08002146
Tyler Chatow67ddb032020-01-12 14:30:04 -08002147 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
2148 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08002149
Austin Schuha9df9ad2021-06-16 14:49:39 -07002150 EXPECT_TRUE(sender->Send(kMessage.span().data(), kMessage.span().size()));
Austin Schuhad154822019-12-27 15:45:13 -08002151
2152 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
2153 EXPECT_LE(sender->monotonic_sent_time(),
2154 monotonic_now + chrono::milliseconds(100));
2155 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
2156 EXPECT_LE(sender->realtime_sent_time(),
2157 realtime_now + chrono::milliseconds(100));
2158 EXPECT_EQ(sender->sent_queue_index(), 0u);
2159
Austin Schuha9df9ad2021-06-16 14:49:39 -07002160 EXPECT_TRUE(sender->Send(kMessage.span().data(), kMessage.span().size()));
Austin Schuhad154822019-12-27 15:45:13 -08002161
2162 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
2163 EXPECT_LE(sender->monotonic_sent_time(),
2164 monotonic_now + chrono::milliseconds(100));
2165 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
2166 EXPECT_LE(sender->realtime_sent_time(),
2167 realtime_now + chrono::milliseconds(100));
2168 EXPECT_EQ(sender->sent_queue_index(), 1u);
2169}
2170
Austin Schuh217a9782019-12-21 23:02:50 -08002171// Tests that not setting up nodes results in no node.
2172TEST_P(AbstractEventLoopTest, NoNode) {
2173 auto loop1 = Make();
2174 auto loop2 = MakePrimary();
2175
2176 EXPECT_EQ(loop1->node(), nullptr);
2177 EXPECT_EQ(loop2->node(), nullptr);
2178}
2179
2180// Tests that setting up nodes results in node being set.
2181TEST_P(AbstractEventLoopTest, Node) {
2182 EnableNodes("me");
2183
2184 auto loop1 = Make();
2185 auto loop2 = MakePrimary();
2186
2187 EXPECT_NE(loop1->node(), nullptr);
2188 EXPECT_NE(loop2->node(), nullptr);
2189}
2190
2191// Tests that watchers work with a node setup.
2192TEST_P(AbstractEventLoopTest, NodeWatcher) {
2193 EnableNodes("me");
2194
2195 auto loop1 = Make();
2196 auto loop2 = Make();
2197 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08002198 loop2->MakeRawWatcher(
2199 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
2200 nullptr),
2201 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08002202}
2203
Brian Silverman454bc112020-03-05 14:21:25 -08002204// Tests that no-arg watchers work with a node setup.
2205TEST_P(AbstractEventLoopTest, NodeNoArgWatcher) {
2206 EnableNodes("me");
2207
2208 auto loop1 = Make();
2209 auto loop2 = Make();
2210 loop1->MakeWatcher("/test", [](const TestMessage &) {});
2211 loop2->MakeRawNoArgWatcher(
2212 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
2213 nullptr),
2214 [](const Context &) {});
2215}
2216
Austin Schuh217a9782019-12-21 23:02:50 -08002217// Tests that fetcher work with a node setup.
2218TEST_P(AbstractEventLoopTest, NodeFetcher) {
2219 EnableNodes("me");
2220 auto loop1 = Make();
2221
2222 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08002223 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
2224 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08002225}
2226
2227// Tests that sender work with a node setup.
2228TEST_P(AbstractEventLoopTest, NodeSender) {
2229 EnableNodes("me");
2230 auto loop1 = Make();
2231
2232 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
2233}
2234
Austin Schuhcc6070c2020-10-10 20:25:56 -07002235// Tests that a non-realtime event loop timer is marked non-realtime.
2236TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopTimer) {
2237 auto loop1 = MakePrimary();
2238
2239 // Add a timer to actually quit.
2240 auto test_timer = loop1->AddTimer([this]() {
2241 CheckNotRealtime();
2242 this->Exit();
2243 });
2244
2245 loop1->OnRun([&test_timer, &loop1]() {
2246 CheckNotRealtime();
2247 test_timer->Setup(loop1->monotonic_now(), ::std::chrono::milliseconds(100));
2248 });
2249
2250 Run();
2251}
2252
2253// Tests that a realtime event loop timer is marked realtime.
2254TEST_P(AbstractEventLoopTest, RealtimeEventLoopTimer) {
2255 auto loop1 = MakePrimary();
2256
2257 loop1->SetRuntimeRealtimePriority(1);
2258
2259 // Add a timer to actually quit.
2260 auto test_timer = loop1->AddTimer([this]() {
2261 CheckRealtime();
2262 this->Exit();
2263 });
2264
2265 loop1->OnRun([&test_timer, &loop1]() {
2266 CheckRealtime();
2267 test_timer->Setup(loop1->monotonic_now(), ::std::chrono::milliseconds(100));
2268 });
2269
2270 Run();
2271}
2272
2273// Tests that a non-realtime event loop phased loop is marked non-realtime.
2274TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopPhasedLoop) {
2275 auto loop1 = MakePrimary();
2276
2277 // Add a timer to actually quit.
2278 loop1->AddPhasedLoop(
2279 [this](int) {
2280 CheckNotRealtime();
2281 this->Exit();
2282 },
2283 chrono::seconds(1), chrono::seconds(0));
2284
2285 Run();
2286}
2287
2288// Tests that a realtime event loop phased loop is marked realtime.
2289TEST_P(AbstractEventLoopTest, RealtimeEventLoopPhasedLoop) {
2290 auto loop1 = MakePrimary();
2291
2292 loop1->SetRuntimeRealtimePriority(1);
2293
2294 // Add a timer to actually quit.
2295 loop1->AddPhasedLoop(
2296 [this](int) {
2297 CheckRealtime();
2298 this->Exit();
2299 },
2300 chrono::seconds(1), chrono::seconds(0));
2301
2302 Run();
2303}
2304
2305// Tests that a non-realtime event loop watcher is marked non-realtime.
2306TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopWatcher) {
2307 auto loop1 = MakePrimary();
2308 auto loop2 = Make();
2309
2310 aos::Sender<TestMessage> sender = loop2->MakeSender<TestMessage>("/test");
2311
2312 loop1->OnRun([&]() {
2313 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
2314 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
2315 ASSERT_TRUE(msg.Send(builder.Finish()));
2316 });
2317
2318 loop1->MakeWatcher("/test", [&](const TestMessage &) {
2319 CheckNotRealtime();
2320 this->Exit();
2321 });
2322
2323 Run();
2324}
2325
2326// Tests that a realtime event loop watcher is marked realtime.
2327TEST_P(AbstractEventLoopTest, RealtimeEventLoopWatcher) {
2328 auto loop1 = MakePrimary();
2329 auto loop2 = Make();
2330
2331 loop1->SetRuntimeRealtimePriority(1);
2332
2333 aos::Sender<TestMessage> sender = loop2->MakeSender<TestMessage>("/test");
2334
2335 loop1->OnRun([&]() {
2336 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
2337 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
2338 ASSERT_TRUE(msg.Send(builder.Finish()));
2339 });
2340
2341 loop1->MakeWatcher("/test", [&](const TestMessage &) {
2342 CheckRealtime();
2343 this->Exit();
2344 });
2345
2346 Run();
2347}
2348
Austin Schuha9012be2021-07-21 15:19:11 -07002349// Tests that event loop's context's monotonic time is set to a value on OnRun.
2350TEST_P(AbstractEventLoopTest, SetContextOnRun) {
2351 auto loop = MakePrimary();
2352
2353 // We want to check that monotonic event time is before monotonic now
2354 // called inside of callback, but after time point obtained callback.
2355 aos::monotonic_clock::time_point monotonic_event_time_on_run;
2356
2357 loop->OnRun([&]() {
2358 monotonic_event_time_on_run = loop->context().monotonic_event_time;
2359 EXPECT_LE(monotonic_event_time_on_run, loop->monotonic_now());
2360 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
2361 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
2362 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
2363 EXPECT_EQ(loop->context().source_boot_uuid, loop->boot_uuid());
2364 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
2365 EXPECT_EQ(loop->context().size, 0u);
2366 EXPECT_EQ(loop->context().data, nullptr);
2367 EXPECT_EQ(loop->context().buffer_index, -1);
2368 });
2369
2370 EndEventLoop(loop.get(), ::std::chrono::milliseconds(200));
2371
2372 const aos::monotonic_clock::time_point before_run_time =
2373 loop->monotonic_now();
2374 Run();
2375 EXPECT_GE(monotonic_event_time_on_run, before_run_time);
2376}
2377
Austin Schuh217a9782019-12-21 23:02:50 -08002378// Tests that watchers fail when created on the wrong node.
2379TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
2380 EnableNodes("them");
2381
2382 auto loop1 = Make();
2383 auto loop2 = Make();
2384 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
2385 "node");
2386 EXPECT_DEATH(
2387 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08002388 loop2->MakeRawWatcher(
2389 configuration::GetChannel(configuration(), "/test",
2390 "aos.TestMessage", "", nullptr),
2391 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08002392 },
2393 "node");
Brian Silverman454bc112020-03-05 14:21:25 -08002394 EXPECT_DEATH({ loop1->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
2395 "node");
2396 EXPECT_DEATH(
2397 {
2398 loop2->MakeRawNoArgWatcher(
2399 configuration::GetChannel(configuration(), "/test",
2400 "aos.TestMessage", "", nullptr),
2401 [](const Context &) {});
2402 },
2403 "node");
Austin Schuh217a9782019-12-21 23:02:50 -08002404}
2405
2406// Tests that fetchers fail when created on the wrong node.
2407TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
2408 EnableNodes("them");
2409 auto loop1 = Make();
2410
2411 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
2412 "node");
2413 EXPECT_DEATH(
2414 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08002415 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
2416 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08002417 },
2418 "node");
2419}
2420
2421// Tests that senders fail when created on the wrong node.
2422TEST_P(AbstractEventLoopDeathTest, NodeSender) {
2423 EnableNodes("them");
2424 auto loop1 = Make();
2425
2426 EXPECT_DEATH(
2427 {
2428 aos::Sender<TestMessage> sender =
2429 loop1->MakeSender<TestMessage>("/test");
2430 },
2431 "node");
2432
2433 // Note: Creating raw senders is always supported. Right now, this lets us
2434 // use them to create message_gateway.
2435}
2436
Brian Silverman341b57e2020-06-23 16:23:18 -07002437// Tests creating multiple Builders from a single Sender at the same time.
2438TEST_P(AbstractEventLoopDeathTest, MultipleBuilders) {
2439 auto loop1 = Make();
2440 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
2441
2442 { auto builder = sender.MakeBuilder(); }
2443 {
2444 auto builder = sender.MakeBuilder();
2445 builder.MakeBuilder<TestMessage>().Finish();
2446 }
2447 {
2448 // Creating this after the first one was destroyed should be fine.
2449 auto builder = sender.MakeBuilder();
2450 builder.MakeBuilder<TestMessage>().Finish();
2451 // But not a second one.
2452 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2453 "May not overwrite in-use allocator");
2454 }
2455
2456 FlatbufferDetachedBuffer<TestMessage> detached =
2457 flatbuffers::DetachedBuffer();
2458 {
2459 auto builder = sender.MakeBuilder();
2460 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2461 }
2462 {
2463 // This is the second one, after the detached one, so it should fail.
2464 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2465 "May not overwrite in-use allocator");
2466 }
2467
2468 // Clear the detached one, and then we should be able to create another.
2469 detached = flatbuffers::DetachedBuffer();
2470 {
2471 auto builder = sender.MakeBuilder();
2472 builder.MakeBuilder<TestMessage>().Finish();
2473 }
2474
2475 // And then detach another one.
2476 {
2477 auto builder = sender.MakeBuilder();
2478 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2479 }
2480}
2481
2482// Tests sending a buffer detached from a different builder.
2483TEST_P(AbstractEventLoopDeathTest, WrongDetachedBuffer) {
2484 auto loop1 = Make();
2485 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
2486 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
2487
2488 auto builder = sender1.MakeBuilder();
2489 FlatbufferDetachedBuffer<TestMessage> detached =
2490 builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2491 EXPECT_DEATH(sender2.SendDetached(std::move(detached)),
2492 "May only send the buffer detached from this Sender");
2493}
2494
Parker Schuhe4a70d62017-12-27 20:10:20 -08002495} // namespace testing
2496} // namespace aos