blob: 606849a291fa129a6d57ecaac6fd4823502ebe61 [file] [log] [blame]
Alex Perrycb7da4b2019-08-28 19:35:56 -07001#include "aos/events/event_loop_param_test.h"
Parker Schuhe4a70d62017-12-27 20:10:20 -08002
Austin Schuh52d325c2019-06-23 18:59:06 -07003#include <chrono>
4
Alex Perrycb7da4b2019-08-28 19:35:56 -07005#include "aos/events/test_message_generated.h"
Austin Schuh54cf95f2019-11-29 13:14:18 -08006#include "aos/flatbuffer_merge.h"
7#include "glog/logging.h"
Tyler Chatow67ddb032020-01-12 14:30:04 -08008#include "gmock/gmock.h"
9#include "gtest/gtest.h"
Austin Schuh9fe68f72019-08-10 19:32:03 -070010
Parker Schuhe4a70d62017-12-27 20:10:20 -080011namespace aos {
12namespace testing {
Austin Schuh52d325c2019-06-23 18:59:06 -070013namespace {
14namespace chrono = ::std::chrono;
15} // namespace
Parker Schuhe4a70d62017-12-27 20:10:20 -080016
Austin Schuh6b6dfa52019-06-12 20:16:20 -070017// Tests that watcher can receive messages from a sender.
Parker Schuhe4a70d62017-12-27 20:10:20 -080018// Also tests that OnRun() works.
19TEST_P(AbstractEventLoopTest, Basic) {
20 auto loop1 = Make();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070021 auto loop2 = MakePrimary();
22
Alex Perrycb7da4b2019-08-28 19:35:56 -070023 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
Austin Schuh6b6dfa52019-06-12 20:16:20 -070024
25 bool happened = false;
26
27 loop2->OnRun([&]() {
28 happened = true;
29
Alex Perrycb7da4b2019-08-28 19:35:56 -070030 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
31 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
32 builder.add_value(200);
33 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -070034 });
35
36 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070037 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -070038 this->Exit();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070039 });
40
41 EXPECT_FALSE(happened);
42 Run();
43 EXPECT_TRUE(happened);
44}
45
Brian Silverman341b57e2020-06-23 16:23:18 -070046// Tests that watcher can receive messages from a sender, sent via SendDetached.
47TEST_P(AbstractEventLoopTest, BasicSendDetached) {
48 auto loop1 = Make();
49 auto loop2 = MakePrimary();
50
51 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
52
53 FlatbufferDetachedBuffer<TestMessage> detached =
54 flatbuffers::DetachedBuffer();
55 {
56 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
57 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
58 builder.add_value(100);
59 detached = msg.Detach(builder.Finish());
60 }
61 detached = flatbuffers::DetachedBuffer();
62 {
63 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
64 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
65 builder.add_value(200);
66 detached = msg.Detach(builder.Finish());
67 }
68 ASSERT_TRUE(sender.SendDetached(std::move(detached)));
69
70 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
71 ASSERT_TRUE(fetcher.Fetch());
72 EXPECT_EQ(fetcher->value(), 200);
73}
74
Brian Silverman6b8a3c32020-03-06 11:26:14 -080075// Verifies that a no-arg watcher will not have a data pointer.
76TEST_P(AbstractEventLoopTest, NoArgNoData) {
77 auto loop1 = Make();
78 auto loop2 = MakePrimary();
79
80 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
81
82 bool happened = false;
83
84 loop2->OnRun([&]() {
85 happened = true;
86
87 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
88 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
89 ASSERT_TRUE(msg.Send(builder.Finish()));
90 });
91
92 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
93 EXPECT_GT(loop2->context().size, 0u);
94 EXPECT_EQ(nullptr, loop2->context().data);
95 this->Exit();
96 });
97
98 EXPECT_FALSE(happened);
99 Run();
100 EXPECT_TRUE(happened);
101}
102
Brian Silverman454bc112020-03-05 14:21:25 -0800103// Tests that no-arg watcher can receive messages from a sender.
104// Also tests that OnRun() works.
105TEST_P(AbstractEventLoopTest, BasicNoArg) {
106 auto loop1 = Make();
107 auto loop2 = MakePrimary();
108
109 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
110
111 bool happened = false;
112
113 loop2->OnRun([&]() {
114 happened = true;
115
116 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
117 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
118 builder.add_value(200);
119 ASSERT_TRUE(msg.Send(builder.Finish()));
120 });
121
122 aos::Fetcher<TestMessage> fetcher = loop2->MakeFetcher<TestMessage>("/test");
123 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
124 ASSERT_TRUE(fetcher.Fetch());
125 EXPECT_EQ(fetcher->value(), 200);
126 this->Exit();
127 });
128
129 EXPECT_FALSE(happened);
130 Run();
131 EXPECT_TRUE(happened);
132}
133
134// Tests that a watcher can be created with an std::function.
135TEST_P(AbstractEventLoopTest, BasicFunction) {
136 auto loop1 = Make();
137 auto loop2 = MakePrimary();
138
139 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
140
141 bool happened = false;
142
143 loop2->OnRun([&]() {
144 happened = true;
145
146 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
147 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
148 builder.add_value(200);
149 ASSERT_TRUE(msg.Send(builder.Finish()));
150 });
151
152 loop2->MakeWatcher("/test", std::function<void(const TestMessage &)>(
153 [&](const TestMessage &message) {
154 EXPECT_EQ(message.value(), 200);
155 this->Exit();
156 }));
157
158 EXPECT_FALSE(happened);
159 Run();
160 EXPECT_TRUE(happened);
161}
162
Brian Silverman0fc69932020-01-24 21:54:02 -0800163// Tests that watcher can receive messages from two senders.
164// Also tests that OnRun() works.
165TEST_P(AbstractEventLoopTest, BasicTwoSenders) {
166 auto loop1 = Make();
167 auto loop2 = MakePrimary();
168
169 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
170 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
171
172 bool happened = false;
173
174 loop2->OnRun([&]() {
175 happened = true;
176
177 {
178 aos::Sender<TestMessage>::Builder msg = sender1.MakeBuilder();
179 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
180 builder.add_value(200);
181 ASSERT_TRUE(msg.Send(builder.Finish()));
182 }
183 {
184 aos::Sender<TestMessage>::Builder msg = sender2.MakeBuilder();
185 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
186 builder.add_value(200);
187 ASSERT_TRUE(msg.Send(builder.Finish()));
188 }
189 });
190
191 int messages_received = 0;
192 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
193 EXPECT_EQ(message.value(), 200);
194 this->Exit();
195 ++messages_received;
196 });
197
198 EXPECT_FALSE(happened);
199 Run();
200 EXPECT_TRUE(happened);
201 EXPECT_EQ(messages_received, 2);
202}
203
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700204// Tests that a fetcher can fetch from a sender.
205// Also tests that OnRun() works.
206TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
207 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800208 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700209 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800210
211 auto sender = loop1->MakeSender<TestMessage>("/test");
212
213 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
214
Austin Schuhbbce72d2019-05-26 15:11:46 -0700215 EXPECT_FALSE(fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -0800216 EXPECT_EQ(fetcher.get(), nullptr);
217
Austin Schuhad154822019-12-27 15:45:13 -0800218 EXPECT_EQ(fetcher.context().monotonic_event_time, monotonic_clock::min_time);
219 EXPECT_EQ(fetcher.context().monotonic_remote_time, monotonic_clock::min_time);
220 EXPECT_EQ(fetcher.context().realtime_event_time, realtime_clock::min_time);
221 EXPECT_EQ(fetcher.context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800222 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
223 EXPECT_EQ(fetcher.context().size, 0u);
224 EXPECT_EQ(fetcher.context().data, nullptr);
Austin Schuhbbce72d2019-05-26 15:11:46 -0700225
Alex Perrycb7da4b2019-08-28 19:35:56 -0700226 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
227 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
228 builder.add_value(200);
229 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700230
231 EXPECT_TRUE(fetcher.Fetch());
232 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700233 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -0800234
235 const chrono::milliseconds kEpsilon(100);
236
Austin Schuhad154822019-12-27 15:45:13 -0800237 const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
238 const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
239 EXPECT_EQ(fetcher.context().monotonic_event_time,
240 fetcher.context().monotonic_remote_time);
241 EXPECT_EQ(fetcher.context().realtime_event_time,
242 fetcher.context().realtime_remote_time);
243
244 EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
245 EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
246 EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
247 EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800248 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
249 EXPECT_EQ(fetcher.context().size, 20u);
250 EXPECT_NE(fetcher.context().data, nullptr);
Parker Schuhe4a70d62017-12-27 20:10:20 -0800251}
252
Austin Schuh3578a2e2019-05-25 18:17:59 -0700253// Tests that watcher will receive all messages sent if they are sent after
254// initialization and before running.
255TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
256 auto loop1 = Make();
257 auto loop2 = MakePrimary();
258
259 auto sender = loop1->MakeSender<TestMessage>("/test");
260
261 ::std::vector<int> values;
262
263 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700264 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700265 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700266 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700267 }
268 });
269
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700270 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -0700271 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700272 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
273 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
274 builder.add_value(199);
275 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700276 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700277
278 loop2->OnRun([&]() {
279 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700280 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
281 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
282 builder.add_value(200);
283 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700284 }
285 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700286 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
287 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
288 builder.add_value(201);
289 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700290 }
291 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700292
293 Run();
294
295 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
296}
297
298// Tests that watcher will not receive messages sent before the watcher is
299// created.
300TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
301 auto loop1 = Make();
302 auto loop2 = MakePrimary();
303
304 auto sender = loop1->MakeSender<TestMessage>("/test");
305
306 ::std::vector<int> values;
307
308 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700309 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
310 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
311 builder.add_value(200);
312 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700313 }
314 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700315 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
316 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
317 builder.add_value(201);
318 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700319 }
320
321 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700322 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700323 });
324
325 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700326 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700327 loop2->OnRun([&test_timer, &loop2]() {
328 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
329 });
330
331 Run();
332 EXPECT_EQ(0, values.size());
333}
334
Austin Schuhbbce72d2019-05-26 15:11:46 -0700335// Tests that FetchNext gets all the messages sent after it is constructed.
336TEST_P(AbstractEventLoopTest, FetchNext) {
337 auto loop1 = Make();
338 auto loop2 = MakePrimary();
339
340 auto sender = loop1->MakeSender<TestMessage>("/test");
341 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
342
343 ::std::vector<int> values;
344
345 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700346 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
347 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
348 builder.add_value(200);
349 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700350 }
351 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700352 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
353 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
354 builder.add_value(201);
355 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700356 }
357
358 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700359 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700360 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700361 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700362 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700363 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700364 });
365
366 loop2->OnRun([&test_timer, &loop2]() {
367 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
368 });
369
370 Run();
371 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
372}
373
374// Tests that FetchNext gets no messages sent before it is constructed.
375TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
376 auto loop1 = Make();
377 auto loop2 = MakePrimary();
378
379 auto sender = loop1->MakeSender<TestMessage>("/test");
380
381 ::std::vector<int> values;
382
383 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700384 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
385 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
386 builder.add_value(200);
387 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700388 }
389 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700390 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
391 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
392 builder.add_value(201);
393 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700394 }
395
396 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
397
398 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700399 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700400 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700401 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700402 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700403 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700404 });
405
406 loop2->OnRun([&test_timer, &loop2]() {
407 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
408 });
409
410 Run();
411 EXPECT_THAT(0, values.size());
412}
413
414// Tests that Fetch returns the last message created before the loop was
415// started.
416TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
417 auto loop1 = Make();
418 auto loop2 = MakePrimary();
419
420 auto sender = loop1->MakeSender<TestMessage>("/test");
421
422 ::std::vector<int> values;
423
424 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700425 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
426 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
427 builder.add_value(200);
428 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700429 }
430 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700431 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
432 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
433 builder.add_value(201);
434 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700435 }
436
437 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
438
439 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700440 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700441 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700442 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700443 }
444 // Do it again to make sure we don't double fetch.
445 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700446 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700447 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700448 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700449 });
450
451 loop2->OnRun([&test_timer, &loop2]() {
452 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
453 });
454
455 Run();
456 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
457}
458
459// Tests that Fetch and FetchNext interleave as expected.
460TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
461 auto loop1 = Make();
462 auto loop2 = MakePrimary();
463
464 auto sender = loop1->MakeSender<TestMessage>("/test");
465
466 ::std::vector<int> values;
467
468 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700469 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
470 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
471 builder.add_value(200);
472 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700473 }
474 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700475 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
476 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
477 builder.add_value(201);
478 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700479 }
480
481 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
482
483 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700484 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700485 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700486 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700487 }
488
489 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700490 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
491 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
492 builder.add_value(202);
493 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700494 }
495 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700496 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
497 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
498 builder.add_value(203);
499 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700500 }
501 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700502 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
503 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
504 builder.add_value(204);
505 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700506 }
507
508 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700509 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700510 }
511
512 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700513 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700514 }
515
Austin Schuh9fe68f72019-08-10 19:32:03 -0700516 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700517 });
518
519 loop2->OnRun([&test_timer, &loop2]() {
520 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
521 });
522
523 Run();
524 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
525}
526
Austin Schuh3115a202019-05-27 21:02:14 -0700527// Tests that FetchNext behaves correctly when we get two messages in the queue
528// but don't consume the first until after the second has been sent.
529TEST_P(AbstractEventLoopTest, FetchNextTest) {
Austin Schuh3115a202019-05-27 21:02:14 -0700530 auto send_loop = Make();
531 auto fetch_loop = Make();
532 auto sender = send_loop->MakeSender<TestMessage>("/test");
533 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
534
535 {
Tyler Chatow67ddb032020-01-12 14:30:04 -0800536 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
537 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
538 builder.add_value(100);
539 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700540 }
541
542 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700543 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
544 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
545 builder.add_value(200);
546 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700547 }
548
549 ASSERT_TRUE(fetcher.FetchNext());
550 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700551 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700552
553 ASSERT_TRUE(fetcher.FetchNext());
554 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700555 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700556
557 // When we run off the end of the queue, expect to still have the old message:
558 ASSERT_FALSE(fetcher.FetchNext());
559 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700560 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700561}
562
Brian Silverman77162972020-08-12 19:52:40 -0700563// Verify that a fetcher still holds its data, even after falling behind.
564TEST_P(AbstractEventLoopTest, FetcherBehindData) {
565 auto send_loop = Make();
566 auto fetch_loop = Make();
567 auto sender = send_loop->MakeSender<TestMessage>("/test");
568 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
569 {
570 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
571 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
572 builder.add_value(1);
573 ASSERT_TRUE(msg.Send(builder.Finish()));
574 }
575 ASSERT_TRUE(fetcher.Fetch());
576 EXPECT_EQ(1, fetcher.get()->value());
577 for (int i = 0; i < 300; ++i) {
578 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
579 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
580 builder.add_value(i + 2);
581 ASSERT_TRUE(msg.Send(builder.Finish()));
582 }
583 EXPECT_EQ(1, fetcher.get()->value());
584}
585
586// Try a bunch of orderings of operations with fetchers and senders. Verify that
587// all the fetchers have the correct data at each step.
588TEST_P(AbstractEventLoopTest, FetcherPermutations) {
589 for (int max_save = 0; max_save < 5; ++max_save) {
590 SCOPED_TRACE("max_save=" + std::to_string(max_save));
591
592 auto send_loop = Make();
593 auto fetch_loop = Make();
594 auto sender = send_loop->MakeSender<TestMessage>("/test");
595 const auto send_message = [&sender](int i) {
596 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
597 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
598 builder.add_value(i);
599 ASSERT_TRUE(msg.Send(builder.Finish()));
600 };
601 std::vector<Fetcher<TestMessage>> fetchers;
602 for (int i = 0; i < 10; ++i) {
603 fetchers.emplace_back(fetch_loop->MakeFetcher<TestMessage>("/test"));
604 }
605 send_message(1);
606 for (auto &fetcher : fetchers) {
607 ASSERT_TRUE(fetcher.Fetch());
608 EXPECT_EQ(1, fetcher.get()->value());
609 }
610
611 for (int save = 1; save <= max_save; ++save) {
612 SCOPED_TRACE("save=" + std::to_string(save));
613 send_message(100 + save);
614 for (size_t i = 0; i < fetchers.size() - save; ++i) {
615 SCOPED_TRACE("fetcher=" + std::to_string(i));
616 ASSERT_TRUE(fetchers[i].Fetch());
617 EXPECT_EQ(100 + save, fetchers[i].get()->value());
618 }
619 for (size_t i = fetchers.size() - save; i < fetchers.size() - 1; ++i) {
620 SCOPED_TRACE("fetcher=" + std::to_string(i));
621 EXPECT_EQ(100 + (fetchers.size() - 1 - i), fetchers[i].get()->value());
622 }
623 EXPECT_EQ(1, fetchers.back().get()->value());
624 }
625
626 for (int i = 0; i < 300; ++i) {
627 send_message(200 + i);
628 }
629
630 for (size_t i = 0; i < fetchers.size() - max_save; ++i) {
631 SCOPED_TRACE("fetcher=" + std::to_string(i));
632 if (max_save > 0) {
633 EXPECT_EQ(100 + max_save, fetchers[i].get()->value());
634 } else {
635 EXPECT_EQ(1, fetchers[i].get()->value());
636 }
637 }
638 for (size_t i = fetchers.size() - max_save; i < fetchers.size() - 1; ++i) {
639 SCOPED_TRACE("fetcher=" + std::to_string(i));
640 EXPECT_EQ(100 + (fetchers.size() - 1 - i), fetchers[i].get()->value());
641 }
642 EXPECT_EQ(1, fetchers.back().get()->value());
643 }
644}
645
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800646// Verify that making a fetcher and watcher for "/test" succeeds.
647TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800648 auto loop = Make();
649 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800650 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800651}
652
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800653// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800654TEST_P(AbstractEventLoopTest, TwoFetcher) {
655 auto loop = Make();
656 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800657 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800658}
659
Alex Perrycb7da4b2019-08-28 19:35:56 -0700660// Verify that registering a watcher for an invalid channel name dies.
661TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
662 auto loop = Make();
663 EXPECT_DEATH(
664 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
665 "/test/invalid");
Brian Silverman454bc112020-03-05 14:21:25 -0800666 EXPECT_DEATH(
667 { loop->MakeNoArgWatcher<TestMessage>("/test/invalid", [&]() {}); },
668 "/test/invalid");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700669}
670
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800671// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700672TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800673 auto loop = Make();
674 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800675 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
676 "/test");
Brian Silverman454bc112020-03-05 14:21:25 -0800677 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
678}
679
680// Verify that registering a no-arg watcher twice for "/test" fails.
681TEST_P(AbstractEventLoopDeathTest, TwoNoArgWatcher) {
682 auto loop = Make();
683 loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {});
684 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
685 "/test");
686 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800687}
688
Austin Schuh3115a202019-05-27 21:02:14 -0700689// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700690TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700691 auto loop = MakePrimary();
692 // Confirm that runtime priority calls work when not realtime.
693 loop->SetRuntimeRealtimePriority(5);
694
695 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
696
697 EXPECT_DEATH(Run(), "realtime");
698}
699
Brian Silverman6a54ff32020-04-28 16:41:39 -0700700// Verify that SetRuntimeAffinity fails while running.
701TEST_P(AbstractEventLoopDeathTest, SetRuntimeAffinity) {
702 auto loop = MakePrimary();
703 // Confirm that runtime priority calls work when not running.
704 loop->SetRuntimeAffinity(MakeCpusetFromCpus({0}));
705
706 loop->OnRun([&]() { loop->SetRuntimeAffinity(MakeCpusetFromCpus({1})); });
707
708 EXPECT_DEATH(Run(), "Cannot set affinity while running");
709}
710
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800711// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700712TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800713 auto loop = Make();
714 auto sender = loop->MakeSender<TestMessage>("/test");
715 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
716 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800717}
718
Austin Schuhe516ab02020-05-06 21:37:04 -0700719// Verify that creating too many senders fails.
720TEST_P(AbstractEventLoopDeathTest, TooManySenders) {
721 auto loop = Make();
722 std::vector<aos::Sender<TestMessage>> senders;
723 for (int i = 0; i < 10; ++i) {
724 senders.emplace_back(loop->MakeSender<TestMessage>("/test"));
725 }
726 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); },
727 "Failed to create sender on \\{ \"name\": \"/test\", \"type\": "
Brian Silverman77162972020-08-12 19:52:40 -0700728 "\"aos.TestMessage\"[^}]*\\ }, too many senders.");
729}
730
731// Verify that creating too many fetchers fails.
732TEST_P(AbstractEventLoopDeathTest, TooManyFetchers) {
733 if (read_method() != ReadMethod::PIN) {
734 // Other read methods don't limit the number of readers, so just skip this.
735 return;
736 }
737
738 auto loop = Make();
739 std::vector<aos::Fetcher<TestMessage>> fetchers;
740 for (int i = 0; i < 10; ++i) {
741 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
742 }
743 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
744 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
745 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
746}
747
748// Verify that creating too many fetchers, split between two event loops, fails.
749TEST_P(AbstractEventLoopDeathTest, TooManyFetchersTwoLoops) {
750 if (read_method() != ReadMethod::PIN) {
751 // Other read methods don't limit the number of readers, so just skip this.
752 return;
753 }
754
755 auto loop = Make();
756 auto loop2 = Make();
757 std::vector<aos::Fetcher<TestMessage>> fetchers;
758 for (int i = 0; i < 5; ++i) {
759 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
760 fetchers.emplace_back(loop2->MakeFetcher<TestMessage>("/test"));
761 }
762 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
763 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
764 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
765}
766
767// Verify that creating too many watchers fails.
768TEST_P(AbstractEventLoopDeathTest, TooManyWatchers) {
769 if (read_method() != ReadMethod::PIN) {
770 // Other read methods don't limit the number of readers, so just skip this.
771 return;
772 }
773
774 std::vector<std::unique_ptr<EventLoop>> loops;
775 for (int i = 0; i < 10; ++i) {
776 loops.emplace_back(Make());
777 loops.back()->MakeWatcher("/test", [](const TestMessage &) {});
778 }
779 EXPECT_DEATH({ Make()->MakeWatcher("/test", [](const TestMessage &) {}); },
780 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
781 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
782}
783
784// Verify that creating too many watchers and fetchers combined fails.
785TEST_P(AbstractEventLoopDeathTest, TooManyWatchersAndFetchers) {
786 if (read_method() != ReadMethod::PIN) {
787 // Other read methods don't limit the number of readers, so just skip this.
788 return;
789 }
790
791 auto loop = Make();
792 std::vector<aos::Fetcher<TestMessage>> fetchers;
793 std::vector<std::unique_ptr<EventLoop>> loops;
794 for (int i = 0; i < 5; ++i) {
795 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
796 loops.emplace_back(Make());
797 loops.back()->MakeWatcher("/test", [](const TestMessage &) {});
798 }
799 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
800 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
801 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
Austin Schuhe516ab02020-05-06 21:37:04 -0700802}
803
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700804// Verify that we can't create a sender inside OnRun.
805TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
806 auto loop1 = MakePrimary();
807
808 loop1->OnRun(
809 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
810
811 EXPECT_DEATH(Run(), "running");
812}
813
814// Verify that we can't create a watcher inside OnRun.
815TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
816 auto loop1 = MakePrimary();
817
818 loop1->OnRun(
819 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
820
821 EXPECT_DEATH(Run(), "running");
822}
823
Brian Silverman454bc112020-03-05 14:21:25 -0800824// Verify that we can't create a no-arg watcher inside OnRun.
825TEST_P(AbstractEventLoopDeathTest, NoArgWatcherInOnRun) {
826 auto loop1 = MakePrimary();
827
828 loop1->OnRun(
829 [&]() { loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {}); });
830
831 EXPECT_DEATH(Run(), "running");
832}
833
Parker Schuhe4a70d62017-12-27 20:10:20 -0800834// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800835TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
836 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700837 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800838
Austin Schuh3578a2e2019-05-25 18:17:59 -0700839 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
840 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700841 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700842 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700843 });
844
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800845 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700846
847 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700848 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
849 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
850 builder.add_value(200);
851 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700852 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800853
Austin Schuh44019f92019-05-19 19:58:27 -0700854 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800855}
856
Neil Balch229001a2018-01-07 18:22:52 -0800857// Verify that timer intervals and duration function properly.
858TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800859 // Force a slower rate so we are guarenteed to have reports for our timer.
860 FLAGS_timing_report_ms = 2000;
861
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800862 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800863
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800864 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800865 auto loop2 = Make();
866
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800867 ::std::vector<::aos::monotonic_clock::time_point> times;
868 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
869
Austin Schuh39788ff2019-12-01 18:22:57 -0800870 Fetcher<timing::Report> report_fetcher =
871 loop2->MakeFetcher<timing::Report>("/aos");
872 EXPECT_FALSE(report_fetcher.Fetch());
873
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800874 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
875 times.push_back(loop->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800876 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
877 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
878 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800879 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
880 EXPECT_EQ(loop->context().size, 0u);
881 EXPECT_EQ(loop->context().data, nullptr);
882
Austin Schuhad154822019-12-27 15:45:13 -0800883 expected_times.push_back(loop->context().monotonic_event_time);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800884 if (times.size() == kCount) {
885 this->Exit();
886 }
Neil Balch229001a2018-01-07 18:22:52 -0800887 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800888 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800889
Austin Schuh39788ff2019-12-01 18:22:57 -0800890 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700891 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800892 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
893
Austin Schuh44019f92019-05-19 19:58:27 -0700894 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800895
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800896 // Confirm that we got both the right number of samples, and it's odd.
897 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
898 EXPECT_EQ(times.size(), expected_times.size());
899 EXPECT_EQ((times.size() % 2), 1);
900
901 // Grab the middle sample.
902 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
903
904 // Add up all the delays of all the times.
905 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
906 for (const ::aos::monotonic_clock::time_point time : times) {
907 sum += time - average_time;
908 }
909
910 // Average and add to the middle to find the average time.
911 sum /= times.size();
912 average_time += sum;
913
914 // Compute the offset from the average and the expected average. It
915 // should be pretty close to 0.
916 const ::aos::monotonic_clock::duration remainder =
917 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
918
919 const chrono::milliseconds kEpsilon(100);
920 EXPECT_LT(remainder, +kEpsilon);
921 EXPECT_GT(remainder, -kEpsilon);
922
923 // Make sure that the average duration is close to 1 second.
924 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
925 times.front())
926 .count() /
927 static_cast<double>(times.size() - 1),
928 1.0, 0.1);
929
930 // Confirm that the ideal wakeup times increment correctly.
931 for (size_t i = 1; i < expected_times.size(); ++i) {
932 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
933 }
934
935 for (size_t i = 0; i < expected_times.size(); ++i) {
936 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
937 chrono::seconds(0));
938 }
939
940 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
941 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800942
943 // And, since we are here, check that the timing report makes sense.
944 // Start by looking for our event loop's timing.
945 FlatbufferDetachedBuffer<timing::Report> report =
946 FlatbufferDetachedBuffer<timing::Report>::Empty();
947 while (report_fetcher.FetchNext()) {
948 if (report_fetcher->name()->string_view() == "primary") {
949 report = CopyFlatBuffer(report_fetcher.get());
950 }
951 }
952
953 // Confirm that we have the right number of reports, and the contents are
954 // sane.
Ravago Jonescf453ab2020-05-06 21:14:53 -0700955 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -0800956
957 EXPECT_EQ(report.message().name()->string_view(), "primary");
958
959 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -0800960 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -0800961
962 ASSERT_NE(report.message().timers(), nullptr);
963 EXPECT_EQ(report.message().timers()->size(), 2);
964
965 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
966 "Test loop");
967 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
968
969 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
970 "timing_reports");
971 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
972
973 // Make sure there is a single phased loop report with our report in it.
974 ASSERT_EQ(report.message().phased_loops(), nullptr);
Neil Balch229001a2018-01-07 18:22:52 -0800975}
976
977// Verify that we can change a timer's parameters during execution.
978TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700979 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800980 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
981
982 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
983 iteration_list.push_back(loop->monotonic_now());
984 });
985
986 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
987 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
988 });
989
Neil Balch229001a2018-01-07 18:22:52 -0800990 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
991 modifier_timer->Setup(loop->monotonic_now() +
992 ::std::chrono::milliseconds(45));
993 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700994 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800995
996 EXPECT_EQ(iteration_list.size(), 7);
997}
998
999// Verify that we can disable a timer during execution.
1000TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -07001001 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -08001002 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
1003
1004 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
1005 iteration_list.push_back(loop->monotonic_now());
1006 });
1007
Tyler Chatow67ddb032020-01-12 14:30:04 -08001008 auto ender_timer = loop->AddTimer([&test_timer]() { test_timer->Disable(); });
Neil Balch229001a2018-01-07 18:22:52 -08001009
1010 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
Tyler Chatow67ddb032020-01-12 14:30:04 -08001011 ender_timer->Setup(loop->monotonic_now() + ::std::chrono::milliseconds(45));
Neil Balch229001a2018-01-07 18:22:52 -08001012 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -07001013 Run();
Neil Balch229001a2018-01-07 18:22:52 -08001014
1015 EXPECT_EQ(iteration_list.size(), 3);
1016}
Austin Schuh7267c532019-05-19 19:55:53 -07001017
Brian Silvermanbd405c02020-06-23 16:25:23 -07001018// Verify that we can disable a timer during execution of another timer
1019// scheduled for the same time, with one ordering of creation for the timers.
1020//
1021// Also schedule some more events to reshuffle the heap in EventLoop used for
1022// tracking events to change up the order. This used to segfault
1023// SimulatedEventLoop.
1024TEST_P(AbstractEventLoopTest, TimerDisableOther) {
1025 for (bool creation_order : {true, false}) {
1026 for (bool setup_order : {true, false}) {
1027 for (int shuffle_events = 0; shuffle_events < 5; ++shuffle_events) {
1028 auto loop = MakePrimary();
1029 aos::TimerHandler *test_timer, *ender_timer;
1030 if (creation_order) {
1031 test_timer = loop->AddTimer([]() {});
1032 ender_timer =
1033 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1034 } else {
1035 ender_timer =
1036 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1037 test_timer = loop->AddTimer([]() {});
1038 }
1039
1040 const auto start = loop->monotonic_now();
1041
1042 for (int i = 0; i < shuffle_events; ++i) {
1043 loop->AddTimer([]() {})->Setup(start + std::chrono::milliseconds(10));
1044 }
1045
1046 if (setup_order) {
1047 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1048 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1049 } else {
1050 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1051 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1052 }
1053 EndEventLoop(loop.get(), ::std::chrono::milliseconds(40));
1054 Run();
1055 }
1056 }
1057 }
1058}
1059
Austin Schuh54cf95f2019-11-29 13:14:18 -08001060// Verifies that the event loop implementations detect when Channel is not a
1061// pointer into confguration()
1062TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
1063 auto loop = MakePrimary();
1064
Tyler Chatow67ddb032020-01-12 14:30:04 -08001065 const Channel *channel = configuration::GetChannel(
1066 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
Austin Schuh54cf95f2019-11-29 13:14:18 -08001067
1068 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
1069
1070 EXPECT_DEATH(
1071 { loop->MakeRawSender(&channel_copy.message()); },
1072 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1073
1074 EXPECT_DEATH(
1075 { loop->MakeRawFetcher(&channel_copy.message()); },
1076 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1077
1078 EXPECT_DEATH(
1079 {
1080 loop->MakeRawWatcher(&channel_copy.message(),
1081 [](const Context, const void *) {});
1082 },
1083 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1084}
1085
Brian Silverman454bc112020-03-05 14:21:25 -08001086// Verify that the send time on a message is roughly right when using a watcher.
Austin Schuh7267c532019-05-19 19:55:53 -07001087TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -07001088 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -07001089 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -08001090 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -07001091 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
1092
1093 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -07001094 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1095 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1096 builder.add_value(200);
1097 ASSERT_TRUE(msg.Send(builder.Finish()));
1098 });
1099
Austin Schuhad154822019-12-27 15:45:13 -08001100 bool triggered = false;
Brian Silverman454bc112020-03-05 14:21:25 -08001101 loop1->MakeWatcher("/test", [&](const TestMessage &msg) {
Austin Schuhad154822019-12-27 15:45:13 -08001102 // Confirm that the data pointer makes sense from a watcher, and all the
1103 // timestamps look right.
1104 EXPECT_GT(&msg, loop1->context().data);
1105 EXPECT_EQ(loop1->context().monotonic_remote_time,
1106 loop1->context().monotonic_event_time);
1107 EXPECT_EQ(loop1->context().realtime_remote_time,
1108 loop1->context().realtime_event_time);
1109
1110 const aos::monotonic_clock::time_point monotonic_now =
1111 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -08001112 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001113
1114 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1115 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1116 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1117 monotonic_now);
1118 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1119 realtime_now);
1120
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001121 EXPECT_LT(&msg, reinterpret_cast<const void *>(
1122 reinterpret_cast<const char *>(loop1->context().data) +
Austin Schuhad154822019-12-27 15:45:13 -08001123 loop1->context().size));
1124 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -07001125 });
1126
1127 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1128
1129 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -07001130 Run();
Austin Schuh7267c532019-05-19 19:55:53 -07001131
Austin Schuhad154822019-12-27 15:45:13 -08001132 EXPECT_TRUE(triggered);
1133
Brian Silverman454bc112020-03-05 14:21:25 -08001134 ASSERT_TRUE(fetcher.Fetch());
1135
1136 monotonic_clock::duration monotonic_time_offset =
1137 fetcher.context().monotonic_event_time -
1138 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1139 realtime_clock::duration realtime_time_offset =
1140 fetcher.context().realtime_event_time -
1141 (loop1->realtime_now() - ::std::chrono::seconds(1));
1142
1143 EXPECT_EQ(fetcher.context().realtime_event_time,
1144 fetcher.context().realtime_remote_time);
1145 EXPECT_EQ(fetcher.context().monotonic_event_time,
1146 fetcher.context().monotonic_remote_time);
1147
1148 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1149 << ": Got "
1150 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1151 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1152 // Confirm that the data pointer makes sense.
1153 EXPECT_GT(fetcher.get(), fetcher.context().data);
1154 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001155 reinterpret_cast<const void *>(
1156 reinterpret_cast<const char *>(fetcher.context().data) +
Brian Silverman454bc112020-03-05 14:21:25 -08001157 fetcher.context().size));
1158 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1159 << ": Got "
1160 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1161 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1162
1163 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1164 << ": Got "
1165 << fetcher.context().realtime_event_time.time_since_epoch().count()
1166 << " expected " << loop1->realtime_now().time_since_epoch().count();
1167 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1168 << ": Got "
1169 << fetcher.context().realtime_event_time.time_since_epoch().count()
1170 << " expected " << loop1->realtime_now().time_since_epoch().count();
1171}
1172
1173// Verify that the send time on a message is roughly right when using a no-arg
1174// watcher. To get a message, we need to use a fetcher to actually access the
1175// message. This is also the main use case for no-arg fetchers.
1176TEST_P(AbstractEventLoopTest, MessageSendTimeNoArg) {
1177 auto loop1 = MakePrimary();
1178 auto loop2 = Make();
1179 auto sender = loop2->MakeSender<TestMessage>("/test");
1180 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1181
1182 auto test_timer = loop1->AddTimer([&sender]() {
1183 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1184 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1185 builder.add_value(200);
1186 ASSERT_TRUE(msg.Send(builder.Finish()));
1187 });
1188
1189 bool triggered = false;
1190 loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {
1191 // Confirm that we can indeed use a fetcher on this channel from this
1192 // context, and it results in a sane data pointer and timestamps.
1193 ASSERT_TRUE(fetcher.Fetch());
1194
1195 EXPECT_EQ(loop1->context().monotonic_remote_time,
1196 loop1->context().monotonic_event_time);
1197 EXPECT_EQ(loop1->context().realtime_remote_time,
1198 loop1->context().realtime_event_time);
1199
1200 const aos::monotonic_clock::time_point monotonic_now =
1201 loop1->monotonic_now();
1202 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
1203
1204 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1205 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1206 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1207 monotonic_now);
1208 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1209 realtime_now);
1210
1211 triggered = true;
1212 });
1213
1214 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1215
1216 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
1217 Run();
1218
1219 ASSERT_TRUE(triggered);
Austin Schuh7267c532019-05-19 19:55:53 -07001220
Alex Perrycb7da4b2019-08-28 19:35:56 -07001221 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001222 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001223 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1224 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001225 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001226 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -07001227
Austin Schuhad154822019-12-27 15:45:13 -08001228 EXPECT_EQ(fetcher.context().realtime_event_time,
1229 fetcher.context().realtime_remote_time);
1230 EXPECT_EQ(fetcher.context().monotonic_event_time,
1231 fetcher.context().monotonic_remote_time);
1232
Alex Perrycb7da4b2019-08-28 19:35:56 -07001233 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1234 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001235 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -07001236 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001237 // Confirm that the data pointer makes sense.
1238 EXPECT_GT(fetcher.get(), fetcher.context().data);
1239 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001240 reinterpret_cast<const void *>(
1241 reinterpret_cast<const char *>(fetcher.context().data) +
Alex Perrycb7da4b2019-08-28 19:35:56 -07001242 fetcher.context().size));
1243 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1244 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001245 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -07001246 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001247
1248 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1249 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001250 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001251 << " expected " << loop1->realtime_now().time_since_epoch().count();
1252 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1253 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001254 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001255 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -07001256}
1257
Austin Schuh52d325c2019-06-23 18:59:06 -07001258// Tests that a couple phased loops run in a row result in the correct offset
1259// and period.
1260TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -08001261 // Force a slower rate so we are guarenteed to have reports for our phased
1262 // loop.
1263 FLAGS_timing_report_ms = 2000;
1264
Austin Schuh52d325c2019-06-23 18:59:06 -07001265 const chrono::milliseconds kOffset = chrono::milliseconds(400);
1266 const int kCount = 5;
1267
1268 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -08001269 auto loop2 = Make();
1270
1271 Fetcher<timing::Report> report_fetcher =
1272 loop2->MakeFetcher<timing::Report>("/aos");
1273 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001274
1275 // Collect up a couple of samples.
1276 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001277 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -07001278
1279 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -08001280 loop1
1281 ->AddPhasedLoop(
1282 [&times, &expected_times, &loop1, this](int count) {
1283 EXPECT_EQ(count, 1);
1284 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -08001285 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -08001286
Austin Schuhad154822019-12-27 15:45:13 -08001287 EXPECT_EQ(loop1->context().monotonic_remote_time,
1288 monotonic_clock::min_time);
1289 EXPECT_EQ(loop1->context().realtime_event_time,
1290 realtime_clock::min_time);
1291 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -08001292 realtime_clock::min_time);
1293 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
1294 EXPECT_EQ(loop1->context().size, 0u);
1295 EXPECT_EQ(loop1->context().data, nullptr);
1296
1297 if (times.size() == kCount) {
1298 LOG(INFO) << "Exiting";
1299 this->Exit();
1300 }
1301 },
1302 chrono::seconds(1), kOffset)
1303 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -07001304
1305 // Add a delay to make sure that delay during startup doesn't result in a
1306 // "missed cycle".
1307 SleepFor(chrono::seconds(2));
1308
1309 Run();
1310
1311 // Confirm that we got both the right number of samples, and it's odd.
1312 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001313 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -07001314 EXPECT_EQ((times.size() % 2), 1);
1315
1316 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001317 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -07001318
1319 // Add up all the delays of all the times.
1320 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1321 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001322 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -07001323 }
1324
1325 // Average and add to the middle to find the average time.
1326 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001327 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -07001328
1329 // Compute the offset from the start of the second of the average time. This
1330 // should be pretty close to the offset.
1331 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001332 average_time.time_since_epoch() -
1333 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001334
1335 const chrono::milliseconds kEpsilon(100);
1336 EXPECT_LT(remainder, kOffset + kEpsilon);
1337 EXPECT_GT(remainder, kOffset - kEpsilon);
1338
1339 // Make sure that the average duration is close to 1 second.
1340 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1341 times.front())
1342 .count() /
1343 static_cast<double>(times.size() - 1),
1344 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001345
1346 // Confirm that the ideal wakeup times increment correctly.
1347 for (size_t i = 1; i < expected_times.size(); ++i) {
1348 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1349 }
1350
1351 for (size_t i = 0; i < expected_times.size(); ++i) {
1352 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1353 kOffset);
1354 }
1355
1356 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1357 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001358
1359 // And, since we are here, check that the timing report makes sense.
1360 // Start by looking for our event loop's timing.
1361 FlatbufferDetachedBuffer<timing::Report> report =
1362 FlatbufferDetachedBuffer<timing::Report>::Empty();
1363 while (report_fetcher.FetchNext()) {
1364 if (report_fetcher->name()->string_view() == "primary") {
1365 report = CopyFlatBuffer(report_fetcher.get());
1366 }
1367 }
1368
Ravago Jonescf453ab2020-05-06 21:14:53 -07001369 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001370
1371 EXPECT_EQ(report.message().name()->string_view(), "primary");
1372
1373 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001374 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001375
1376 ASSERT_NE(report.message().timers(), nullptr);
1377 EXPECT_EQ(report.message().timers()->size(), 1);
1378
1379 // Make sure there is a single phased loop report with our report in it.
1380 ASSERT_NE(report.message().phased_loops(), nullptr);
1381 ASSERT_EQ(report.message().phased_loops()->size(), 1);
1382 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
1383 "Test loop");
1384 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
1385}
1386
1387// Tests that senders count correctly in the timing report.
1388TEST_P(AbstractEventLoopTest, SenderTimingReport) {
1389 FLAGS_timing_report_ms = 1000;
1390 auto loop1 = MakePrimary();
1391
1392 auto loop2 = Make("watcher_loop");
1393 loop2->MakeWatcher("/test", [](const TestMessage &) {});
1394
1395 auto loop3 = Make();
1396
1397 Fetcher<timing::Report> report_fetcher =
1398 loop3->MakeFetcher<timing::Report>("/aos");
1399 EXPECT_FALSE(report_fetcher.Fetch());
1400
1401 auto sender = loop1->MakeSender<TestMessage>("/test");
1402
1403 // Add a timer to actually quit.
1404 auto test_timer = loop1->AddTimer([&sender]() {
1405 for (int i = 0; i < 10; ++i) {
1406 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1407 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1408 builder.add_value(200 + i);
1409 ASSERT_TRUE(msg.Send(builder.Finish()));
1410 }
1411 });
1412
1413 // Quit after 1 timing report, mid way through the next cycle.
1414 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1415
1416 loop1->OnRun([&test_timer, &loop1]() {
1417 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1418 });
1419
1420 Run();
1421
1422 // And, since we are here, check that the timing report makes sense.
1423 // Start by looking for our event loop's timing.
1424 FlatbufferDetachedBuffer<timing::Report> primary_report =
1425 FlatbufferDetachedBuffer<timing::Report>::Empty();
1426 while (report_fetcher.FetchNext()) {
1427 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1428 if (report_fetcher->name()->string_view() == "primary") {
1429 primary_report = CopyFlatBuffer(report_fetcher.get());
1430 }
1431 }
1432
Ravago Jonescf453ab2020-05-06 21:14:53 -07001433 LOG(INFO) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001434
1435 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1436
1437 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001438 EXPECT_EQ(primary_report.message().senders()->size(), 3);
Austin Schuh39788ff2019-12-01 18:22:57 -08001439
1440 // Confirm that the sender looks sane.
1441 EXPECT_EQ(
1442 loop1->configuration()
1443 ->channels()
1444 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1445 ->name()
1446 ->string_view(),
1447 "/test");
1448 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1449
1450 // Confirm that the timing primary_report sender looks sane.
1451 EXPECT_EQ(
1452 loop1->configuration()
1453 ->channels()
1454 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1455 ->name()
1456 ->string_view(),
1457 "/aos");
1458 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1459
1460 ASSERT_NE(primary_report.message().timers(), nullptr);
1461 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1462
1463 // Make sure there are no phased loops or watchers.
1464 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1465 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1466}
1467
1468// Tests that senders count correctly in the timing report.
1469TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1470 FLAGS_timing_report_ms = 1000;
1471 auto loop1 = MakePrimary();
1472 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1473
1474 auto loop2 = Make("sender_loop");
1475
1476 auto loop3 = Make();
1477
1478 Fetcher<timing::Report> report_fetcher =
1479 loop3->MakeFetcher<timing::Report>("/aos");
1480 EXPECT_FALSE(report_fetcher.Fetch());
1481
1482 auto sender = loop2->MakeSender<TestMessage>("/test");
1483
1484 // Add a timer to actually quit.
1485 auto test_timer = loop1->AddTimer([&sender]() {
1486 for (int i = 0; i < 10; ++i) {
1487 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1488 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1489 builder.add_value(200 + i);
1490 ASSERT_TRUE(msg.Send(builder.Finish()));
1491 }
1492 });
1493
1494 // Quit after 1 timing report, mid way through the next cycle.
1495 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1496
1497 loop1->OnRun([&test_timer, &loop1]() {
1498 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1499 });
1500
1501 Run();
1502
1503 // And, since we are here, check that the timing report makes sense.
1504 // Start by looking for our event loop's timing.
1505 FlatbufferDetachedBuffer<timing::Report> primary_report =
1506 FlatbufferDetachedBuffer<timing::Report>::Empty();
1507 while (report_fetcher.FetchNext()) {
1508 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1509 if (report_fetcher->name()->string_view() == "primary") {
1510 primary_report = CopyFlatBuffer(report_fetcher.get());
1511 }
1512 }
1513
1514 // Check the watcher report.
Ravago Jonescf453ab2020-05-06 21:14:53 -07001515 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001516
1517 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1518
1519 // Just the timing report timer.
1520 ASSERT_NE(primary_report.message().timers(), nullptr);
1521 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1522
1523 // No phased loops
1524 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1525
1526 ASSERT_NE(primary_report.message().watchers(), nullptr);
1527 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1528 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1529}
1530
1531// Tests that fetchers count correctly in the timing report.
1532TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1533 FLAGS_timing_report_ms = 1000;
1534 auto loop1 = MakePrimary();
1535 auto loop2 = Make("sender_loop");
1536
1537 auto loop3 = Make();
1538
1539 Fetcher<timing::Report> report_fetcher =
1540 loop3->MakeFetcher<timing::Report>("/aos");
1541 EXPECT_FALSE(report_fetcher.Fetch());
1542
1543 auto sender = loop2->MakeSender<TestMessage>("/test");
1544 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1545 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1546 fetcher1.Fetch();
1547 fetcher2.Fetch();
1548
1549 // Add a timer to actually quit.
1550 auto test_timer = loop1->AddTimer([&sender]() {
1551 for (int i = 0; i < 10; ++i) {
1552 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1553 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1554 builder.add_value(200 + i);
1555 ASSERT_TRUE(msg.Send(builder.Finish()));
1556 }
1557 });
1558
1559 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1560 fetcher1.Fetch();
1561 while (fetcher2.FetchNext()) {
1562 }
1563 });
1564
1565 // Quit after 1 timing report, mid way through the next cycle.
1566 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1567
1568 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1569 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1570 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1571 });
1572
1573 Run();
1574
1575 // And, since we are here, check that the timing report makes sense.
1576 // Start by looking for our event loop's timing.
1577 FlatbufferDetachedBuffer<timing::Report> primary_report =
1578 FlatbufferDetachedBuffer<timing::Report>::Empty();
1579 while (report_fetcher.FetchNext()) {
1580 if (report_fetcher->name()->string_view() == "primary") {
1581 primary_report = CopyFlatBuffer(report_fetcher.get());
1582 }
1583 }
1584
Ravago Jonescf453ab2020-05-06 21:14:53 -07001585 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001586
1587 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1588
1589 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001590 EXPECT_EQ(primary_report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001591
1592 ASSERT_NE(primary_report.message().timers(), nullptr);
1593 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1594
1595 // Make sure there are no phased loops or watchers.
1596 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1597 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1598
1599 // Now look at the fetchrs.
1600 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1601 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1602
1603 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1604 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1605 0.1);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001606 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(), 0.1);
1607 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(), 0.1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001608 EXPECT_EQ(primary_report.message()
1609 .fetchers()
1610 ->Get(0)
1611 ->latency()
1612 ->standard_deviation(),
1613 0.0);
1614
1615 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001616}
1617
Austin Schuh67420a42019-12-21 21:55:04 -08001618// Tests that a raw watcher and raw fetcher can receive messages from a raw
1619// sender without messing up offsets.
1620TEST_P(AbstractEventLoopTest, RawBasic) {
1621 auto loop1 = Make();
1622 auto loop2 = MakePrimary();
1623 auto loop3 = Make();
1624
1625 const std::string kData("971 is the best");
1626
1627 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001628 loop1->MakeRawSender(configuration::GetChannel(
1629 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001630
1631 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001632 loop3->MakeRawFetcher(configuration::GetChannel(
1633 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001634
1635 loop2->OnRun(
1636 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1637
1638 bool happened = false;
1639 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001640 configuration::GetChannel(loop2->configuration(), "/test",
1641 "aos.TestMessage", "", nullptr),
Austin Schuh67420a42019-12-21 21:55:04 -08001642 [this, &kData, &fetcher, &happened](const Context &context,
1643 const void *message) {
1644 happened = true;
1645 EXPECT_EQ(std::string_view(kData),
1646 std::string_view(reinterpret_cast<const char *>(message),
1647 context.size));
1648 EXPECT_EQ(std::string_view(kData),
1649 std::string_view(reinterpret_cast<const char *>(context.data),
1650 context.size));
1651
1652 ASSERT_TRUE(fetcher->Fetch());
1653
1654 EXPECT_EQ(std::string_view(kData),
1655 std::string_view(
1656 reinterpret_cast<const char *>(fetcher->context().data),
1657 fetcher->context().size));
1658
1659 this->Exit();
1660 });
1661
1662 EXPECT_FALSE(happened);
1663 Run();
1664 EXPECT_TRUE(happened);
1665}
1666
Austin Schuhad154822019-12-27 15:45:13 -08001667// Tests that a raw watcher and raw fetcher can receive messages from a raw
1668// sender with remote times filled out.
1669TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1670 auto loop1 = Make();
1671 auto loop2 = MakePrimary();
1672 auto loop3 = Make();
1673
1674 const std::string kData("971 is the best");
1675
1676 const aos::monotonic_clock::time_point monotonic_remote_time =
1677 aos::monotonic_clock::time_point(chrono::seconds(1501));
1678 const aos::realtime_clock::time_point realtime_remote_time =
1679 aos::realtime_clock::time_point(chrono::seconds(3132));
1680
1681 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001682 loop1->MakeRawSender(configuration::GetChannel(
1683 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001684
1685 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001686 loop3->MakeRawFetcher(configuration::GetChannel(
1687 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001688
1689 loop2->OnRun([&]() {
1690 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1691 realtime_remote_time));
1692 });
1693
1694 bool happened = false;
1695 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001696 configuration::GetChannel(loop2->configuration(), "/test",
1697 "aos.TestMessage", "", nullptr),
Austin Schuhad154822019-12-27 15:45:13 -08001698 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1699 const Context &context, const void * /*message*/) {
1700 happened = true;
1701 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1702 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1703
1704 ASSERT_TRUE(fetcher->Fetch());
1705 EXPECT_EQ(monotonic_remote_time,
1706 fetcher->context().monotonic_remote_time);
1707 EXPECT_EQ(realtime_remote_time,
1708 fetcher->context().realtime_remote_time);
1709
1710 this->Exit();
1711 });
1712
1713 EXPECT_FALSE(happened);
1714 Run();
1715 EXPECT_TRUE(happened);
1716}
1717
1718// Tests that a raw sender fills out sent data.
1719TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1720 auto loop1 = MakePrimary();
1721
1722 const std::string kData("971 is the best");
1723
1724 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001725 loop1->MakeRawSender(configuration::GetChannel(
1726 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001727
Tyler Chatow67ddb032020-01-12 14:30:04 -08001728 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
1729 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001730
1731 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1732
1733 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1734 EXPECT_LE(sender->monotonic_sent_time(),
1735 monotonic_now + chrono::milliseconds(100));
1736 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1737 EXPECT_LE(sender->realtime_sent_time(),
1738 realtime_now + chrono::milliseconds(100));
1739 EXPECT_EQ(sender->sent_queue_index(), 0u);
1740
1741 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1742
1743 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1744 EXPECT_LE(sender->monotonic_sent_time(),
1745 monotonic_now + chrono::milliseconds(100));
1746 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1747 EXPECT_LE(sender->realtime_sent_time(),
1748 realtime_now + chrono::milliseconds(100));
1749 EXPECT_EQ(sender->sent_queue_index(), 1u);
1750}
1751
Austin Schuh217a9782019-12-21 23:02:50 -08001752// Tests that not setting up nodes results in no node.
1753TEST_P(AbstractEventLoopTest, NoNode) {
1754 auto loop1 = Make();
1755 auto loop2 = MakePrimary();
1756
1757 EXPECT_EQ(loop1->node(), nullptr);
1758 EXPECT_EQ(loop2->node(), nullptr);
1759}
1760
1761// Tests that setting up nodes results in node being set.
1762TEST_P(AbstractEventLoopTest, Node) {
1763 EnableNodes("me");
1764
1765 auto loop1 = Make();
1766 auto loop2 = MakePrimary();
1767
1768 EXPECT_NE(loop1->node(), nullptr);
1769 EXPECT_NE(loop2->node(), nullptr);
1770}
1771
1772// Tests that watchers work with a node setup.
1773TEST_P(AbstractEventLoopTest, NodeWatcher) {
1774 EnableNodes("me");
1775
1776 auto loop1 = Make();
1777 auto loop2 = Make();
1778 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08001779 loop2->MakeRawWatcher(
1780 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1781 nullptr),
1782 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001783}
1784
Brian Silverman454bc112020-03-05 14:21:25 -08001785// Tests that no-arg watchers work with a node setup.
1786TEST_P(AbstractEventLoopTest, NodeNoArgWatcher) {
1787 EnableNodes("me");
1788
1789 auto loop1 = Make();
1790 auto loop2 = Make();
1791 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1792 loop2->MakeRawNoArgWatcher(
1793 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1794 nullptr),
1795 [](const Context &) {});
1796}
1797
Austin Schuh217a9782019-12-21 23:02:50 -08001798// Tests that fetcher work with a node setup.
1799TEST_P(AbstractEventLoopTest, NodeFetcher) {
1800 EnableNodes("me");
1801 auto loop1 = Make();
1802
1803 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08001804 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1805 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001806}
1807
1808// Tests that sender work with a node setup.
1809TEST_P(AbstractEventLoopTest, NodeSender) {
1810 EnableNodes("me");
1811 auto loop1 = Make();
1812
1813 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1814}
1815
1816// Tests that watchers fail when created on the wrong node.
1817TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
1818 EnableNodes("them");
1819
1820 auto loop1 = Make();
1821 auto loop2 = Make();
1822 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
1823 "node");
1824 EXPECT_DEATH(
1825 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001826 loop2->MakeRawWatcher(
1827 configuration::GetChannel(configuration(), "/test",
1828 "aos.TestMessage", "", nullptr),
1829 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001830 },
1831 "node");
Brian Silverman454bc112020-03-05 14:21:25 -08001832 EXPECT_DEATH({ loop1->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1833 "node");
1834 EXPECT_DEATH(
1835 {
1836 loop2->MakeRawNoArgWatcher(
1837 configuration::GetChannel(configuration(), "/test",
1838 "aos.TestMessage", "", nullptr),
1839 [](const Context &) {});
1840 },
1841 "node");
Austin Schuh217a9782019-12-21 23:02:50 -08001842}
1843
1844// Tests that fetchers fail when created on the wrong node.
1845TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
1846 EnableNodes("them");
1847 auto loop1 = Make();
1848
1849 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
1850 "node");
1851 EXPECT_DEATH(
1852 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001853 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1854 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001855 },
1856 "node");
1857}
1858
1859// Tests that senders fail when created on the wrong node.
1860TEST_P(AbstractEventLoopDeathTest, NodeSender) {
1861 EnableNodes("them");
1862 auto loop1 = Make();
1863
1864 EXPECT_DEATH(
1865 {
1866 aos::Sender<TestMessage> sender =
1867 loop1->MakeSender<TestMessage>("/test");
1868 },
1869 "node");
1870
1871 // Note: Creating raw senders is always supported. Right now, this lets us
1872 // use them to create message_gateway.
1873}
1874
Brian Silverman341b57e2020-06-23 16:23:18 -07001875// Tests creating multiple Builders from a single Sender at the same time.
1876TEST_P(AbstractEventLoopDeathTest, MultipleBuilders) {
1877 auto loop1 = Make();
1878 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1879
1880 { auto builder = sender.MakeBuilder(); }
1881 {
1882 auto builder = sender.MakeBuilder();
1883 builder.MakeBuilder<TestMessage>().Finish();
1884 }
1885 {
1886 // Creating this after the first one was destroyed should be fine.
1887 auto builder = sender.MakeBuilder();
1888 builder.MakeBuilder<TestMessage>().Finish();
1889 // But not a second one.
1890 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
1891 "May not overwrite in-use allocator");
1892 }
1893
1894 FlatbufferDetachedBuffer<TestMessage> detached =
1895 flatbuffers::DetachedBuffer();
1896 {
1897 auto builder = sender.MakeBuilder();
1898 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
1899 }
1900 {
1901 // This is the second one, after the detached one, so it should fail.
1902 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
1903 "May not overwrite in-use allocator");
1904 }
1905
1906 // Clear the detached one, and then we should be able to create another.
1907 detached = flatbuffers::DetachedBuffer();
1908 {
1909 auto builder = sender.MakeBuilder();
1910 builder.MakeBuilder<TestMessage>().Finish();
1911 }
1912
1913 // And then detach another one.
1914 {
1915 auto builder = sender.MakeBuilder();
1916 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
1917 }
1918}
1919
1920// Tests sending a buffer detached from a different builder.
1921TEST_P(AbstractEventLoopDeathTest, WrongDetachedBuffer) {
1922 auto loop1 = Make();
1923 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
1924 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
1925
1926 auto builder = sender1.MakeBuilder();
1927 FlatbufferDetachedBuffer<TestMessage> detached =
1928 builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
1929 EXPECT_DEATH(sender2.SendDetached(std::move(detached)),
1930 "May only send the buffer detached from this Sender");
1931}
1932
Parker Schuhe4a70d62017-12-27 20:10:20 -08001933} // namespace testing
1934} // namespace aos