blob: dc7c5d0254935e8b4bfc8b09b88917c2b5779900 [file] [log] [blame]
Alex Perrycb7da4b2019-08-28 19:35:56 -07001#include "aos/events/event_loop_param_test.h"
Parker Schuhe4a70d62017-12-27 20:10:20 -08002
Austin Schuh52d325c2019-06-23 18:59:06 -07003#include <chrono>
4
Alex Perrycb7da4b2019-08-28 19:35:56 -07005#include "aos/events/test_message_generated.h"
Austin Schuh54cf95f2019-11-29 13:14:18 -08006#include "aos/flatbuffer_merge.h"
7#include "glog/logging.h"
Tyler Chatow67ddb032020-01-12 14:30:04 -08008#include "gmock/gmock.h"
9#include "gtest/gtest.h"
Austin Schuh9fe68f72019-08-10 19:32:03 -070010
Parker Schuhe4a70d62017-12-27 20:10:20 -080011namespace aos {
12namespace testing {
Austin Schuh52d325c2019-06-23 18:59:06 -070013namespace {
14namespace chrono = ::std::chrono;
15} // namespace
Parker Schuhe4a70d62017-12-27 20:10:20 -080016
Austin Schuh6b6dfa52019-06-12 20:16:20 -070017// Tests that watcher can receive messages from a sender.
Parker Schuhe4a70d62017-12-27 20:10:20 -080018// Also tests that OnRun() works.
19TEST_P(AbstractEventLoopTest, Basic) {
20 auto loop1 = Make();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070021 auto loop2 = MakePrimary();
22
Alex Perrycb7da4b2019-08-28 19:35:56 -070023 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
Austin Schuh6b6dfa52019-06-12 20:16:20 -070024
25 bool happened = false;
26
27 loop2->OnRun([&]() {
28 happened = true;
29
Alex Perrycb7da4b2019-08-28 19:35:56 -070030 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
31 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
32 builder.add_value(200);
33 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -070034 });
35
36 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070037 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -070038 this->Exit();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070039 });
40
41 EXPECT_FALSE(happened);
42 Run();
43 EXPECT_TRUE(happened);
44}
45
Brian Silverman6b8a3c32020-03-06 11:26:14 -080046// Verifies that a no-arg watcher will not have a data pointer.
47TEST_P(AbstractEventLoopTest, NoArgNoData) {
48 auto loop1 = Make();
49 auto loop2 = MakePrimary();
50
51 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
52
53 bool happened = false;
54
55 loop2->OnRun([&]() {
56 happened = true;
57
58 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
59 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
60 ASSERT_TRUE(msg.Send(builder.Finish()));
61 });
62
63 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
64 EXPECT_GT(loop2->context().size, 0u);
65 EXPECT_EQ(nullptr, loop2->context().data);
66 this->Exit();
67 });
68
69 EXPECT_FALSE(happened);
70 Run();
71 EXPECT_TRUE(happened);
72}
73
Brian Silverman454bc112020-03-05 14:21:25 -080074// Tests that no-arg watcher can receive messages from a sender.
75// Also tests that OnRun() works.
76TEST_P(AbstractEventLoopTest, BasicNoArg) {
77 auto loop1 = Make();
78 auto loop2 = MakePrimary();
79
80 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
81
82 bool happened = false;
83
84 loop2->OnRun([&]() {
85 happened = true;
86
87 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
88 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
89 builder.add_value(200);
90 ASSERT_TRUE(msg.Send(builder.Finish()));
91 });
92
93 aos::Fetcher<TestMessage> fetcher = loop2->MakeFetcher<TestMessage>("/test");
94 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
95 ASSERT_TRUE(fetcher.Fetch());
96 EXPECT_EQ(fetcher->value(), 200);
97 this->Exit();
98 });
99
100 EXPECT_FALSE(happened);
101 Run();
102 EXPECT_TRUE(happened);
103}
104
105// Tests that a watcher can be created with an std::function.
106TEST_P(AbstractEventLoopTest, BasicFunction) {
107 auto loop1 = Make();
108 auto loop2 = MakePrimary();
109
110 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
111
112 bool happened = false;
113
114 loop2->OnRun([&]() {
115 happened = true;
116
117 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
118 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
119 builder.add_value(200);
120 ASSERT_TRUE(msg.Send(builder.Finish()));
121 });
122
123 loop2->MakeWatcher("/test", std::function<void(const TestMessage &)>(
124 [&](const TestMessage &message) {
125 EXPECT_EQ(message.value(), 200);
126 this->Exit();
127 }));
128
129 EXPECT_FALSE(happened);
130 Run();
131 EXPECT_TRUE(happened);
132}
133
Brian Silverman0fc69932020-01-24 21:54:02 -0800134// Tests that watcher can receive messages from two senders.
135// Also tests that OnRun() works.
136TEST_P(AbstractEventLoopTest, BasicTwoSenders) {
137 auto loop1 = Make();
138 auto loop2 = MakePrimary();
139
140 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
141 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
142
143 bool happened = false;
144
145 loop2->OnRun([&]() {
146 happened = true;
147
148 {
149 aos::Sender<TestMessage>::Builder msg = sender1.MakeBuilder();
150 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
151 builder.add_value(200);
152 ASSERT_TRUE(msg.Send(builder.Finish()));
153 }
154 {
155 aos::Sender<TestMessage>::Builder msg = sender2.MakeBuilder();
156 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
157 builder.add_value(200);
158 ASSERT_TRUE(msg.Send(builder.Finish()));
159 }
160 });
161
162 int messages_received = 0;
163 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
164 EXPECT_EQ(message.value(), 200);
165 this->Exit();
166 ++messages_received;
167 });
168
169 EXPECT_FALSE(happened);
170 Run();
171 EXPECT_TRUE(happened);
172 EXPECT_EQ(messages_received, 2);
173}
174
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700175// Tests that a fetcher can fetch from a sender.
176// Also tests that OnRun() works.
177TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
178 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800179 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700180 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800181
182 auto sender = loop1->MakeSender<TestMessage>("/test");
183
184 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
185
Austin Schuhbbce72d2019-05-26 15:11:46 -0700186 EXPECT_FALSE(fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -0800187 EXPECT_EQ(fetcher.get(), nullptr);
188
Austin Schuhad154822019-12-27 15:45:13 -0800189 EXPECT_EQ(fetcher.context().monotonic_event_time, monotonic_clock::min_time);
190 EXPECT_EQ(fetcher.context().monotonic_remote_time, monotonic_clock::min_time);
191 EXPECT_EQ(fetcher.context().realtime_event_time, realtime_clock::min_time);
192 EXPECT_EQ(fetcher.context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800193 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
194 EXPECT_EQ(fetcher.context().size, 0u);
195 EXPECT_EQ(fetcher.context().data, nullptr);
Austin Schuhbbce72d2019-05-26 15:11:46 -0700196
Alex Perrycb7da4b2019-08-28 19:35:56 -0700197 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
198 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
199 builder.add_value(200);
200 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700201
202 EXPECT_TRUE(fetcher.Fetch());
203 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700204 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -0800205
206 const chrono::milliseconds kEpsilon(100);
207
Austin Schuhad154822019-12-27 15:45:13 -0800208 const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
209 const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
210 EXPECT_EQ(fetcher.context().monotonic_event_time,
211 fetcher.context().monotonic_remote_time);
212 EXPECT_EQ(fetcher.context().realtime_event_time,
213 fetcher.context().realtime_remote_time);
214
215 EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
216 EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
217 EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
218 EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800219 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
220 EXPECT_EQ(fetcher.context().size, 20u);
221 EXPECT_NE(fetcher.context().data, nullptr);
Parker Schuhe4a70d62017-12-27 20:10:20 -0800222}
223
Austin Schuh3578a2e2019-05-25 18:17:59 -0700224// Tests that watcher will receive all messages sent if they are sent after
225// initialization and before running.
226TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
227 auto loop1 = Make();
228 auto loop2 = MakePrimary();
229
230 auto sender = loop1->MakeSender<TestMessage>("/test");
231
232 ::std::vector<int> values;
233
234 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700235 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700236 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700237 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700238 }
239 });
240
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700241 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -0700242 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700243 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
244 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
245 builder.add_value(199);
246 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700247 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700248
249 loop2->OnRun([&]() {
250 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700251 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
252 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
253 builder.add_value(200);
254 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700255 }
256 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700257 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
258 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
259 builder.add_value(201);
260 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700261 }
262 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700263
264 Run();
265
266 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
267}
268
269// Tests that watcher will not receive messages sent before the watcher is
270// created.
271TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
272 auto loop1 = Make();
273 auto loop2 = MakePrimary();
274
275 auto sender = loop1->MakeSender<TestMessage>("/test");
276
277 ::std::vector<int> values;
278
279 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700280 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
281 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
282 builder.add_value(200);
283 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700284 }
285 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700286 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
287 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
288 builder.add_value(201);
289 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700290 }
291
292 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700293 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700294 });
295
296 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700297 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700298 loop2->OnRun([&test_timer, &loop2]() {
299 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
300 });
301
302 Run();
303 EXPECT_EQ(0, values.size());
304}
305
Austin Schuhbbce72d2019-05-26 15:11:46 -0700306// Tests that FetchNext gets all the messages sent after it is constructed.
307TEST_P(AbstractEventLoopTest, FetchNext) {
308 auto loop1 = Make();
309 auto loop2 = MakePrimary();
310
311 auto sender = loop1->MakeSender<TestMessage>("/test");
312 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
313
314 ::std::vector<int> values;
315
316 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700317 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
318 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
319 builder.add_value(200);
320 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700321 }
322 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700323 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
324 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
325 builder.add_value(201);
326 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700327 }
328
329 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700330 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700331 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700332 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700333 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700334 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700335 });
336
337 loop2->OnRun([&test_timer, &loop2]() {
338 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
339 });
340
341 Run();
342 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
343}
344
345// Tests that FetchNext gets no messages sent before it is constructed.
346TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
347 auto loop1 = Make();
348 auto loop2 = MakePrimary();
349
350 auto sender = loop1->MakeSender<TestMessage>("/test");
351
352 ::std::vector<int> values;
353
354 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700355 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
356 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
357 builder.add_value(200);
358 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700359 }
360 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700361 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
362 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
363 builder.add_value(201);
364 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700365 }
366
367 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
368
369 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700370 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700371 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700372 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700373 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700374 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700375 });
376
377 loop2->OnRun([&test_timer, &loop2]() {
378 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
379 });
380
381 Run();
382 EXPECT_THAT(0, values.size());
383}
384
385// Tests that Fetch returns the last message created before the loop was
386// started.
387TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
388 auto loop1 = Make();
389 auto loop2 = MakePrimary();
390
391 auto sender = loop1->MakeSender<TestMessage>("/test");
392
393 ::std::vector<int> values;
394
395 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700396 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
397 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
398 builder.add_value(200);
399 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700400 }
401 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700402 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
403 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
404 builder.add_value(201);
405 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700406 }
407
408 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
409
410 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700411 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700412 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700413 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700414 }
415 // Do it again to make sure we don't double fetch.
416 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700417 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700418 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700419 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700420 });
421
422 loop2->OnRun([&test_timer, &loop2]() {
423 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
424 });
425
426 Run();
427 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
428}
429
430// Tests that Fetch and FetchNext interleave as expected.
431TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
432 auto loop1 = Make();
433 auto loop2 = MakePrimary();
434
435 auto sender = loop1->MakeSender<TestMessage>("/test");
436
437 ::std::vector<int> values;
438
439 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700440 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
441 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
442 builder.add_value(200);
443 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700444 }
445 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700446 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
447 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
448 builder.add_value(201);
449 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700450 }
451
452 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
453
454 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700455 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700456 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700457 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700458 }
459
460 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700461 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
462 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
463 builder.add_value(202);
464 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700465 }
466 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700467 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
468 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
469 builder.add_value(203);
470 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700471 }
472 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700473 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
474 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
475 builder.add_value(204);
476 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700477 }
478
479 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700480 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700481 }
482
483 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700484 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700485 }
486
Austin Schuh9fe68f72019-08-10 19:32:03 -0700487 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700488 });
489
490 loop2->OnRun([&test_timer, &loop2]() {
491 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
492 });
493
494 Run();
495 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
496}
497
Austin Schuh3115a202019-05-27 21:02:14 -0700498// Tests that FetchNext behaves correctly when we get two messages in the queue
499// but don't consume the first until after the second has been sent.
500TEST_P(AbstractEventLoopTest, FetchNextTest) {
Austin Schuh3115a202019-05-27 21:02:14 -0700501 auto send_loop = Make();
502 auto fetch_loop = Make();
503 auto sender = send_loop->MakeSender<TestMessage>("/test");
504 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
505
506 {
Tyler Chatow67ddb032020-01-12 14:30:04 -0800507 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
508 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
509 builder.add_value(100);
510 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700511 }
512
513 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700514 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
515 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
516 builder.add_value(200);
517 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700518 }
519
520 ASSERT_TRUE(fetcher.FetchNext());
521 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700522 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700523
524 ASSERT_TRUE(fetcher.FetchNext());
525 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700526 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700527
528 // When we run off the end of the queue, expect to still have the old message:
529 ASSERT_FALSE(fetcher.FetchNext());
530 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700531 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700532}
533
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800534// Verify that making a fetcher and watcher for "/test" succeeds.
535TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800536 auto loop = Make();
537 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800538 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800539}
540
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800541// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800542TEST_P(AbstractEventLoopTest, TwoFetcher) {
543 auto loop = Make();
544 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800545 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800546}
547
Alex Perrycb7da4b2019-08-28 19:35:56 -0700548// Verify that registering a watcher for an invalid channel name dies.
549TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
550 auto loop = Make();
551 EXPECT_DEATH(
552 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
553 "/test/invalid");
Brian Silverman454bc112020-03-05 14:21:25 -0800554 EXPECT_DEATH(
555 { loop->MakeNoArgWatcher<TestMessage>("/test/invalid", [&]() {}); },
556 "/test/invalid");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700557}
558
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800559// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700560TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800561 auto loop = Make();
562 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800563 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
564 "/test");
Brian Silverman454bc112020-03-05 14:21:25 -0800565 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
566}
567
568// Verify that registering a no-arg watcher twice for "/test" fails.
569TEST_P(AbstractEventLoopDeathTest, TwoNoArgWatcher) {
570 auto loop = Make();
571 loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {});
572 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
573 "/test");
574 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800575}
576
Austin Schuh3115a202019-05-27 21:02:14 -0700577// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700578TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700579 auto loop = MakePrimary();
580 // Confirm that runtime priority calls work when not realtime.
581 loop->SetRuntimeRealtimePriority(5);
582
583 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
584
585 EXPECT_DEATH(Run(), "realtime");
586}
587
Brian Silverman6a54ff32020-04-28 16:41:39 -0700588// Verify that SetRuntimeAffinity fails while running.
589TEST_P(AbstractEventLoopDeathTest, SetRuntimeAffinity) {
590 auto loop = MakePrimary();
591 // Confirm that runtime priority calls work when not running.
592 loop->SetRuntimeAffinity(MakeCpusetFromCpus({0}));
593
594 loop->OnRun([&]() { loop->SetRuntimeAffinity(MakeCpusetFromCpus({1})); });
595
596 EXPECT_DEATH(Run(), "Cannot set affinity while running");
597}
598
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800599// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700600TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800601 auto loop = Make();
602 auto sender = loop->MakeSender<TestMessage>("/test");
603 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
604 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800605}
606
Austin Schuhe516ab02020-05-06 21:37:04 -0700607// Verify that creating too many senders fails.
608TEST_P(AbstractEventLoopDeathTest, TooManySenders) {
609 auto loop = Make();
610 std::vector<aos::Sender<TestMessage>> senders;
611 for (int i = 0; i < 10; ++i) {
612 senders.emplace_back(loop->MakeSender<TestMessage>("/test"));
613 }
614 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); },
615 "Failed to create sender on \\{ \"name\": \"/test\", \"type\": "
616 "\"aos.TestMessage\" \\}, too many senders.");
617}
618
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700619// Verify that we can't create a sender inside OnRun.
620TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
621 auto loop1 = MakePrimary();
622
623 loop1->OnRun(
624 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
625
626 EXPECT_DEATH(Run(), "running");
627}
628
629// Verify that we can't create a watcher inside OnRun.
630TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
631 auto loop1 = MakePrimary();
632
633 loop1->OnRun(
634 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
635
636 EXPECT_DEATH(Run(), "running");
637}
638
Brian Silverman454bc112020-03-05 14:21:25 -0800639// Verify that we can't create a no-arg watcher inside OnRun.
640TEST_P(AbstractEventLoopDeathTest, NoArgWatcherInOnRun) {
641 auto loop1 = MakePrimary();
642
643 loop1->OnRun(
644 [&]() { loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {}); });
645
646 EXPECT_DEATH(Run(), "running");
647}
648
Parker Schuhe4a70d62017-12-27 20:10:20 -0800649// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800650TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
651 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700652 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800653
Austin Schuh3578a2e2019-05-25 18:17:59 -0700654 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
655 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700656 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700657 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700658 });
659
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800660 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700661
662 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700663 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
664 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
665 builder.add_value(200);
666 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700667 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800668
Austin Schuh44019f92019-05-19 19:58:27 -0700669 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800670}
671
Neil Balch229001a2018-01-07 18:22:52 -0800672// Verify that timer intervals and duration function properly.
673TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800674 // Force a slower rate so we are guarenteed to have reports for our timer.
675 FLAGS_timing_report_ms = 2000;
676
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800677 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800678
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800679 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800680 auto loop2 = Make();
681
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800682 ::std::vector<::aos::monotonic_clock::time_point> times;
683 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
684
Austin Schuh39788ff2019-12-01 18:22:57 -0800685 Fetcher<timing::Report> report_fetcher =
686 loop2->MakeFetcher<timing::Report>("/aos");
687 EXPECT_FALSE(report_fetcher.Fetch());
688
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800689 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
690 times.push_back(loop->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800691 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
692 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
693 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800694 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
695 EXPECT_EQ(loop->context().size, 0u);
696 EXPECT_EQ(loop->context().data, nullptr);
697
Austin Schuhad154822019-12-27 15:45:13 -0800698 expected_times.push_back(loop->context().monotonic_event_time);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800699 if (times.size() == kCount) {
700 this->Exit();
701 }
Neil Balch229001a2018-01-07 18:22:52 -0800702 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800703 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800704
Austin Schuh39788ff2019-12-01 18:22:57 -0800705 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700706 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800707 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
708
Austin Schuh44019f92019-05-19 19:58:27 -0700709 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800710
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800711 // Confirm that we got both the right number of samples, and it's odd.
712 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
713 EXPECT_EQ(times.size(), expected_times.size());
714 EXPECT_EQ((times.size() % 2), 1);
715
716 // Grab the middle sample.
717 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
718
719 // Add up all the delays of all the times.
720 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
721 for (const ::aos::monotonic_clock::time_point time : times) {
722 sum += time - average_time;
723 }
724
725 // Average and add to the middle to find the average time.
726 sum /= times.size();
727 average_time += sum;
728
729 // Compute the offset from the average and the expected average. It
730 // should be pretty close to 0.
731 const ::aos::monotonic_clock::duration remainder =
732 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
733
734 const chrono::milliseconds kEpsilon(100);
735 EXPECT_LT(remainder, +kEpsilon);
736 EXPECT_GT(remainder, -kEpsilon);
737
738 // Make sure that the average duration is close to 1 second.
739 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
740 times.front())
741 .count() /
742 static_cast<double>(times.size() - 1),
743 1.0, 0.1);
744
745 // Confirm that the ideal wakeup times increment correctly.
746 for (size_t i = 1; i < expected_times.size(); ++i) {
747 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
748 }
749
750 for (size_t i = 0; i < expected_times.size(); ++i) {
751 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
752 chrono::seconds(0));
753 }
754
755 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
756 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800757
758 // And, since we are here, check that the timing report makes sense.
759 // Start by looking for our event loop's timing.
760 FlatbufferDetachedBuffer<timing::Report> report =
761 FlatbufferDetachedBuffer<timing::Report>::Empty();
762 while (report_fetcher.FetchNext()) {
763 if (report_fetcher->name()->string_view() == "primary") {
764 report = CopyFlatBuffer(report_fetcher.get());
765 }
766 }
767
768 // Confirm that we have the right number of reports, and the contents are
769 // sane.
Ravago Jonescf453ab2020-05-06 21:14:53 -0700770 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -0800771
772 EXPECT_EQ(report.message().name()->string_view(), "primary");
773
774 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -0800775 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -0800776
777 ASSERT_NE(report.message().timers(), nullptr);
778 EXPECT_EQ(report.message().timers()->size(), 2);
779
780 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
781 "Test loop");
782 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
783
784 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
785 "timing_reports");
786 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
787
788 // Make sure there is a single phased loop report with our report in it.
789 ASSERT_EQ(report.message().phased_loops(), nullptr);
Neil Balch229001a2018-01-07 18:22:52 -0800790}
791
792// Verify that we can change a timer's parameters during execution.
793TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700794 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800795 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
796
797 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
798 iteration_list.push_back(loop->monotonic_now());
799 });
800
801 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
802 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
803 });
804
Neil Balch229001a2018-01-07 18:22:52 -0800805 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
806 modifier_timer->Setup(loop->monotonic_now() +
807 ::std::chrono::milliseconds(45));
808 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700809 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800810
811 EXPECT_EQ(iteration_list.size(), 7);
812}
813
814// Verify that we can disable a timer during execution.
815TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700816 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800817 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
818
819 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
820 iteration_list.push_back(loop->monotonic_now());
821 });
822
Tyler Chatow67ddb032020-01-12 14:30:04 -0800823 auto ender_timer = loop->AddTimer([&test_timer]() { test_timer->Disable(); });
Neil Balch229001a2018-01-07 18:22:52 -0800824
825 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
Tyler Chatow67ddb032020-01-12 14:30:04 -0800826 ender_timer->Setup(loop->monotonic_now() + ::std::chrono::milliseconds(45));
Neil Balch229001a2018-01-07 18:22:52 -0800827 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700828 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800829
830 EXPECT_EQ(iteration_list.size(), 3);
831}
Austin Schuh7267c532019-05-19 19:55:53 -0700832
Brian Silvermanbd405c02020-06-23 16:25:23 -0700833// Verify that we can disable a timer during execution of another timer
834// scheduled for the same time, with one ordering of creation for the timers.
835//
836// Also schedule some more events to reshuffle the heap in EventLoop used for
837// tracking events to change up the order. This used to segfault
838// SimulatedEventLoop.
839TEST_P(AbstractEventLoopTest, TimerDisableOther) {
840 for (bool creation_order : {true, false}) {
841 for (bool setup_order : {true, false}) {
842 for (int shuffle_events = 0; shuffle_events < 5; ++shuffle_events) {
843 auto loop = MakePrimary();
844 aos::TimerHandler *test_timer, *ender_timer;
845 if (creation_order) {
846 test_timer = loop->AddTimer([]() {});
847 ender_timer =
848 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
849 } else {
850 ender_timer =
851 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
852 test_timer = loop->AddTimer([]() {});
853 }
854
855 const auto start = loop->monotonic_now();
856
857 for (int i = 0; i < shuffle_events; ++i) {
858 loop->AddTimer([]() {})->Setup(start + std::chrono::milliseconds(10));
859 }
860
861 if (setup_order) {
862 test_timer->Setup(start + ::std::chrono::milliseconds(20));
863 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
864 } else {
865 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
866 test_timer->Setup(start + ::std::chrono::milliseconds(20));
867 }
868 EndEventLoop(loop.get(), ::std::chrono::milliseconds(40));
869 Run();
870 }
871 }
872 }
873}
874
Austin Schuh54cf95f2019-11-29 13:14:18 -0800875// Verifies that the event loop implementations detect when Channel is not a
876// pointer into confguration()
877TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
878 auto loop = MakePrimary();
879
Tyler Chatow67ddb032020-01-12 14:30:04 -0800880 const Channel *channel = configuration::GetChannel(
881 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
Austin Schuh54cf95f2019-11-29 13:14:18 -0800882
883 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
884
885 EXPECT_DEATH(
886 { loop->MakeRawSender(&channel_copy.message()); },
887 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
888
889 EXPECT_DEATH(
890 { loop->MakeRawFetcher(&channel_copy.message()); },
891 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
892
893 EXPECT_DEATH(
894 {
895 loop->MakeRawWatcher(&channel_copy.message(),
896 [](const Context, const void *) {});
897 },
898 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
899}
900
Brian Silverman454bc112020-03-05 14:21:25 -0800901// Verify that the send time on a message is roughly right when using a watcher.
Austin Schuh7267c532019-05-19 19:55:53 -0700902TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700903 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700904 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -0800905 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -0700906 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
907
908 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700909 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
910 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
911 builder.add_value(200);
912 ASSERT_TRUE(msg.Send(builder.Finish()));
913 });
914
Austin Schuhad154822019-12-27 15:45:13 -0800915 bool triggered = false;
Brian Silverman454bc112020-03-05 14:21:25 -0800916 loop1->MakeWatcher("/test", [&](const TestMessage &msg) {
Austin Schuhad154822019-12-27 15:45:13 -0800917 // Confirm that the data pointer makes sense from a watcher, and all the
918 // timestamps look right.
919 EXPECT_GT(&msg, loop1->context().data);
920 EXPECT_EQ(loop1->context().monotonic_remote_time,
921 loop1->context().monotonic_event_time);
922 EXPECT_EQ(loop1->context().realtime_remote_time,
923 loop1->context().realtime_event_time);
924
925 const aos::monotonic_clock::time_point monotonic_now =
926 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -0800927 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -0800928
929 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
930 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
931 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
932 monotonic_now);
933 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
934 realtime_now);
935
Alex Perrycb7da4b2019-08-28 19:35:56 -0700936 EXPECT_LT(&msg, reinterpret_cast<void *>(
Austin Schuhad154822019-12-27 15:45:13 -0800937 reinterpret_cast<char *>(loop1->context().data) +
938 loop1->context().size));
939 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -0700940 });
941
942 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
943
944 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700945 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700946
Austin Schuhad154822019-12-27 15:45:13 -0800947 EXPECT_TRUE(triggered);
948
Brian Silverman454bc112020-03-05 14:21:25 -0800949 ASSERT_TRUE(fetcher.Fetch());
950
951 monotonic_clock::duration monotonic_time_offset =
952 fetcher.context().monotonic_event_time -
953 (loop1->monotonic_now() - ::std::chrono::seconds(1));
954 realtime_clock::duration realtime_time_offset =
955 fetcher.context().realtime_event_time -
956 (loop1->realtime_now() - ::std::chrono::seconds(1));
957
958 EXPECT_EQ(fetcher.context().realtime_event_time,
959 fetcher.context().realtime_remote_time);
960 EXPECT_EQ(fetcher.context().monotonic_event_time,
961 fetcher.context().monotonic_remote_time);
962
963 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
964 << ": Got "
965 << fetcher.context().monotonic_event_time.time_since_epoch().count()
966 << " expected " << loop1->monotonic_now().time_since_epoch().count();
967 // Confirm that the data pointer makes sense.
968 EXPECT_GT(fetcher.get(), fetcher.context().data);
969 EXPECT_LT(fetcher.get(),
970 reinterpret_cast<void *>(
971 reinterpret_cast<char *>(fetcher.context().data) +
972 fetcher.context().size));
973 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
974 << ": Got "
975 << fetcher.context().monotonic_event_time.time_since_epoch().count()
976 << " expected " << loop1->monotonic_now().time_since_epoch().count();
977
978 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
979 << ": Got "
980 << fetcher.context().realtime_event_time.time_since_epoch().count()
981 << " expected " << loop1->realtime_now().time_since_epoch().count();
982 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
983 << ": Got "
984 << fetcher.context().realtime_event_time.time_since_epoch().count()
985 << " expected " << loop1->realtime_now().time_since_epoch().count();
986}
987
988// Verify that the send time on a message is roughly right when using a no-arg
989// watcher. To get a message, we need to use a fetcher to actually access the
990// message. This is also the main use case for no-arg fetchers.
991TEST_P(AbstractEventLoopTest, MessageSendTimeNoArg) {
992 auto loop1 = MakePrimary();
993 auto loop2 = Make();
994 auto sender = loop2->MakeSender<TestMessage>("/test");
995 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
996
997 auto test_timer = loop1->AddTimer([&sender]() {
998 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
999 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1000 builder.add_value(200);
1001 ASSERT_TRUE(msg.Send(builder.Finish()));
1002 });
1003
1004 bool triggered = false;
1005 loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {
1006 // Confirm that we can indeed use a fetcher on this channel from this
1007 // context, and it results in a sane data pointer and timestamps.
1008 ASSERT_TRUE(fetcher.Fetch());
1009
1010 EXPECT_EQ(loop1->context().monotonic_remote_time,
1011 loop1->context().monotonic_event_time);
1012 EXPECT_EQ(loop1->context().realtime_remote_time,
1013 loop1->context().realtime_event_time);
1014
1015 const aos::monotonic_clock::time_point monotonic_now =
1016 loop1->monotonic_now();
1017 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
1018
1019 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1020 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1021 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1022 monotonic_now);
1023 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1024 realtime_now);
1025
1026 triggered = true;
1027 });
1028
1029 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1030
1031 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
1032 Run();
1033
1034 ASSERT_TRUE(triggered);
Austin Schuh7267c532019-05-19 19:55:53 -07001035
Alex Perrycb7da4b2019-08-28 19:35:56 -07001036 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001037 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001038 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1039 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001040 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001041 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -07001042
Austin Schuhad154822019-12-27 15:45:13 -08001043 EXPECT_EQ(fetcher.context().realtime_event_time,
1044 fetcher.context().realtime_remote_time);
1045 EXPECT_EQ(fetcher.context().monotonic_event_time,
1046 fetcher.context().monotonic_remote_time);
1047
Alex Perrycb7da4b2019-08-28 19:35:56 -07001048 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1049 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001050 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -07001051 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001052 // Confirm that the data pointer makes sense.
1053 EXPECT_GT(fetcher.get(), fetcher.context().data);
1054 EXPECT_LT(fetcher.get(),
1055 reinterpret_cast<void *>(
1056 reinterpret_cast<char *>(fetcher.context().data) +
1057 fetcher.context().size));
1058 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1059 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001060 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -07001061 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001062
1063 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1064 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001065 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001066 << " expected " << loop1->realtime_now().time_since_epoch().count();
1067 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1068 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001069 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001070 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -07001071}
1072
Austin Schuh52d325c2019-06-23 18:59:06 -07001073// Tests that a couple phased loops run in a row result in the correct offset
1074// and period.
1075TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -08001076 // Force a slower rate so we are guarenteed to have reports for our phased
1077 // loop.
1078 FLAGS_timing_report_ms = 2000;
1079
Austin Schuh52d325c2019-06-23 18:59:06 -07001080 const chrono::milliseconds kOffset = chrono::milliseconds(400);
1081 const int kCount = 5;
1082
1083 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -08001084 auto loop2 = Make();
1085
1086 Fetcher<timing::Report> report_fetcher =
1087 loop2->MakeFetcher<timing::Report>("/aos");
1088 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001089
1090 // Collect up a couple of samples.
1091 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001092 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -07001093
1094 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -08001095 loop1
1096 ->AddPhasedLoop(
1097 [&times, &expected_times, &loop1, this](int count) {
1098 EXPECT_EQ(count, 1);
1099 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -08001100 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -08001101
Austin Schuhad154822019-12-27 15:45:13 -08001102 EXPECT_EQ(loop1->context().monotonic_remote_time,
1103 monotonic_clock::min_time);
1104 EXPECT_EQ(loop1->context().realtime_event_time,
1105 realtime_clock::min_time);
1106 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -08001107 realtime_clock::min_time);
1108 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
1109 EXPECT_EQ(loop1->context().size, 0u);
1110 EXPECT_EQ(loop1->context().data, nullptr);
1111
1112 if (times.size() == kCount) {
1113 LOG(INFO) << "Exiting";
1114 this->Exit();
1115 }
1116 },
1117 chrono::seconds(1), kOffset)
1118 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -07001119
1120 // Add a delay to make sure that delay during startup doesn't result in a
1121 // "missed cycle".
1122 SleepFor(chrono::seconds(2));
1123
1124 Run();
1125
1126 // Confirm that we got both the right number of samples, and it's odd.
1127 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001128 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -07001129 EXPECT_EQ((times.size() % 2), 1);
1130
1131 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001132 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -07001133
1134 // Add up all the delays of all the times.
1135 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1136 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001137 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -07001138 }
1139
1140 // Average and add to the middle to find the average time.
1141 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001142 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -07001143
1144 // Compute the offset from the start of the second of the average time. This
1145 // should be pretty close to the offset.
1146 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001147 average_time.time_since_epoch() -
1148 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001149
1150 const chrono::milliseconds kEpsilon(100);
1151 EXPECT_LT(remainder, kOffset + kEpsilon);
1152 EXPECT_GT(remainder, kOffset - kEpsilon);
1153
1154 // Make sure that the average duration is close to 1 second.
1155 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1156 times.front())
1157 .count() /
1158 static_cast<double>(times.size() - 1),
1159 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001160
1161 // Confirm that the ideal wakeup times increment correctly.
1162 for (size_t i = 1; i < expected_times.size(); ++i) {
1163 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1164 }
1165
1166 for (size_t i = 0; i < expected_times.size(); ++i) {
1167 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1168 kOffset);
1169 }
1170
1171 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1172 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001173
1174 // And, since we are here, check that the timing report makes sense.
1175 // Start by looking for our event loop's timing.
1176 FlatbufferDetachedBuffer<timing::Report> report =
1177 FlatbufferDetachedBuffer<timing::Report>::Empty();
1178 while (report_fetcher.FetchNext()) {
1179 if (report_fetcher->name()->string_view() == "primary") {
1180 report = CopyFlatBuffer(report_fetcher.get());
1181 }
1182 }
1183
Ravago Jonescf453ab2020-05-06 21:14:53 -07001184 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001185
1186 EXPECT_EQ(report.message().name()->string_view(), "primary");
1187
1188 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001189 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001190
1191 ASSERT_NE(report.message().timers(), nullptr);
1192 EXPECT_EQ(report.message().timers()->size(), 1);
1193
1194 // Make sure there is a single phased loop report with our report in it.
1195 ASSERT_NE(report.message().phased_loops(), nullptr);
1196 ASSERT_EQ(report.message().phased_loops()->size(), 1);
1197 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
1198 "Test loop");
1199 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
1200}
1201
1202// Tests that senders count correctly in the timing report.
1203TEST_P(AbstractEventLoopTest, SenderTimingReport) {
1204 FLAGS_timing_report_ms = 1000;
1205 auto loop1 = MakePrimary();
1206
1207 auto loop2 = Make("watcher_loop");
1208 loop2->MakeWatcher("/test", [](const TestMessage &) {});
1209
1210 auto loop3 = Make();
1211
1212 Fetcher<timing::Report> report_fetcher =
1213 loop3->MakeFetcher<timing::Report>("/aos");
1214 EXPECT_FALSE(report_fetcher.Fetch());
1215
1216 auto sender = loop1->MakeSender<TestMessage>("/test");
1217
1218 // Add a timer to actually quit.
1219 auto test_timer = loop1->AddTimer([&sender]() {
1220 for (int i = 0; i < 10; ++i) {
1221 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1222 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1223 builder.add_value(200 + i);
1224 ASSERT_TRUE(msg.Send(builder.Finish()));
1225 }
1226 });
1227
1228 // Quit after 1 timing report, mid way through the next cycle.
1229 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1230
1231 loop1->OnRun([&test_timer, &loop1]() {
1232 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1233 });
1234
1235 Run();
1236
1237 // And, since we are here, check that the timing report makes sense.
1238 // Start by looking for our event loop's timing.
1239 FlatbufferDetachedBuffer<timing::Report> primary_report =
1240 FlatbufferDetachedBuffer<timing::Report>::Empty();
1241 while (report_fetcher.FetchNext()) {
1242 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1243 if (report_fetcher->name()->string_view() == "primary") {
1244 primary_report = CopyFlatBuffer(report_fetcher.get());
1245 }
1246 }
1247
Ravago Jonescf453ab2020-05-06 21:14:53 -07001248 LOG(INFO) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001249
1250 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1251
1252 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001253 EXPECT_EQ(primary_report.message().senders()->size(), 3);
Austin Schuh39788ff2019-12-01 18:22:57 -08001254
1255 // Confirm that the sender looks sane.
1256 EXPECT_EQ(
1257 loop1->configuration()
1258 ->channels()
1259 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1260 ->name()
1261 ->string_view(),
1262 "/test");
1263 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1264
1265 // Confirm that the timing primary_report sender looks sane.
1266 EXPECT_EQ(
1267 loop1->configuration()
1268 ->channels()
1269 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1270 ->name()
1271 ->string_view(),
1272 "/aos");
1273 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1274
1275 ASSERT_NE(primary_report.message().timers(), nullptr);
1276 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1277
1278 // Make sure there are no phased loops or watchers.
1279 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1280 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1281}
1282
1283// Tests that senders count correctly in the timing report.
1284TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1285 FLAGS_timing_report_ms = 1000;
1286 auto loop1 = MakePrimary();
1287 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1288
1289 auto loop2 = Make("sender_loop");
1290
1291 auto loop3 = Make();
1292
1293 Fetcher<timing::Report> report_fetcher =
1294 loop3->MakeFetcher<timing::Report>("/aos");
1295 EXPECT_FALSE(report_fetcher.Fetch());
1296
1297 auto sender = loop2->MakeSender<TestMessage>("/test");
1298
1299 // Add a timer to actually quit.
1300 auto test_timer = loop1->AddTimer([&sender]() {
1301 for (int i = 0; i < 10; ++i) {
1302 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1303 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1304 builder.add_value(200 + i);
1305 ASSERT_TRUE(msg.Send(builder.Finish()));
1306 }
1307 });
1308
1309 // Quit after 1 timing report, mid way through the next cycle.
1310 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1311
1312 loop1->OnRun([&test_timer, &loop1]() {
1313 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1314 });
1315
1316 Run();
1317
1318 // And, since we are here, check that the timing report makes sense.
1319 // Start by looking for our event loop's timing.
1320 FlatbufferDetachedBuffer<timing::Report> primary_report =
1321 FlatbufferDetachedBuffer<timing::Report>::Empty();
1322 while (report_fetcher.FetchNext()) {
1323 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1324 if (report_fetcher->name()->string_view() == "primary") {
1325 primary_report = CopyFlatBuffer(report_fetcher.get());
1326 }
1327 }
1328
1329 // Check the watcher report.
Ravago Jonescf453ab2020-05-06 21:14:53 -07001330 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001331
1332 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1333
1334 // Just the timing report timer.
1335 ASSERT_NE(primary_report.message().timers(), nullptr);
1336 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1337
1338 // No phased loops
1339 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1340
1341 ASSERT_NE(primary_report.message().watchers(), nullptr);
1342 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1343 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1344}
1345
1346// Tests that fetchers count correctly in the timing report.
1347TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1348 FLAGS_timing_report_ms = 1000;
1349 auto loop1 = MakePrimary();
1350 auto loop2 = Make("sender_loop");
1351
1352 auto loop3 = Make();
1353
1354 Fetcher<timing::Report> report_fetcher =
1355 loop3->MakeFetcher<timing::Report>("/aos");
1356 EXPECT_FALSE(report_fetcher.Fetch());
1357
1358 auto sender = loop2->MakeSender<TestMessage>("/test");
1359 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1360 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1361 fetcher1.Fetch();
1362 fetcher2.Fetch();
1363
1364 // Add a timer to actually quit.
1365 auto test_timer = loop1->AddTimer([&sender]() {
1366 for (int i = 0; i < 10; ++i) {
1367 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1368 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1369 builder.add_value(200 + i);
1370 ASSERT_TRUE(msg.Send(builder.Finish()));
1371 }
1372 });
1373
1374 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1375 fetcher1.Fetch();
1376 while (fetcher2.FetchNext()) {
1377 }
1378 });
1379
1380 // Quit after 1 timing report, mid way through the next cycle.
1381 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1382
1383 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1384 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1385 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1386 });
1387
1388 Run();
1389
1390 // And, since we are here, check that the timing report makes sense.
1391 // Start by looking for our event loop's timing.
1392 FlatbufferDetachedBuffer<timing::Report> primary_report =
1393 FlatbufferDetachedBuffer<timing::Report>::Empty();
1394 while (report_fetcher.FetchNext()) {
1395 if (report_fetcher->name()->string_view() == "primary") {
1396 primary_report = CopyFlatBuffer(report_fetcher.get());
1397 }
1398 }
1399
Ravago Jonescf453ab2020-05-06 21:14:53 -07001400 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001401
1402 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1403
1404 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001405 EXPECT_EQ(primary_report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001406
1407 ASSERT_NE(primary_report.message().timers(), nullptr);
1408 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1409
1410 // Make sure there are no phased loops or watchers.
1411 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1412 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1413
1414 // Now look at the fetchrs.
1415 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1416 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1417
1418 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1419 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1420 0.1);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001421 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(), 0.1);
1422 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(), 0.1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001423 EXPECT_EQ(primary_report.message()
1424 .fetchers()
1425 ->Get(0)
1426 ->latency()
1427 ->standard_deviation(),
1428 0.0);
1429
1430 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001431}
1432
Austin Schuh67420a42019-12-21 21:55:04 -08001433// Tests that a raw watcher and raw fetcher can receive messages from a raw
1434// sender without messing up offsets.
1435TEST_P(AbstractEventLoopTest, RawBasic) {
1436 auto loop1 = Make();
1437 auto loop2 = MakePrimary();
1438 auto loop3 = Make();
1439
1440 const std::string kData("971 is the best");
1441
1442 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001443 loop1->MakeRawSender(configuration::GetChannel(
1444 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001445
1446 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001447 loop3->MakeRawFetcher(configuration::GetChannel(
1448 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001449
1450 loop2->OnRun(
1451 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1452
1453 bool happened = false;
1454 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001455 configuration::GetChannel(loop2->configuration(), "/test",
1456 "aos.TestMessage", "", nullptr),
Austin Schuh67420a42019-12-21 21:55:04 -08001457 [this, &kData, &fetcher, &happened](const Context &context,
1458 const void *message) {
1459 happened = true;
1460 EXPECT_EQ(std::string_view(kData),
1461 std::string_view(reinterpret_cast<const char *>(message),
1462 context.size));
1463 EXPECT_EQ(std::string_view(kData),
1464 std::string_view(reinterpret_cast<const char *>(context.data),
1465 context.size));
1466
1467 ASSERT_TRUE(fetcher->Fetch());
1468
1469 EXPECT_EQ(std::string_view(kData),
1470 std::string_view(
1471 reinterpret_cast<const char *>(fetcher->context().data),
1472 fetcher->context().size));
1473
1474 this->Exit();
1475 });
1476
1477 EXPECT_FALSE(happened);
1478 Run();
1479 EXPECT_TRUE(happened);
1480}
1481
Austin Schuhad154822019-12-27 15:45:13 -08001482// Tests that a raw watcher and raw fetcher can receive messages from a raw
1483// sender with remote times filled out.
1484TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1485 auto loop1 = Make();
1486 auto loop2 = MakePrimary();
1487 auto loop3 = Make();
1488
1489 const std::string kData("971 is the best");
1490
1491 const aos::monotonic_clock::time_point monotonic_remote_time =
1492 aos::monotonic_clock::time_point(chrono::seconds(1501));
1493 const aos::realtime_clock::time_point realtime_remote_time =
1494 aos::realtime_clock::time_point(chrono::seconds(3132));
1495
1496 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001497 loop1->MakeRawSender(configuration::GetChannel(
1498 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001499
1500 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001501 loop3->MakeRawFetcher(configuration::GetChannel(
1502 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001503
1504 loop2->OnRun([&]() {
1505 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1506 realtime_remote_time));
1507 });
1508
1509 bool happened = false;
1510 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001511 configuration::GetChannel(loop2->configuration(), "/test",
1512 "aos.TestMessage", "", nullptr),
Austin Schuhad154822019-12-27 15:45:13 -08001513 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1514 const Context &context, const void * /*message*/) {
1515 happened = true;
1516 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1517 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1518
1519 ASSERT_TRUE(fetcher->Fetch());
1520 EXPECT_EQ(monotonic_remote_time,
1521 fetcher->context().monotonic_remote_time);
1522 EXPECT_EQ(realtime_remote_time,
1523 fetcher->context().realtime_remote_time);
1524
1525 this->Exit();
1526 });
1527
1528 EXPECT_FALSE(happened);
1529 Run();
1530 EXPECT_TRUE(happened);
1531}
1532
1533// Tests that a raw sender fills out sent data.
1534TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1535 auto loop1 = MakePrimary();
1536
1537 const std::string kData("971 is the best");
1538
1539 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001540 loop1->MakeRawSender(configuration::GetChannel(
1541 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001542
Tyler Chatow67ddb032020-01-12 14:30:04 -08001543 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
1544 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001545
1546 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1547
1548 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1549 EXPECT_LE(sender->monotonic_sent_time(),
1550 monotonic_now + chrono::milliseconds(100));
1551 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1552 EXPECT_LE(sender->realtime_sent_time(),
1553 realtime_now + chrono::milliseconds(100));
1554 EXPECT_EQ(sender->sent_queue_index(), 0u);
1555
1556 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1557
1558 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1559 EXPECT_LE(sender->monotonic_sent_time(),
1560 monotonic_now + chrono::milliseconds(100));
1561 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1562 EXPECT_LE(sender->realtime_sent_time(),
1563 realtime_now + chrono::milliseconds(100));
1564 EXPECT_EQ(sender->sent_queue_index(), 1u);
1565}
1566
Austin Schuh217a9782019-12-21 23:02:50 -08001567// Tests that not setting up nodes results in no node.
1568TEST_P(AbstractEventLoopTest, NoNode) {
1569 auto loop1 = Make();
1570 auto loop2 = MakePrimary();
1571
1572 EXPECT_EQ(loop1->node(), nullptr);
1573 EXPECT_EQ(loop2->node(), nullptr);
1574}
1575
1576// Tests that setting up nodes results in node being set.
1577TEST_P(AbstractEventLoopTest, Node) {
1578 EnableNodes("me");
1579
1580 auto loop1 = Make();
1581 auto loop2 = MakePrimary();
1582
1583 EXPECT_NE(loop1->node(), nullptr);
1584 EXPECT_NE(loop2->node(), nullptr);
1585}
1586
1587// Tests that watchers work with a node setup.
1588TEST_P(AbstractEventLoopTest, NodeWatcher) {
1589 EnableNodes("me");
1590
1591 auto loop1 = Make();
1592 auto loop2 = Make();
1593 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08001594 loop2->MakeRawWatcher(
1595 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1596 nullptr),
1597 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001598}
1599
Brian Silverman454bc112020-03-05 14:21:25 -08001600// Tests that no-arg watchers work with a node setup.
1601TEST_P(AbstractEventLoopTest, NodeNoArgWatcher) {
1602 EnableNodes("me");
1603
1604 auto loop1 = Make();
1605 auto loop2 = Make();
1606 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1607 loop2->MakeRawNoArgWatcher(
1608 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1609 nullptr),
1610 [](const Context &) {});
1611}
1612
Austin Schuh217a9782019-12-21 23:02:50 -08001613// Tests that fetcher work with a node setup.
1614TEST_P(AbstractEventLoopTest, NodeFetcher) {
1615 EnableNodes("me");
1616 auto loop1 = Make();
1617
1618 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08001619 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1620 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001621}
1622
1623// Tests that sender work with a node setup.
1624TEST_P(AbstractEventLoopTest, NodeSender) {
1625 EnableNodes("me");
1626 auto loop1 = Make();
1627
1628 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1629}
1630
1631// Tests that watchers fail when created on the wrong node.
1632TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
1633 EnableNodes("them");
1634
1635 auto loop1 = Make();
1636 auto loop2 = Make();
1637 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
1638 "node");
1639 EXPECT_DEATH(
1640 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001641 loop2->MakeRawWatcher(
1642 configuration::GetChannel(configuration(), "/test",
1643 "aos.TestMessage", "", nullptr),
1644 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001645 },
1646 "node");
Brian Silverman454bc112020-03-05 14:21:25 -08001647 EXPECT_DEATH({ loop1->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1648 "node");
1649 EXPECT_DEATH(
1650 {
1651 loop2->MakeRawNoArgWatcher(
1652 configuration::GetChannel(configuration(), "/test",
1653 "aos.TestMessage", "", nullptr),
1654 [](const Context &) {});
1655 },
1656 "node");
Austin Schuh217a9782019-12-21 23:02:50 -08001657}
1658
1659// Tests that fetchers fail when created on the wrong node.
1660TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
1661 EnableNodes("them");
1662 auto loop1 = Make();
1663
1664 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
1665 "node");
1666 EXPECT_DEATH(
1667 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001668 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1669 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001670 },
1671 "node");
1672}
1673
1674// Tests that senders fail when created on the wrong node.
1675TEST_P(AbstractEventLoopDeathTest, NodeSender) {
1676 EnableNodes("them");
1677 auto loop1 = Make();
1678
1679 EXPECT_DEATH(
1680 {
1681 aos::Sender<TestMessage> sender =
1682 loop1->MakeSender<TestMessage>("/test");
1683 },
1684 "node");
1685
1686 // Note: Creating raw senders is always supported. Right now, this lets us
1687 // use them to create message_gateway.
1688}
1689
Parker Schuhe4a70d62017-12-27 20:10:20 -08001690} // namespace testing
1691} // namespace aos