blob: e0c6024e928308c9706b7b1e673e4ef5d957139f [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 Schuh39788ff2019-12-01 18:22:57 -0800277 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
278 EXPECT_EQ(fetcher.context().size, 0u);
279 EXPECT_EQ(fetcher.context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700280 EXPECT_EQ(fetcher.context().buffer_index, -1);
Austin Schuhbbce72d2019-05-26 15:11:46 -0700281
Alex Perrycb7da4b2019-08-28 19:35:56 -0700282 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
283 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
284 builder.add_value(200);
285 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700286
287 EXPECT_TRUE(fetcher.Fetch());
288 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700289 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -0800290
291 const chrono::milliseconds kEpsilon(100);
292
Austin Schuhad154822019-12-27 15:45:13 -0800293 const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
294 const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
295 EXPECT_EQ(fetcher.context().monotonic_event_time,
296 fetcher.context().monotonic_remote_time);
297 EXPECT_EQ(fetcher.context().realtime_event_time,
298 fetcher.context().realtime_remote_time);
299
300 EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
301 EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
302 EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
303 EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800304 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
305 EXPECT_EQ(fetcher.context().size, 20u);
306 EXPECT_NE(fetcher.context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700307 if (read_method() == ReadMethod::PIN) {
308 EXPECT_GE(fetcher.context().buffer_index, 0);
309 EXPECT_LT(fetcher.context().buffer_index,
310 loop2->NumberBuffers(fetcher.channel()));
311 } else {
312 EXPECT_EQ(fetcher.context().buffer_index, -1);
313 }
Parker Schuhe4a70d62017-12-27 20:10:20 -0800314}
315
Austin Schuh3578a2e2019-05-25 18:17:59 -0700316// Tests that watcher will receive all messages sent if they are sent after
317// initialization and before running.
318TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
319 auto loop1 = Make();
320 auto loop2 = MakePrimary();
321
322 auto sender = loop1->MakeSender<TestMessage>("/test");
323
324 ::std::vector<int> values;
325
326 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700327 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700328 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700329 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700330 }
331 });
332
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700333 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -0700334 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700335 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
336 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
337 builder.add_value(199);
338 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700339 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700340
341 loop2->OnRun([&]() {
342 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700343 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
344 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
345 builder.add_value(200);
346 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700347 }
348 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700349 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
350 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
351 builder.add_value(201);
352 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700353 }
354 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700355
356 Run();
357
358 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
359}
360
361// Tests that watcher will not receive messages sent before the watcher is
362// created.
363TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
364 auto loop1 = Make();
365 auto loop2 = MakePrimary();
366
367 auto sender = loop1->MakeSender<TestMessage>("/test");
368
369 ::std::vector<int> values;
370
371 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700372 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
373 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
374 builder.add_value(200);
375 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700376 }
377 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700378 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
379 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
380 builder.add_value(201);
381 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700382 }
383
384 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700385 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700386 });
387
388 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700389 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700390 loop2->OnRun([&test_timer, &loop2]() {
391 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
392 });
393
394 Run();
395 EXPECT_EQ(0, values.size());
396}
397
Austin Schuhbbce72d2019-05-26 15:11:46 -0700398// Tests that FetchNext gets all the messages sent after it is constructed.
399TEST_P(AbstractEventLoopTest, FetchNext) {
400 auto loop1 = Make();
401 auto loop2 = MakePrimary();
402
403 auto sender = loop1->MakeSender<TestMessage>("/test");
404 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
405
406 ::std::vector<int> values;
407
408 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700409 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
410 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
411 builder.add_value(200);
412 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700413 }
414 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700415 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
416 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
417 builder.add_value(201);
418 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700419 }
420
421 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700422 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700423 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700424 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700425 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700426 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700427 });
428
429 loop2->OnRun([&test_timer, &loop2]() {
430 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
431 });
432
433 Run();
434 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
435}
436
437// Tests that FetchNext gets no messages sent before it is constructed.
438TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
439 auto loop1 = Make();
440 auto loop2 = MakePrimary();
441
442 auto sender = loop1->MakeSender<TestMessage>("/test");
443
444 ::std::vector<int> values;
445
446 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700447 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
448 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
449 builder.add_value(200);
450 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700451 }
452 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700453 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
454 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
455 builder.add_value(201);
456 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700457 }
458
459 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
460
461 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700462 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700463 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700464 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700465 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700466 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700467 });
468
469 loop2->OnRun([&test_timer, &loop2]() {
470 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
471 });
472
473 Run();
474 EXPECT_THAT(0, values.size());
475}
476
477// Tests that Fetch returns the last message created before the loop was
478// started.
479TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
480 auto loop1 = Make();
481 auto loop2 = MakePrimary();
482
483 auto sender = loop1->MakeSender<TestMessage>("/test");
484
485 ::std::vector<int> values;
486
487 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700488 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
489 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
490 builder.add_value(200);
491 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700492 }
493 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700494 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
495 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
496 builder.add_value(201);
497 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700498 }
499
500 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
501
502 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700503 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700504 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700505 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700506 }
507 // Do it again to make sure we don't double fetch.
508 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700509 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700510 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700511 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700512 });
513
514 loop2->OnRun([&test_timer, &loop2]() {
515 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
516 });
517
518 Run();
519 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
520}
521
522// Tests that Fetch and FetchNext interleave as expected.
523TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
524 auto loop1 = Make();
525 auto loop2 = MakePrimary();
526
527 auto sender = loop1->MakeSender<TestMessage>("/test");
528
529 ::std::vector<int> values;
530
531 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700532 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
533 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
534 builder.add_value(200);
535 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700536 }
537 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700538 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
539 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
540 builder.add_value(201);
541 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700542 }
543
544 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
545
546 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700547 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700548 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700549 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700550 }
551
552 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700553 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
554 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
555 builder.add_value(202);
556 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700557 }
558 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700559 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
560 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
561 builder.add_value(203);
562 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700563 }
564 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700565 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
566 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
567 builder.add_value(204);
568 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700569 }
570
571 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700572 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700573 }
574
575 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700576 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700577 }
578
Austin Schuh9fe68f72019-08-10 19:32:03 -0700579 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700580 });
581
582 loop2->OnRun([&test_timer, &loop2]() {
583 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
584 });
585
586 Run();
587 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
588}
589
Austin Schuh3115a202019-05-27 21:02:14 -0700590// Tests that FetchNext behaves correctly when we get two messages in the queue
591// but don't consume the first until after the second has been sent.
592TEST_P(AbstractEventLoopTest, FetchNextTest) {
Austin Schuh3115a202019-05-27 21:02:14 -0700593 auto send_loop = Make();
594 auto fetch_loop = Make();
595 auto sender = send_loop->MakeSender<TestMessage>("/test");
596 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
597
598 {
Tyler Chatow67ddb032020-01-12 14:30:04 -0800599 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
600 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
601 builder.add_value(100);
602 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700603 }
604
605 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700606 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
607 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
608 builder.add_value(200);
609 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700610 }
611
612 ASSERT_TRUE(fetcher.FetchNext());
613 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700614 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700615
616 ASSERT_TRUE(fetcher.FetchNext());
617 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700618 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700619
620 // When we run off the end of the queue, expect to still have the old message:
621 ASSERT_FALSE(fetcher.FetchNext());
622 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700623 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700624}
625
Brian Silverman77162972020-08-12 19:52:40 -0700626// Verify that a fetcher still holds its data, even after falling behind.
627TEST_P(AbstractEventLoopTest, FetcherBehindData) {
628 auto send_loop = Make();
629 auto fetch_loop = Make();
630 auto sender = send_loop->MakeSender<TestMessage>("/test");
631 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
632 {
633 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
634 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
635 builder.add_value(1);
636 ASSERT_TRUE(msg.Send(builder.Finish()));
637 }
638 ASSERT_TRUE(fetcher.Fetch());
639 EXPECT_EQ(1, fetcher.get()->value());
640 for (int i = 0; i < 300; ++i) {
641 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
642 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
643 builder.add_value(i + 2);
644 ASSERT_TRUE(msg.Send(builder.Finish()));
645 }
646 EXPECT_EQ(1, fetcher.get()->value());
647}
648
649// Try a bunch of orderings of operations with fetchers and senders. Verify that
650// all the fetchers have the correct data at each step.
651TEST_P(AbstractEventLoopTest, FetcherPermutations) {
652 for (int max_save = 0; max_save < 5; ++max_save) {
653 SCOPED_TRACE("max_save=" + std::to_string(max_save));
654
655 auto send_loop = Make();
656 auto fetch_loop = Make();
657 auto sender = send_loop->MakeSender<TestMessage>("/test");
658 const auto send_message = [&sender](int i) {
659 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
660 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
661 builder.add_value(i);
662 ASSERT_TRUE(msg.Send(builder.Finish()));
663 };
664 std::vector<Fetcher<TestMessage>> fetchers;
665 for (int i = 0; i < 10; ++i) {
666 fetchers.emplace_back(fetch_loop->MakeFetcher<TestMessage>("/test"));
667 }
668 send_message(1);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700669 const auto verify_buffers = [&]() {
670 std::vector<std::reference_wrapper<const Fetcher<TestMessage>>>
671 fetchers_copy;
672 for (const auto &fetcher : fetchers) {
673 fetchers_copy.emplace_back(fetcher);
674 }
675 std::vector<std::reference_wrapper<const Sender<TestMessage>>>
676 senders_copy;
677 senders_copy.emplace_back(sender);
678 VerifyBuffers(send_loop->NumberBuffers(sender.channel()), fetchers_copy,
679 senders_copy);
680 };
Brian Silverman77162972020-08-12 19:52:40 -0700681 for (auto &fetcher : fetchers) {
682 ASSERT_TRUE(fetcher.Fetch());
Brian Silverman4f4e0612020-08-12 19:54:41 -0700683 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700684 EXPECT_EQ(1, fetcher.get()->value());
685 }
686
687 for (int save = 1; save <= max_save; ++save) {
688 SCOPED_TRACE("save=" + std::to_string(save));
689 send_message(100 + save);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700690 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700691 for (size_t i = 0; i < fetchers.size() - save; ++i) {
692 SCOPED_TRACE("fetcher=" + std::to_string(i));
693 ASSERT_TRUE(fetchers[i].Fetch());
Brian Silverman4f4e0612020-08-12 19:54:41 -0700694 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700695 EXPECT_EQ(100 + save, fetchers[i].get()->value());
696 }
697 for (size_t i = fetchers.size() - save; i < fetchers.size() - 1; ++i) {
698 SCOPED_TRACE("fetcher=" + std::to_string(i));
699 EXPECT_EQ(100 + (fetchers.size() - 1 - i), fetchers[i].get()->value());
700 }
701 EXPECT_EQ(1, fetchers.back().get()->value());
702 }
703
704 for (int i = 0; i < 300; ++i) {
705 send_message(200 + i);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700706 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700707 }
708
709 for (size_t i = 0; i < fetchers.size() - max_save; ++i) {
710 SCOPED_TRACE("fetcher=" + std::to_string(i));
711 if (max_save > 0) {
712 EXPECT_EQ(100 + max_save, fetchers[i].get()->value());
713 } else {
714 EXPECT_EQ(1, fetchers[i].get()->value());
715 }
716 }
717 for (size_t i = fetchers.size() - max_save; i < fetchers.size() - 1; ++i) {
718 SCOPED_TRACE("fetcher=" + std::to_string(i));
719 EXPECT_EQ(100 + (fetchers.size() - 1 - i), fetchers[i].get()->value());
720 }
721 EXPECT_EQ(1, fetchers.back().get()->value());
722 }
723}
724
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800725// Verify that making a fetcher and watcher for "/test" succeeds.
726TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800727 auto loop = Make();
728 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800729 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800730}
731
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800732// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800733TEST_P(AbstractEventLoopTest, TwoFetcher) {
734 auto loop = Make();
735 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800736 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800737}
738
Alex Perrycb7da4b2019-08-28 19:35:56 -0700739// Verify that registering a watcher for an invalid channel name dies.
740TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
741 auto loop = Make();
742 EXPECT_DEATH(
743 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
744 "/test/invalid");
Brian Silverman454bc112020-03-05 14:21:25 -0800745 EXPECT_DEATH(
746 { loop->MakeNoArgWatcher<TestMessage>("/test/invalid", [&]() {}); },
747 "/test/invalid");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700748}
749
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800750// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700751TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800752 auto loop = Make();
753 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800754 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
755 "/test");
Brian Silverman454bc112020-03-05 14:21:25 -0800756 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
757}
758
759// Verify that registering a no-arg watcher twice for "/test" fails.
760TEST_P(AbstractEventLoopDeathTest, TwoNoArgWatcher) {
761 auto loop = Make();
762 loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {});
763 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
764 "/test");
765 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800766}
767
Austin Schuh3115a202019-05-27 21:02:14 -0700768// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700769TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700770 auto loop = MakePrimary();
771 // Confirm that runtime priority calls work when not realtime.
772 loop->SetRuntimeRealtimePriority(5);
773
774 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
775
776 EXPECT_DEATH(Run(), "realtime");
777}
778
Brian Silverman6a54ff32020-04-28 16:41:39 -0700779// Verify that SetRuntimeAffinity fails while running.
780TEST_P(AbstractEventLoopDeathTest, SetRuntimeAffinity) {
781 auto loop = MakePrimary();
782 // Confirm that runtime priority calls work when not running.
783 loop->SetRuntimeAffinity(MakeCpusetFromCpus({0}));
784
785 loop->OnRun([&]() { loop->SetRuntimeAffinity(MakeCpusetFromCpus({1})); });
786
787 EXPECT_DEATH(Run(), "Cannot set affinity while running");
788}
789
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800790// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700791TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800792 auto loop = Make();
793 auto sender = loop->MakeSender<TestMessage>("/test");
794 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
795 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800796}
797
Austin Schuhe516ab02020-05-06 21:37:04 -0700798// Verify that creating too many senders fails.
799TEST_P(AbstractEventLoopDeathTest, TooManySenders) {
800 auto loop = Make();
801 std::vector<aos::Sender<TestMessage>> senders;
802 for (int i = 0; i < 10; ++i) {
803 senders.emplace_back(loop->MakeSender<TestMessage>("/test"));
804 }
805 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); },
806 "Failed to create sender on \\{ \"name\": \"/test\", \"type\": "
Brian Silverman77162972020-08-12 19:52:40 -0700807 "\"aos.TestMessage\"[^}]*\\ }, too many senders.");
808}
809
810// Verify that creating too many fetchers fails.
811TEST_P(AbstractEventLoopDeathTest, TooManyFetchers) {
812 if (read_method() != ReadMethod::PIN) {
813 // Other read methods don't limit the number of readers, so just skip this.
814 return;
815 }
816
817 auto loop = Make();
818 std::vector<aos::Fetcher<TestMessage>> fetchers;
819 for (int i = 0; i < 10; ++i) {
820 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
821 }
822 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
823 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
824 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
825}
826
827// Verify that creating too many fetchers, split between two event loops, fails.
828TEST_P(AbstractEventLoopDeathTest, TooManyFetchersTwoLoops) {
829 if (read_method() != ReadMethod::PIN) {
830 // Other read methods don't limit the number of readers, so just skip this.
831 return;
832 }
833
834 auto loop = Make();
835 auto loop2 = Make();
836 std::vector<aos::Fetcher<TestMessage>> fetchers;
837 for (int i = 0; i < 5; ++i) {
838 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
839 fetchers.emplace_back(loop2->MakeFetcher<TestMessage>("/test"));
840 }
841 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
842 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
843 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
844}
845
846// Verify that creating too many watchers fails.
847TEST_P(AbstractEventLoopDeathTest, TooManyWatchers) {
848 if (read_method() != ReadMethod::PIN) {
849 // Other read methods don't limit the number of readers, so just skip this.
850 return;
851 }
852
853 std::vector<std::unique_ptr<EventLoop>> loops;
854 for (int i = 0; i < 10; ++i) {
855 loops.emplace_back(Make());
856 loops.back()->MakeWatcher("/test", [](const TestMessage &) {});
857 }
858 EXPECT_DEATH({ Make()->MakeWatcher("/test", [](const TestMessage &) {}); },
859 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
860 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
861}
862
863// Verify that creating too many watchers and fetchers combined fails.
864TEST_P(AbstractEventLoopDeathTest, TooManyWatchersAndFetchers) {
865 if (read_method() != ReadMethod::PIN) {
866 // Other read methods don't limit the number of readers, so just skip this.
867 return;
868 }
869
870 auto loop = Make();
871 std::vector<aos::Fetcher<TestMessage>> fetchers;
872 std::vector<std::unique_ptr<EventLoop>> loops;
873 for (int i = 0; i < 5; ++i) {
874 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
875 loops.emplace_back(Make());
876 loops.back()->MakeWatcher("/test", [](const TestMessage &) {});
877 }
878 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
879 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
880 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
Austin Schuhe516ab02020-05-06 21:37:04 -0700881}
882
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700883// Verify that we can't create a sender inside OnRun.
884TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
885 auto loop1 = MakePrimary();
886
887 loop1->OnRun(
888 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
889
890 EXPECT_DEATH(Run(), "running");
891}
892
893// Verify that we can't create a watcher inside OnRun.
894TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
895 auto loop1 = MakePrimary();
896
897 loop1->OnRun(
898 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
899
900 EXPECT_DEATH(Run(), "running");
901}
902
Brian Silverman454bc112020-03-05 14:21:25 -0800903// Verify that we can't create a no-arg watcher inside OnRun.
904TEST_P(AbstractEventLoopDeathTest, NoArgWatcherInOnRun) {
905 auto loop1 = MakePrimary();
906
907 loop1->OnRun(
908 [&]() { loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {}); });
909
910 EXPECT_DEATH(Run(), "running");
911}
912
Parker Schuhe4a70d62017-12-27 20:10:20 -0800913// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800914TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
915 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700916 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800917
Austin Schuh3578a2e2019-05-25 18:17:59 -0700918 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
919 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700920 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700921 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700922 });
923
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800924 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700925
926 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700927 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
928 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
929 builder.add_value(200);
930 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700931 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800932
Austin Schuh44019f92019-05-19 19:58:27 -0700933 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800934}
935
Neil Balch229001a2018-01-07 18:22:52 -0800936// Verify that timer intervals and duration function properly.
937TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800938 // Force a slower rate so we are guarenteed to have reports for our timer.
939 FLAGS_timing_report_ms = 2000;
940
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800941 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800942
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800943 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800944 auto loop2 = Make();
945
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800946 ::std::vector<::aos::monotonic_clock::time_point> times;
947 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
948
Austin Schuh39788ff2019-12-01 18:22:57 -0800949 Fetcher<timing::Report> report_fetcher =
950 loop2->MakeFetcher<timing::Report>("/aos");
951 EXPECT_FALSE(report_fetcher.Fetch());
952
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800953 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
954 times.push_back(loop->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800955 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
956 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
957 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800958 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
959 EXPECT_EQ(loop->context().size, 0u);
960 EXPECT_EQ(loop->context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700961 EXPECT_EQ(loop->context().buffer_index, -1);
Austin Schuh39788ff2019-12-01 18:22:57 -0800962
Austin Schuhad154822019-12-27 15:45:13 -0800963 expected_times.push_back(loop->context().monotonic_event_time);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800964 if (times.size() == kCount) {
965 this->Exit();
966 }
Neil Balch229001a2018-01-07 18:22:52 -0800967 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800968 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800969
Austin Schuh39788ff2019-12-01 18:22:57 -0800970 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700971 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800972 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
973
Austin Schuh44019f92019-05-19 19:58:27 -0700974 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800975
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800976 // Confirm that we got both the right number of samples, and it's odd.
977 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
978 EXPECT_EQ(times.size(), expected_times.size());
979 EXPECT_EQ((times.size() % 2), 1);
980
981 // Grab the middle sample.
982 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
983
984 // Add up all the delays of all the times.
985 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
986 for (const ::aos::monotonic_clock::time_point time : times) {
987 sum += time - average_time;
988 }
989
990 // Average and add to the middle to find the average time.
991 sum /= times.size();
992 average_time += sum;
993
994 // Compute the offset from the average and the expected average. It
995 // should be pretty close to 0.
996 const ::aos::monotonic_clock::duration remainder =
997 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
998
999 const chrono::milliseconds kEpsilon(100);
1000 EXPECT_LT(remainder, +kEpsilon);
1001 EXPECT_GT(remainder, -kEpsilon);
1002
1003 // Make sure that the average duration is close to 1 second.
1004 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1005 times.front())
1006 .count() /
1007 static_cast<double>(times.size() - 1),
1008 1.0, 0.1);
1009
1010 // Confirm that the ideal wakeup times increment correctly.
1011 for (size_t i = 1; i < expected_times.size(); ++i) {
1012 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1013 }
1014
1015 for (size_t i = 0; i < expected_times.size(); ++i) {
1016 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
1017 chrono::seconds(0));
1018 }
1019
1020 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1021 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001022
Austin Schuh6bae8252021-02-07 22:01:49 -08001023 if (do_timing_reports() == DoTimingReports::kYes) {
1024 // And, since we are here, check that the timing report makes sense.
1025 // Start by looking for our event loop's timing.
1026 FlatbufferDetachedBuffer<timing::Report> report =
1027 FlatbufferDetachedBuffer<timing::Report>::Empty();
1028 while (report_fetcher.FetchNext()) {
1029 if (report_fetcher->name()->string_view() == "primary") {
1030 report = CopyFlatBuffer(report_fetcher.get());
1031 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001032 }
Austin Schuh6bae8252021-02-07 22:01:49 -08001033
1034 // Confirm that we have the right number of reports, and the contents are
1035 // sane.
1036 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
1037
1038 EXPECT_EQ(report.message().name()->string_view(), "primary");
1039
1040 ASSERT_NE(report.message().senders(), nullptr);
1041 EXPECT_EQ(report.message().senders()->size(), 2);
1042
1043 ASSERT_NE(report.message().timers(), nullptr);
1044 EXPECT_EQ(report.message().timers()->size(), 2);
1045
1046 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
1047 "Test loop");
1048 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
1049
1050 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
1051 "timing_reports");
1052 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
1053
1054 // Make sure there is a single phased loop report with our report in it.
1055 ASSERT_EQ(report.message().phased_loops(), nullptr);
1056 } else {
1057 ASSERT_FALSE(report_fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -08001058 }
Neil Balch229001a2018-01-07 18:22:52 -08001059}
1060
1061// Verify that we can change a timer's parameters during execution.
1062TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -07001063 auto loop = MakePrimary();
Austin Schuh7f20f512021-01-31 17:56:16 -08001064 std::vector<monotonic_clock::time_point> iteration_list;
Neil Balch229001a2018-01-07 18:22:52 -08001065
1066 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
Austin Schuh7f20f512021-01-31 17:56:16 -08001067 iteration_list.push_back(loop->context().monotonic_event_time);
Neil Balch229001a2018-01-07 18:22:52 -08001068 });
1069
Austin Schuh7f20f512021-01-31 17:56:16 -08001070 monotonic_clock::time_point s;
1071 auto modifier_timer = loop->AddTimer([&test_timer, &s]() {
1072 test_timer->Setup(s + chrono::milliseconds(45), chrono::milliseconds(30));
Neil Balch229001a2018-01-07 18:22:52 -08001073 });
1074
Austin Schuh7f20f512021-01-31 17:56:16 -08001075 s = loop->monotonic_now();
1076 test_timer->Setup(s, chrono::milliseconds(20));
1077 modifier_timer->Setup(s + chrono::milliseconds(45));
1078 EndEventLoop(loop.get(), chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -07001079 Run();
Neil Balch229001a2018-01-07 18:22:52 -08001080
1081 EXPECT_EQ(iteration_list.size(), 7);
Austin Schuh7f20f512021-01-31 17:56:16 -08001082 EXPECT_EQ(iteration_list[0], s);
1083 EXPECT_EQ(iteration_list[1], s + chrono::milliseconds(20));
1084 EXPECT_EQ(iteration_list[2], s + chrono::milliseconds(40));
1085 EXPECT_EQ(iteration_list[3], s + chrono::milliseconds(45));
1086 EXPECT_EQ(iteration_list[4], s + chrono::milliseconds(75));
1087 EXPECT_EQ(iteration_list[5], s + chrono::milliseconds(105));
1088 EXPECT_EQ(iteration_list[6], s + chrono::milliseconds(135));
Neil Balch229001a2018-01-07 18:22:52 -08001089}
1090
1091// Verify that we can disable a timer during execution.
1092TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -07001093 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -08001094 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
1095
1096 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
1097 iteration_list.push_back(loop->monotonic_now());
1098 });
1099
Tyler Chatow67ddb032020-01-12 14:30:04 -08001100 auto ender_timer = loop->AddTimer([&test_timer]() { test_timer->Disable(); });
Neil Balch229001a2018-01-07 18:22:52 -08001101
1102 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
Tyler Chatow67ddb032020-01-12 14:30:04 -08001103 ender_timer->Setup(loop->monotonic_now() + ::std::chrono::milliseconds(45));
Neil Balch229001a2018-01-07 18:22:52 -08001104 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -07001105 Run();
Neil Balch229001a2018-01-07 18:22:52 -08001106
1107 EXPECT_EQ(iteration_list.size(), 3);
1108}
Austin Schuh7267c532019-05-19 19:55:53 -07001109
Brian Silvermanaf9a4d82020-10-06 15:10:58 -07001110// Verify that a timer can disable itself.
1111//
1112// TODO(Brian): Do something similar with phased loops, both with a quick
1113// handler and a handler that would miss a cycle except it got deferred. Current
1114// behavior doing that is a mess.
1115TEST_P(AbstractEventLoopTest, TimerDisableSelf) {
1116 auto loop = MakePrimary();
1117
1118 int count = 0;
1119 aos::TimerHandler *test_timer;
1120 test_timer = loop->AddTimer([&count, &test_timer]() {
1121 ++count;
1122 test_timer->Disable();
1123 });
1124
1125 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
1126 EndEventLoop(loop.get(), ::std::chrono::milliseconds(80));
1127 Run();
1128
1129 EXPECT_EQ(count, 1);
1130}
1131
Brian Silvermanbd405c02020-06-23 16:25:23 -07001132// Verify that we can disable a timer during execution of another timer
1133// scheduled for the same time, with one ordering of creation for the timers.
1134//
1135// Also schedule some more events to reshuffle the heap in EventLoop used for
1136// tracking events to change up the order. This used to segfault
1137// SimulatedEventLoop.
1138TEST_P(AbstractEventLoopTest, TimerDisableOther) {
1139 for (bool creation_order : {true, false}) {
1140 for (bool setup_order : {true, false}) {
1141 for (int shuffle_events = 0; shuffle_events < 5; ++shuffle_events) {
1142 auto loop = MakePrimary();
1143 aos::TimerHandler *test_timer, *ender_timer;
1144 if (creation_order) {
1145 test_timer = loop->AddTimer([]() {});
1146 ender_timer =
1147 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1148 } else {
1149 ender_timer =
1150 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1151 test_timer = loop->AddTimer([]() {});
1152 }
1153
1154 const auto start = loop->monotonic_now();
1155
1156 for (int i = 0; i < shuffle_events; ++i) {
1157 loop->AddTimer([]() {})->Setup(start + std::chrono::milliseconds(10));
1158 }
1159
1160 if (setup_order) {
1161 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1162 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1163 } else {
1164 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1165 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1166 }
1167 EndEventLoop(loop.get(), ::std::chrono::milliseconds(40));
1168 Run();
1169 }
1170 }
1171 }
1172}
1173
Austin Schuh54cf95f2019-11-29 13:14:18 -08001174// Verifies that the event loop implementations detect when Channel is not a
1175// pointer into confguration()
1176TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
1177 auto loop = MakePrimary();
1178
Tyler Chatow67ddb032020-01-12 14:30:04 -08001179 const Channel *channel = configuration::GetChannel(
1180 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
Austin Schuh54cf95f2019-11-29 13:14:18 -08001181
1182 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
1183
1184 EXPECT_DEATH(
1185 { loop->MakeRawSender(&channel_copy.message()); },
1186 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1187
1188 EXPECT_DEATH(
1189 { loop->MakeRawFetcher(&channel_copy.message()); },
1190 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1191
1192 EXPECT_DEATH(
1193 {
1194 loop->MakeRawWatcher(&channel_copy.message(),
1195 [](const Context, const void *) {});
1196 },
1197 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1198}
1199
Austin Schuhd54780b2020-10-03 16:26:02 -07001200// Verifies that the event loop implementations detect when Channel has an
1201// invalid alignment.
1202TEST_P(AbstractEventLoopDeathTest, InvalidChannelAlignment) {
1203 const char *const kError = "multiple of alignment";
1204 InvalidChannelAlignment();
1205
1206 auto loop = MakePrimary();
1207
1208 const Channel *channel = configuration::GetChannel(
1209 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
1210
1211 EXPECT_DEATH({ loop->MakeRawSender(channel); }, kError);
1212 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); }, kError);
1213
1214 EXPECT_DEATH({ loop->MakeRawFetcher(channel); }, kError);
1215 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); }, kError);
1216
1217 EXPECT_DEATH(
1218 { loop->MakeRawWatcher(channel, [](const Context &, const void *) {}); },
1219 kError);
1220 EXPECT_DEATH({ loop->MakeRawNoArgWatcher(channel, [](const Context &) {}); },
1221 kError);
1222
1223 EXPECT_DEATH({ loop->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1224 kError);
1225 EXPECT_DEATH({ loop->MakeWatcher("/test", [](const TestMessage &) {}); },
1226 kError);
1227}
1228
Brian Silverman454bc112020-03-05 14:21:25 -08001229// Verify that the send time on a message is roughly right when using a watcher.
Austin Schuh7267c532019-05-19 19:55:53 -07001230TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -07001231 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -07001232 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -08001233 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -07001234 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
1235
1236 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -07001237 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1238 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1239 builder.add_value(200);
1240 ASSERT_TRUE(msg.Send(builder.Finish()));
1241 });
1242
Austin Schuhad154822019-12-27 15:45:13 -08001243 bool triggered = false;
Brian Silverman454bc112020-03-05 14:21:25 -08001244 loop1->MakeWatcher("/test", [&](const TestMessage &msg) {
Austin Schuhad154822019-12-27 15:45:13 -08001245 // Confirm that the data pointer makes sense from a watcher, and all the
1246 // timestamps look right.
1247 EXPECT_GT(&msg, loop1->context().data);
1248 EXPECT_EQ(loop1->context().monotonic_remote_time,
1249 loop1->context().monotonic_event_time);
1250 EXPECT_EQ(loop1->context().realtime_remote_time,
1251 loop1->context().realtime_event_time);
1252
1253 const aos::monotonic_clock::time_point monotonic_now =
1254 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -08001255 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001256
1257 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1258 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1259 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1260 monotonic_now);
1261 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1262 realtime_now);
1263
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001264 EXPECT_LT(&msg, reinterpret_cast<const void *>(
1265 reinterpret_cast<const char *>(loop1->context().data) +
Austin Schuhad154822019-12-27 15:45:13 -08001266 loop1->context().size));
Brian Silverman4f4e0612020-08-12 19:54:41 -07001267 if (read_method() == ReadMethod::PIN) {
1268 EXPECT_GE(loop1->context().buffer_index, 0);
1269 EXPECT_LT(loop1->context().buffer_index,
1270 loop1->NumberBuffers(
1271 configuration::GetChannel(loop1->configuration(), "/test",
1272 "aos.TestMessage", "", nullptr)));
1273 } else {
1274 EXPECT_EQ(-1, loop1->context().buffer_index);
1275 }
Austin Schuhad154822019-12-27 15:45:13 -08001276 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -07001277 });
1278
1279 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1280
1281 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -07001282 Run();
Austin Schuh7267c532019-05-19 19:55:53 -07001283
Austin Schuhad154822019-12-27 15:45:13 -08001284 EXPECT_TRUE(triggered);
1285
Brian Silverman454bc112020-03-05 14:21:25 -08001286 ASSERT_TRUE(fetcher.Fetch());
1287
1288 monotonic_clock::duration monotonic_time_offset =
1289 fetcher.context().monotonic_event_time -
1290 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1291 realtime_clock::duration realtime_time_offset =
1292 fetcher.context().realtime_event_time -
1293 (loop1->realtime_now() - ::std::chrono::seconds(1));
1294
1295 EXPECT_EQ(fetcher.context().realtime_event_time,
1296 fetcher.context().realtime_remote_time);
1297 EXPECT_EQ(fetcher.context().monotonic_event_time,
1298 fetcher.context().monotonic_remote_time);
1299
1300 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1301 << ": Got "
1302 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1303 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1304 // Confirm that the data pointer makes sense.
1305 EXPECT_GT(fetcher.get(), fetcher.context().data);
1306 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001307 reinterpret_cast<const void *>(
1308 reinterpret_cast<const char *>(fetcher.context().data) +
Brian Silverman454bc112020-03-05 14:21:25 -08001309 fetcher.context().size));
1310 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1311 << ": Got "
1312 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1313 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1314
1315 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1316 << ": Got "
1317 << fetcher.context().realtime_event_time.time_since_epoch().count()
1318 << " expected " << loop1->realtime_now().time_since_epoch().count();
1319 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1320 << ": Got "
1321 << fetcher.context().realtime_event_time.time_since_epoch().count()
1322 << " expected " << loop1->realtime_now().time_since_epoch().count();
1323}
1324
1325// Verify that the send time on a message is roughly right when using a no-arg
1326// watcher. To get a message, we need to use a fetcher to actually access the
1327// message. This is also the main use case for no-arg fetchers.
1328TEST_P(AbstractEventLoopTest, MessageSendTimeNoArg) {
1329 auto loop1 = MakePrimary();
1330 auto loop2 = Make();
1331 auto sender = loop2->MakeSender<TestMessage>("/test");
1332 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1333
1334 auto test_timer = loop1->AddTimer([&sender]() {
1335 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1336 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1337 builder.add_value(200);
1338 ASSERT_TRUE(msg.Send(builder.Finish()));
1339 });
1340
1341 bool triggered = false;
1342 loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {
1343 // Confirm that we can indeed use a fetcher on this channel from this
1344 // context, and it results in a sane data pointer and timestamps.
1345 ASSERT_TRUE(fetcher.Fetch());
1346
1347 EXPECT_EQ(loop1->context().monotonic_remote_time,
1348 loop1->context().monotonic_event_time);
1349 EXPECT_EQ(loop1->context().realtime_remote_time,
1350 loop1->context().realtime_event_time);
1351
1352 const aos::monotonic_clock::time_point monotonic_now =
1353 loop1->monotonic_now();
1354 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
1355
1356 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1357 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1358 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1359 monotonic_now);
1360 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1361 realtime_now);
1362
1363 triggered = true;
1364 });
1365
1366 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1367
1368 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
1369 Run();
1370
1371 ASSERT_TRUE(triggered);
Austin Schuh7267c532019-05-19 19:55:53 -07001372
Alex Perrycb7da4b2019-08-28 19:35:56 -07001373 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001374 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001375 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1376 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001377 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001378 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -07001379
Austin Schuhad154822019-12-27 15:45:13 -08001380 EXPECT_EQ(fetcher.context().realtime_event_time,
1381 fetcher.context().realtime_remote_time);
1382 EXPECT_EQ(fetcher.context().monotonic_event_time,
1383 fetcher.context().monotonic_remote_time);
1384
Alex Perrycb7da4b2019-08-28 19:35:56 -07001385 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1386 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001387 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -07001388 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001389 // Confirm that the data pointer makes sense.
1390 EXPECT_GT(fetcher.get(), fetcher.context().data);
1391 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001392 reinterpret_cast<const void *>(
1393 reinterpret_cast<const char *>(fetcher.context().data) +
Alex Perrycb7da4b2019-08-28 19:35:56 -07001394 fetcher.context().size));
1395 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1396 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001397 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -07001398 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001399
1400 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1401 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001402 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001403 << " expected " << loop1->realtime_now().time_since_epoch().count();
1404 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1405 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001406 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001407 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -07001408}
1409
Austin Schuh52d325c2019-06-23 18:59:06 -07001410// Tests that a couple phased loops run in a row result in the correct offset
1411// and period.
1412TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -08001413 // Force a slower rate so we are guarenteed to have reports for our phased
1414 // loop.
1415 FLAGS_timing_report_ms = 2000;
1416
Austin Schuh52d325c2019-06-23 18:59:06 -07001417 const chrono::milliseconds kOffset = chrono::milliseconds(400);
1418 const int kCount = 5;
1419
1420 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -08001421 auto loop2 = Make();
1422
1423 Fetcher<timing::Report> report_fetcher =
1424 loop2->MakeFetcher<timing::Report>("/aos");
1425 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001426
1427 // Collect up a couple of samples.
1428 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001429 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -07001430
1431 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -08001432 loop1
1433 ->AddPhasedLoop(
1434 [&times, &expected_times, &loop1, this](int count) {
1435 EXPECT_EQ(count, 1);
1436 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -08001437 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -08001438
Austin Schuhad154822019-12-27 15:45:13 -08001439 EXPECT_EQ(loop1->context().monotonic_remote_time,
1440 monotonic_clock::min_time);
1441 EXPECT_EQ(loop1->context().realtime_event_time,
1442 realtime_clock::min_time);
1443 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -08001444 realtime_clock::min_time);
1445 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
1446 EXPECT_EQ(loop1->context().size, 0u);
1447 EXPECT_EQ(loop1->context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -07001448 EXPECT_EQ(loop1->context().buffer_index, -1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001449
1450 if (times.size() == kCount) {
1451 LOG(INFO) << "Exiting";
1452 this->Exit();
1453 }
1454 },
1455 chrono::seconds(1), kOffset)
1456 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -07001457
1458 // Add a delay to make sure that delay during startup doesn't result in a
1459 // "missed cycle".
1460 SleepFor(chrono::seconds(2));
1461
1462 Run();
1463
1464 // Confirm that we got both the right number of samples, and it's odd.
1465 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001466 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -07001467 EXPECT_EQ((times.size() % 2), 1);
1468
1469 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001470 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -07001471
1472 // Add up all the delays of all the times.
1473 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1474 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001475 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -07001476 }
1477
1478 // Average and add to the middle to find the average time.
1479 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001480 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -07001481
1482 // Compute the offset from the start of the second of the average time. This
1483 // should be pretty close to the offset.
1484 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001485 average_time.time_since_epoch() -
1486 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001487
1488 const chrono::milliseconds kEpsilon(100);
1489 EXPECT_LT(remainder, kOffset + kEpsilon);
1490 EXPECT_GT(remainder, kOffset - kEpsilon);
1491
1492 // Make sure that the average duration is close to 1 second.
1493 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1494 times.front())
1495 .count() /
1496 static_cast<double>(times.size() - 1),
1497 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001498
1499 // Confirm that the ideal wakeup times increment correctly.
1500 for (size_t i = 1; i < expected_times.size(); ++i) {
1501 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1502 }
1503
1504 for (size_t i = 0; i < expected_times.size(); ++i) {
1505 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1506 kOffset);
1507 }
1508
1509 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1510 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001511
Austin Schuh6bae8252021-02-07 22:01:49 -08001512 if (do_timing_reports() == DoTimingReports::kYes) {
1513 // And, since we are here, check that the timing report makes sense.
1514 // Start by looking for our event loop's timing.
1515 FlatbufferDetachedBuffer<timing::Report> report =
1516 FlatbufferDetachedBuffer<timing::Report>::Empty();
1517 while (report_fetcher.FetchNext()) {
1518 if (report_fetcher->name()->string_view() == "primary") {
1519 report = CopyFlatBuffer(report_fetcher.get());
1520 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001521 }
Austin Schuh6bae8252021-02-07 22:01:49 -08001522
1523 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
1524
1525 EXPECT_EQ(report.message().name()->string_view(), "primary");
1526
1527 ASSERT_NE(report.message().senders(), nullptr);
1528 EXPECT_EQ(report.message().senders()->size(), 2);
1529
1530 ASSERT_NE(report.message().timers(), nullptr);
1531 EXPECT_EQ(report.message().timers()->size(), 1);
1532
1533 // Make sure there is a single phased loop report with our report in it.
1534 ASSERT_NE(report.message().phased_loops(), nullptr);
1535 ASSERT_EQ(report.message().phased_loops()->size(), 1);
1536 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
1537 "Test loop");
1538 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
1539 } else {
1540 ASSERT_FALSE(report_fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -08001541 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001542}
1543
1544// Tests that senders count correctly in the timing report.
1545TEST_P(AbstractEventLoopTest, SenderTimingReport) {
1546 FLAGS_timing_report_ms = 1000;
1547 auto loop1 = MakePrimary();
1548
1549 auto loop2 = Make("watcher_loop");
1550 loop2->MakeWatcher("/test", [](const TestMessage &) {});
1551
1552 auto loop3 = Make();
1553
1554 Fetcher<timing::Report> report_fetcher =
1555 loop3->MakeFetcher<timing::Report>("/aos");
1556 EXPECT_FALSE(report_fetcher.Fetch());
1557
1558 auto sender = loop1->MakeSender<TestMessage>("/test");
1559
1560 // Add a timer to actually quit.
1561 auto test_timer = loop1->AddTimer([&sender]() {
1562 for (int i = 0; i < 10; ++i) {
1563 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1564 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1565 builder.add_value(200 + i);
1566 ASSERT_TRUE(msg.Send(builder.Finish()));
1567 }
1568 });
1569
1570 // Quit after 1 timing report, mid way through the next cycle.
1571 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1572
1573 loop1->OnRun([&test_timer, &loop1]() {
1574 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1575 });
1576
1577 Run();
1578
Austin Schuh6bae8252021-02-07 22:01:49 -08001579 if (do_timing_reports() == DoTimingReports::kYes) {
1580 // And, since we are here, check that the timing report makes sense.
1581 // Start by looking for our event loop's timing.
1582 FlatbufferDetachedBuffer<timing::Report> primary_report =
1583 FlatbufferDetachedBuffer<timing::Report>::Empty();
1584 while (report_fetcher.FetchNext()) {
1585 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1586 if (report_fetcher->name()->string_view() == "primary") {
1587 primary_report = CopyFlatBuffer(report_fetcher.get());
1588 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001589 }
Austin Schuh6bae8252021-02-07 22:01:49 -08001590
1591 LOG(INFO) << FlatbufferToJson(primary_report, {.multi_line = true});
1592
1593 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1594
1595 ASSERT_NE(primary_report.message().senders(), nullptr);
1596 EXPECT_EQ(primary_report.message().senders()->size(), 3);
1597
1598 // Confirm that the sender looks sane.
1599 EXPECT_EQ(
1600 loop1->configuration()
1601 ->channels()
1602 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1603 ->name()
1604 ->string_view(),
1605 "/test");
1606 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1607
1608 // Confirm that the timing primary_report sender looks sane.
1609 EXPECT_EQ(
1610 loop1->configuration()
1611 ->channels()
1612 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1613 ->name()
1614 ->string_view(),
1615 "/aos");
1616 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1617
1618 ASSERT_NE(primary_report.message().timers(), nullptr);
1619 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1620
1621 // Make sure there are no phased loops or watchers.
1622 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1623 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1624 } else {
1625 ASSERT_FALSE(report_fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -08001626 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001627}
1628
1629// Tests that senders count correctly in the timing report.
1630TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1631 FLAGS_timing_report_ms = 1000;
1632 auto loop1 = MakePrimary();
1633 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1634
1635 auto loop2 = Make("sender_loop");
1636
1637 auto loop3 = Make();
1638
1639 Fetcher<timing::Report> report_fetcher =
1640 loop3->MakeFetcher<timing::Report>("/aos");
1641 EXPECT_FALSE(report_fetcher.Fetch());
1642
1643 auto sender = loop2->MakeSender<TestMessage>("/test");
1644
1645 // Add a timer to actually quit.
1646 auto test_timer = loop1->AddTimer([&sender]() {
1647 for (int i = 0; i < 10; ++i) {
1648 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1649 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1650 builder.add_value(200 + i);
1651 ASSERT_TRUE(msg.Send(builder.Finish()));
1652 }
1653 });
1654
1655 // Quit after 1 timing report, mid way through the next cycle.
1656 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1657
1658 loop1->OnRun([&test_timer, &loop1]() {
1659 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1660 });
1661
1662 Run();
1663
Austin Schuh6bae8252021-02-07 22:01:49 -08001664 if (do_timing_reports() == DoTimingReports::kYes) {
1665 // And, since we are here, check that the timing report makes sense.
1666 // Start by looking for our event loop's timing.
1667 FlatbufferDetachedBuffer<timing::Report> primary_report =
1668 FlatbufferDetachedBuffer<timing::Report>::Empty();
1669 while (report_fetcher.FetchNext()) {
1670 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1671 if (report_fetcher->name()->string_view() == "primary") {
1672 primary_report = CopyFlatBuffer(report_fetcher.get());
1673 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001674 }
Austin Schuh6bae8252021-02-07 22:01:49 -08001675
1676 // Check the watcher report.
1677 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
1678
1679 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1680
1681 // Just the timing report timer.
1682 ASSERT_NE(primary_report.message().timers(), nullptr);
1683 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1684
1685 // No phased loops
1686 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1687
1688 ASSERT_NE(primary_report.message().watchers(), nullptr);
1689 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1690 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1691 } else {
1692 ASSERT_FALSE(report_fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -08001693 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001694}
1695
1696// Tests that fetchers count correctly in the timing report.
1697TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1698 FLAGS_timing_report_ms = 1000;
1699 auto loop1 = MakePrimary();
1700 auto loop2 = Make("sender_loop");
1701
1702 auto loop3 = Make();
1703
1704 Fetcher<timing::Report> report_fetcher =
1705 loop3->MakeFetcher<timing::Report>("/aos");
1706 EXPECT_FALSE(report_fetcher.Fetch());
1707
1708 auto sender = loop2->MakeSender<TestMessage>("/test");
1709 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1710 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1711 fetcher1.Fetch();
1712 fetcher2.Fetch();
1713
1714 // Add a timer to actually quit.
1715 auto test_timer = loop1->AddTimer([&sender]() {
1716 for (int i = 0; i < 10; ++i) {
1717 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1718 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1719 builder.add_value(200 + i);
1720 ASSERT_TRUE(msg.Send(builder.Finish()));
1721 }
1722 });
1723
1724 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1725 fetcher1.Fetch();
1726 while (fetcher2.FetchNext()) {
1727 }
1728 });
1729
1730 // Quit after 1 timing report, mid way through the next cycle.
1731 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1732
1733 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1734 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1735 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1736 });
1737
1738 Run();
1739
Austin Schuh6bae8252021-02-07 22:01:49 -08001740 if (do_timing_reports() == DoTimingReports::kYes) {
1741 // And, since we are here, check that the timing report makes sense.
1742 // Start by looking for our event loop's timing.
1743 FlatbufferDetachedBuffer<timing::Report> primary_report =
1744 FlatbufferDetachedBuffer<timing::Report>::Empty();
1745 while (report_fetcher.FetchNext()) {
1746 if (report_fetcher->name()->string_view() == "primary") {
1747 primary_report = CopyFlatBuffer(report_fetcher.get());
1748 }
Austin Schuh39788ff2019-12-01 18:22:57 -08001749 }
Austin Schuh6bae8252021-02-07 22:01:49 -08001750
1751 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
1752
1753 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1754
1755 ASSERT_NE(primary_report.message().senders(), nullptr);
1756 EXPECT_EQ(primary_report.message().senders()->size(), 2);
1757
1758 ASSERT_NE(primary_report.message().timers(), nullptr);
1759 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1760
1761 // Make sure there are no phased loops or watchers.
1762 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1763 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1764
1765 // Now look at the fetchrs.
1766 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1767 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1768
1769 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1770 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1771 0.1);
1772 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(),
1773 0.1);
1774 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(),
1775 0.1);
1776 EXPECT_EQ(primary_report.message()
1777 .fetchers()
1778 ->Get(0)
1779 ->latency()
1780 ->standard_deviation(),
1781 0.0);
1782
1783 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
1784 } else {
1785 ASSERT_FALSE(report_fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -08001786 }
Austin Schuh52d325c2019-06-23 18:59:06 -07001787}
1788
Austin Schuh67420a42019-12-21 21:55:04 -08001789// Tests that a raw watcher and raw fetcher can receive messages from a raw
1790// sender without messing up offsets.
1791TEST_P(AbstractEventLoopTest, RawBasic) {
1792 auto loop1 = Make();
1793 auto loop2 = MakePrimary();
1794 auto loop3 = Make();
1795
1796 const std::string kData("971 is the best");
1797
1798 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001799 loop1->MakeRawSender(configuration::GetChannel(
1800 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001801
1802 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001803 loop3->MakeRawFetcher(configuration::GetChannel(
1804 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001805
1806 loop2->OnRun(
1807 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1808
1809 bool happened = false;
1810 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001811 configuration::GetChannel(loop2->configuration(), "/test",
1812 "aos.TestMessage", "", nullptr),
Austin Schuh67420a42019-12-21 21:55:04 -08001813 [this, &kData, &fetcher, &happened](const Context &context,
1814 const void *message) {
1815 happened = true;
1816 EXPECT_EQ(std::string_view(kData),
1817 std::string_view(reinterpret_cast<const char *>(message),
1818 context.size));
1819 EXPECT_EQ(std::string_view(kData),
1820 std::string_view(reinterpret_cast<const char *>(context.data),
1821 context.size));
1822
1823 ASSERT_TRUE(fetcher->Fetch());
1824
1825 EXPECT_EQ(std::string_view(kData),
1826 std::string_view(
1827 reinterpret_cast<const char *>(fetcher->context().data),
1828 fetcher->context().size));
1829
1830 this->Exit();
1831 });
1832
1833 EXPECT_FALSE(happened);
1834 Run();
1835 EXPECT_TRUE(happened);
1836}
1837
Austin Schuhad154822019-12-27 15:45:13 -08001838// Tests that a raw watcher and raw fetcher can receive messages from a raw
1839// sender with remote times filled out.
1840TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1841 auto loop1 = Make();
1842 auto loop2 = MakePrimary();
1843 auto loop3 = Make();
1844
1845 const std::string kData("971 is the best");
1846
1847 const aos::monotonic_clock::time_point monotonic_remote_time =
1848 aos::monotonic_clock::time_point(chrono::seconds(1501));
1849 const aos::realtime_clock::time_point realtime_remote_time =
1850 aos::realtime_clock::time_point(chrono::seconds(3132));
Austin Schuhb5c6f972021-03-14 21:53:07 -07001851 const uint32_t remote_queue_index = 0x254971;
Austin Schuhad154822019-12-27 15:45:13 -08001852
1853 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001854 loop1->MakeRawSender(configuration::GetChannel(
1855 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001856
1857 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001858 loop3->MakeRawFetcher(configuration::GetChannel(
1859 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001860
1861 loop2->OnRun([&]() {
1862 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
Austin Schuhb5c6f972021-03-14 21:53:07 -07001863 realtime_remote_time, remote_queue_index));
Austin Schuhad154822019-12-27 15:45:13 -08001864 });
1865
1866 bool happened = false;
1867 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001868 configuration::GetChannel(loop2->configuration(), "/test",
1869 "aos.TestMessage", "", nullptr),
Austin Schuhb5c6f972021-03-14 21:53:07 -07001870 [this, monotonic_remote_time, realtime_remote_time,
1871 remote_queue_index, &fetcher,
1872 &happened](const Context &context, const void * /*message*/) {
Austin Schuhad154822019-12-27 15:45:13 -08001873 happened = true;
1874 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1875 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
Austin Schuhb5c6f972021-03-14 21:53:07 -07001876 EXPECT_EQ(remote_queue_index, context.remote_queue_index);
Austin Schuhad154822019-12-27 15:45:13 -08001877
1878 ASSERT_TRUE(fetcher->Fetch());
1879 EXPECT_EQ(monotonic_remote_time,
1880 fetcher->context().monotonic_remote_time);
1881 EXPECT_EQ(realtime_remote_time,
1882 fetcher->context().realtime_remote_time);
1883
1884 this->Exit();
1885 });
1886
1887 EXPECT_FALSE(happened);
1888 Run();
1889 EXPECT_TRUE(happened);
1890}
1891
1892// Tests that a raw sender fills out sent data.
1893TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1894 auto loop1 = MakePrimary();
1895
1896 const std::string kData("971 is the best");
1897
1898 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001899 loop1->MakeRawSender(configuration::GetChannel(
1900 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001901
Tyler Chatow67ddb032020-01-12 14:30:04 -08001902 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
1903 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001904
1905 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1906
1907 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1908 EXPECT_LE(sender->monotonic_sent_time(),
1909 monotonic_now + chrono::milliseconds(100));
1910 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1911 EXPECT_LE(sender->realtime_sent_time(),
1912 realtime_now + chrono::milliseconds(100));
1913 EXPECT_EQ(sender->sent_queue_index(), 0u);
1914
1915 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1916
1917 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1918 EXPECT_LE(sender->monotonic_sent_time(),
1919 monotonic_now + chrono::milliseconds(100));
1920 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1921 EXPECT_LE(sender->realtime_sent_time(),
1922 realtime_now + chrono::milliseconds(100));
1923 EXPECT_EQ(sender->sent_queue_index(), 1u);
1924}
1925
Austin Schuh217a9782019-12-21 23:02:50 -08001926// Tests that not setting up nodes results in no node.
1927TEST_P(AbstractEventLoopTest, NoNode) {
1928 auto loop1 = Make();
1929 auto loop2 = MakePrimary();
1930
1931 EXPECT_EQ(loop1->node(), nullptr);
1932 EXPECT_EQ(loop2->node(), nullptr);
1933}
1934
1935// Tests that setting up nodes results in node being set.
1936TEST_P(AbstractEventLoopTest, Node) {
1937 EnableNodes("me");
1938
1939 auto loop1 = Make();
1940 auto loop2 = MakePrimary();
1941
1942 EXPECT_NE(loop1->node(), nullptr);
1943 EXPECT_NE(loop2->node(), nullptr);
1944}
1945
1946// Tests that watchers work with a node setup.
1947TEST_P(AbstractEventLoopTest, NodeWatcher) {
1948 EnableNodes("me");
1949
1950 auto loop1 = Make();
1951 auto loop2 = Make();
1952 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08001953 loop2->MakeRawWatcher(
1954 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1955 nullptr),
1956 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001957}
1958
Brian Silverman454bc112020-03-05 14:21:25 -08001959// Tests that no-arg watchers work with a node setup.
1960TEST_P(AbstractEventLoopTest, NodeNoArgWatcher) {
1961 EnableNodes("me");
1962
1963 auto loop1 = Make();
1964 auto loop2 = Make();
1965 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1966 loop2->MakeRawNoArgWatcher(
1967 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1968 nullptr),
1969 [](const Context &) {});
1970}
1971
Austin Schuh217a9782019-12-21 23:02:50 -08001972// Tests that fetcher work with a node setup.
1973TEST_P(AbstractEventLoopTest, NodeFetcher) {
1974 EnableNodes("me");
1975 auto loop1 = Make();
1976
1977 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08001978 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1979 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001980}
1981
1982// Tests that sender work with a node setup.
1983TEST_P(AbstractEventLoopTest, NodeSender) {
1984 EnableNodes("me");
1985 auto loop1 = Make();
1986
1987 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1988}
1989
Austin Schuhcc6070c2020-10-10 20:25:56 -07001990// Tests that a non-realtime event loop timer is marked non-realtime.
1991TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopTimer) {
1992 auto loop1 = MakePrimary();
1993
1994 // Add a timer to actually quit.
1995 auto test_timer = loop1->AddTimer([this]() {
1996 CheckNotRealtime();
1997 this->Exit();
1998 });
1999
2000 loop1->OnRun([&test_timer, &loop1]() {
2001 CheckNotRealtime();
2002 test_timer->Setup(loop1->monotonic_now(), ::std::chrono::milliseconds(100));
2003 });
2004
2005 Run();
2006}
2007
2008// Tests that a realtime event loop timer is marked realtime.
2009TEST_P(AbstractEventLoopTest, RealtimeEventLoopTimer) {
2010 auto loop1 = MakePrimary();
2011
2012 loop1->SetRuntimeRealtimePriority(1);
2013
2014 // Add a timer to actually quit.
2015 auto test_timer = loop1->AddTimer([this]() {
2016 CheckRealtime();
2017 this->Exit();
2018 });
2019
2020 loop1->OnRun([&test_timer, &loop1]() {
2021 CheckRealtime();
2022 test_timer->Setup(loop1->monotonic_now(), ::std::chrono::milliseconds(100));
2023 });
2024
2025 Run();
2026}
2027
2028// Tests that a non-realtime event loop phased loop is marked non-realtime.
2029TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopPhasedLoop) {
2030 auto loop1 = MakePrimary();
2031
2032 // Add a timer to actually quit.
2033 loop1->AddPhasedLoop(
2034 [this](int) {
2035 CheckNotRealtime();
2036 this->Exit();
2037 },
2038 chrono::seconds(1), chrono::seconds(0));
2039
2040 Run();
2041}
2042
2043// Tests that a realtime event loop phased loop is marked realtime.
2044TEST_P(AbstractEventLoopTest, RealtimeEventLoopPhasedLoop) {
2045 auto loop1 = MakePrimary();
2046
2047 loop1->SetRuntimeRealtimePriority(1);
2048
2049 // Add a timer to actually quit.
2050 loop1->AddPhasedLoop(
2051 [this](int) {
2052 CheckRealtime();
2053 this->Exit();
2054 },
2055 chrono::seconds(1), chrono::seconds(0));
2056
2057 Run();
2058}
2059
2060// Tests that a non-realtime event loop watcher is marked non-realtime.
2061TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopWatcher) {
2062 auto loop1 = MakePrimary();
2063 auto loop2 = Make();
2064
2065 aos::Sender<TestMessage> sender = loop2->MakeSender<TestMessage>("/test");
2066
2067 loop1->OnRun([&]() {
2068 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
2069 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
2070 ASSERT_TRUE(msg.Send(builder.Finish()));
2071 });
2072
2073 loop1->MakeWatcher("/test", [&](const TestMessage &) {
2074 CheckNotRealtime();
2075 this->Exit();
2076 });
2077
2078 Run();
2079}
2080
2081// Tests that a realtime event loop watcher is marked realtime.
2082TEST_P(AbstractEventLoopTest, RealtimeEventLoopWatcher) {
2083 auto loop1 = MakePrimary();
2084 auto loop2 = Make();
2085
2086 loop1->SetRuntimeRealtimePriority(1);
2087
2088 aos::Sender<TestMessage> sender = loop2->MakeSender<TestMessage>("/test");
2089
2090 loop1->OnRun([&]() {
2091 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
2092 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
2093 ASSERT_TRUE(msg.Send(builder.Finish()));
2094 });
2095
2096 loop1->MakeWatcher("/test", [&](const TestMessage &) {
2097 CheckRealtime();
2098 this->Exit();
2099 });
2100
2101 Run();
2102}
2103
Austin Schuh217a9782019-12-21 23:02:50 -08002104// Tests that watchers fail when created on the wrong node.
2105TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
2106 EnableNodes("them");
2107
2108 auto loop1 = Make();
2109 auto loop2 = Make();
2110 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
2111 "node");
2112 EXPECT_DEATH(
2113 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08002114 loop2->MakeRawWatcher(
2115 configuration::GetChannel(configuration(), "/test",
2116 "aos.TestMessage", "", nullptr),
2117 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08002118 },
2119 "node");
Brian Silverman454bc112020-03-05 14:21:25 -08002120 EXPECT_DEATH({ loop1->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
2121 "node");
2122 EXPECT_DEATH(
2123 {
2124 loop2->MakeRawNoArgWatcher(
2125 configuration::GetChannel(configuration(), "/test",
2126 "aos.TestMessage", "", nullptr),
2127 [](const Context &) {});
2128 },
2129 "node");
Austin Schuh217a9782019-12-21 23:02:50 -08002130}
2131
2132// Tests that fetchers fail when created on the wrong node.
2133TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
2134 EnableNodes("them");
2135 auto loop1 = Make();
2136
2137 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
2138 "node");
2139 EXPECT_DEATH(
2140 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08002141 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
2142 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08002143 },
2144 "node");
2145}
2146
2147// Tests that senders fail when created on the wrong node.
2148TEST_P(AbstractEventLoopDeathTest, NodeSender) {
2149 EnableNodes("them");
2150 auto loop1 = Make();
2151
2152 EXPECT_DEATH(
2153 {
2154 aos::Sender<TestMessage> sender =
2155 loop1->MakeSender<TestMessage>("/test");
2156 },
2157 "node");
2158
2159 // Note: Creating raw senders is always supported. Right now, this lets us
2160 // use them to create message_gateway.
2161}
2162
Brian Silverman341b57e2020-06-23 16:23:18 -07002163// Tests creating multiple Builders from a single Sender at the same time.
2164TEST_P(AbstractEventLoopDeathTest, MultipleBuilders) {
2165 auto loop1 = Make();
2166 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
2167
2168 { auto builder = sender.MakeBuilder(); }
2169 {
2170 auto builder = sender.MakeBuilder();
2171 builder.MakeBuilder<TestMessage>().Finish();
2172 }
2173 {
2174 // Creating this after the first one was destroyed should be fine.
2175 auto builder = sender.MakeBuilder();
2176 builder.MakeBuilder<TestMessage>().Finish();
2177 // But not a second one.
2178 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2179 "May not overwrite in-use allocator");
2180 }
2181
2182 FlatbufferDetachedBuffer<TestMessage> detached =
2183 flatbuffers::DetachedBuffer();
2184 {
2185 auto builder = sender.MakeBuilder();
2186 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2187 }
2188 {
2189 // This is the second one, after the detached one, so it should fail.
2190 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2191 "May not overwrite in-use allocator");
2192 }
2193
2194 // Clear the detached one, and then we should be able to create another.
2195 detached = flatbuffers::DetachedBuffer();
2196 {
2197 auto builder = sender.MakeBuilder();
2198 builder.MakeBuilder<TestMessage>().Finish();
2199 }
2200
2201 // And then detach another one.
2202 {
2203 auto builder = sender.MakeBuilder();
2204 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2205 }
2206}
2207
2208// Tests sending a buffer detached from a different builder.
2209TEST_P(AbstractEventLoopDeathTest, WrongDetachedBuffer) {
2210 auto loop1 = Make();
2211 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
2212 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
2213
2214 auto builder = sender1.MakeBuilder();
2215 FlatbufferDetachedBuffer<TestMessage> detached =
2216 builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2217 EXPECT_DEATH(sender2.SendDetached(std::move(detached)),
2218 "May only send the buffer detached from this Sender");
2219}
2220
Parker Schuhe4a70d62017-12-27 20:10:20 -08002221} // namespace testing
2222} // namespace aos