blob: d92927b83521544bb32104d6b67582a58023dfda [file] [log] [blame]
Alex Perrycb7da4b2019-08-28 19:35:56 -07001#include "aos/events/event_loop_param_test.h"
Parker Schuhe4a70d62017-12-27 20:10:20 -08002
Austin Schuh52d325c2019-06-23 18:59:06 -07003#include <chrono>
Brian Silverman4f4e0612020-08-12 19:54:41 -07004#include <unordered_map>
5#include <unordered_set>
Austin Schuh52d325c2019-06-23 18:59:06 -07006
Austin Schuh54cf95f2019-11-29 13:14:18 -08007#include "aos/flatbuffer_merge.h"
Austin Schuhcc6070c2020-10-10 20:25:56 -07008#include "aos/realtime.h"
Austin Schuh54cf95f2019-11-29 13:14:18 -08009#include "glog/logging.h"
Tyler Chatow67ddb032020-01-12 14:30:04 -080010#include "gmock/gmock.h"
11#include "gtest/gtest.h"
Austin Schuh9fe68f72019-08-10 19:32:03 -070012
Parker Schuhe4a70d62017-12-27 20:10:20 -080013namespace aos {
14namespace testing {
Austin Schuh52d325c2019-06-23 18:59:06 -070015namespace {
16namespace chrono = ::std::chrono;
17} // namespace
Parker Schuhe4a70d62017-12-27 20:10:20 -080018
Brian Silverman4f4e0612020-08-12 19:54:41 -070019::std::unique_ptr<EventLoop> AbstractEventLoopTest::Make(
20 std::string_view name) {
21 std::string name_copy(name);
22 if (name == "") {
23 name_copy = "loop";
24 name_copy += std::to_string(event_loop_count_);
25 }
26 ++event_loop_count_;
27 return factory_->Make(name_copy);
28}
29
30void AbstractEventLoopTest::VerifyBuffers(
31 int number_buffers,
32 std::vector<std::reference_wrapper<const Fetcher<TestMessage>>> fetchers,
33 std::vector<std::reference_wrapper<const Sender<TestMessage>>> senders) {
34 // The buffers which are in a sender.
35 std::unordered_set<int> in_sender;
36 for (const Sender<TestMessage> &sender : senders) {
37 const int this_buffer = sender.buffer_index();
38 CHECK_GE(this_buffer, 0);
39 CHECK_LT(this_buffer, number_buffers);
40 CHECK(in_sender.insert(this_buffer).second) << ": " << this_buffer;
41 }
42
43 if (read_method() != ReadMethod::PIN) {
44 // If we're not using PIN, we can't really verify anything about what
45 // buffers the fetchers have.
46 return;
47 }
48
49 // Mapping from TestMessage::value to buffer index.
50 std::unordered_map<int, int> fetcher_values;
51 for (const Fetcher<TestMessage> &fetcher : fetchers) {
52 if (!fetcher.get()) {
53 continue;
54 }
55 const int this_buffer = fetcher.context().buffer_index;
56 CHECK_GE(this_buffer, 0);
57 CHECK_LT(this_buffer, number_buffers);
58 CHECK(in_sender.count(this_buffer) == 0) << ": " << this_buffer;
59 const auto insert_result = fetcher_values.insert(
60 std::make_pair(fetcher.get()->value(), this_buffer));
61 if (!insert_result.second) {
62 CHECK_EQ(this_buffer, insert_result.first->second);
63 }
64 }
65}
66
Austin Schuh6b6dfa52019-06-12 20:16:20 -070067// Tests that watcher can receive messages from a sender.
Parker Schuhe4a70d62017-12-27 20:10:20 -080068// Also tests that OnRun() works.
69TEST_P(AbstractEventLoopTest, Basic) {
70 auto loop1 = Make();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070071 auto loop2 = MakePrimary();
72
Alex Perrycb7da4b2019-08-28 19:35:56 -070073 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
Austin Schuh6b6dfa52019-06-12 20:16:20 -070074
75 bool happened = false;
76
77 loop2->OnRun([&]() {
78 happened = true;
79
Alex Perrycb7da4b2019-08-28 19:35:56 -070080 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
81 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
82 builder.add_value(200);
83 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -070084 });
85
86 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070087 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -070088 this->Exit();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070089 });
90
91 EXPECT_FALSE(happened);
92 Run();
93 EXPECT_TRUE(happened);
94}
95
Brian Silverman341b57e2020-06-23 16:23:18 -070096// Tests that watcher can receive messages from a sender, sent via SendDetached.
97TEST_P(AbstractEventLoopTest, BasicSendDetached) {
98 auto loop1 = Make();
99 auto loop2 = MakePrimary();
100
101 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
102
103 FlatbufferDetachedBuffer<TestMessage> detached =
104 flatbuffers::DetachedBuffer();
105 {
106 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
107 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
108 builder.add_value(100);
109 detached = msg.Detach(builder.Finish());
110 }
111 detached = flatbuffers::DetachedBuffer();
112 {
113 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
114 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
115 builder.add_value(200);
116 detached = msg.Detach(builder.Finish());
117 }
118 ASSERT_TRUE(sender.SendDetached(std::move(detached)));
119
120 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
121 ASSERT_TRUE(fetcher.Fetch());
122 EXPECT_EQ(fetcher->value(), 200);
123}
124
Brian Silverman6b8a3c32020-03-06 11:26:14 -0800125// Verifies that a no-arg watcher will not have a data pointer.
126TEST_P(AbstractEventLoopTest, NoArgNoData) {
127 auto loop1 = Make();
128 auto loop2 = MakePrimary();
129
130 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
131
132 bool happened = false;
133
134 loop2->OnRun([&]() {
135 happened = true;
136
137 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
138 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
139 ASSERT_TRUE(msg.Send(builder.Finish()));
140 });
141
142 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
143 EXPECT_GT(loop2->context().size, 0u);
144 EXPECT_EQ(nullptr, loop2->context().data);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700145 EXPECT_EQ(-1, loop2->context().buffer_index);
Brian Silverman6b8a3c32020-03-06 11:26:14 -0800146 this->Exit();
147 });
148
149 EXPECT_FALSE(happened);
150 Run();
151 EXPECT_TRUE(happened);
152}
153
Brian Silverman454bc112020-03-05 14:21:25 -0800154// Tests that no-arg watcher can receive messages from a sender.
155// Also tests that OnRun() works.
156TEST_P(AbstractEventLoopTest, BasicNoArg) {
157 auto loop1 = Make();
158 auto loop2 = MakePrimary();
159
160 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
161
162 bool happened = false;
163
164 loop2->OnRun([&]() {
165 happened = true;
166
167 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
168 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
169 builder.add_value(200);
170 ASSERT_TRUE(msg.Send(builder.Finish()));
171 });
172
173 aos::Fetcher<TestMessage> fetcher = loop2->MakeFetcher<TestMessage>("/test");
174 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
175 ASSERT_TRUE(fetcher.Fetch());
176 EXPECT_EQ(fetcher->value(), 200);
177 this->Exit();
178 });
179
180 EXPECT_FALSE(happened);
181 Run();
182 EXPECT_TRUE(happened);
183}
184
185// Tests that a watcher can be created with an std::function.
186TEST_P(AbstractEventLoopTest, BasicFunction) {
187 auto loop1 = Make();
188 auto loop2 = MakePrimary();
189
190 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
191
192 bool happened = false;
193
194 loop2->OnRun([&]() {
195 happened = true;
196
197 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()));
201 });
202
203 loop2->MakeWatcher("/test", std::function<void(const TestMessage &)>(
204 [&](const TestMessage &message) {
205 EXPECT_EQ(message.value(), 200);
206 this->Exit();
207 }));
208
209 EXPECT_FALSE(happened);
210 Run();
211 EXPECT_TRUE(happened);
212}
213
Brian Silverman0fc69932020-01-24 21:54:02 -0800214// Tests that watcher can receive messages from two senders.
215// Also tests that OnRun() works.
216TEST_P(AbstractEventLoopTest, BasicTwoSenders) {
217 auto loop1 = Make();
218 auto loop2 = MakePrimary();
219
220 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
221 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
222
223 bool happened = false;
224
225 loop2->OnRun([&]() {
226 happened = true;
227
228 {
229 aos::Sender<TestMessage>::Builder msg = sender1.MakeBuilder();
230 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
231 builder.add_value(200);
232 ASSERT_TRUE(msg.Send(builder.Finish()));
233 }
234 {
235 aos::Sender<TestMessage>::Builder msg = sender2.MakeBuilder();
236 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
237 builder.add_value(200);
238 ASSERT_TRUE(msg.Send(builder.Finish()));
239 }
240 });
241
242 int messages_received = 0;
243 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
244 EXPECT_EQ(message.value(), 200);
245 this->Exit();
246 ++messages_received;
247 });
248
249 EXPECT_FALSE(happened);
250 Run();
251 EXPECT_TRUE(happened);
252 EXPECT_EQ(messages_received, 2);
253}
254
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700255// Tests that a fetcher can fetch from a sender.
256// Also tests that OnRun() works.
257TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
258 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800259 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700260 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800261
262 auto sender = loop1->MakeSender<TestMessage>("/test");
263
264 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
265
Austin Schuhbbce72d2019-05-26 15:11:46 -0700266 EXPECT_FALSE(fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -0800267 EXPECT_EQ(fetcher.get(), nullptr);
268
Austin Schuhad154822019-12-27 15:45:13 -0800269 EXPECT_EQ(fetcher.context().monotonic_event_time, monotonic_clock::min_time);
270 EXPECT_EQ(fetcher.context().monotonic_remote_time, monotonic_clock::min_time);
271 EXPECT_EQ(fetcher.context().realtime_event_time, realtime_clock::min_time);
272 EXPECT_EQ(fetcher.context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800273 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
274 EXPECT_EQ(fetcher.context().size, 0u);
275 EXPECT_EQ(fetcher.context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700276 EXPECT_EQ(fetcher.context().buffer_index, -1);
Austin Schuhbbce72d2019-05-26 15:11:46 -0700277
Alex Perrycb7da4b2019-08-28 19:35:56 -0700278 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
279 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
280 builder.add_value(200);
281 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700282
283 EXPECT_TRUE(fetcher.Fetch());
284 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700285 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -0800286
287 const chrono::milliseconds kEpsilon(100);
288
Austin Schuhad154822019-12-27 15:45:13 -0800289 const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
290 const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
291 EXPECT_EQ(fetcher.context().monotonic_event_time,
292 fetcher.context().monotonic_remote_time);
293 EXPECT_EQ(fetcher.context().realtime_event_time,
294 fetcher.context().realtime_remote_time);
295
296 EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
297 EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
298 EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
299 EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800300 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
301 EXPECT_EQ(fetcher.context().size, 20u);
302 EXPECT_NE(fetcher.context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700303 if (read_method() == ReadMethod::PIN) {
304 EXPECT_GE(fetcher.context().buffer_index, 0);
305 EXPECT_LT(fetcher.context().buffer_index,
306 loop2->NumberBuffers(fetcher.channel()));
307 } else {
308 EXPECT_EQ(fetcher.context().buffer_index, -1);
309 }
Parker Schuhe4a70d62017-12-27 20:10:20 -0800310}
311
Austin Schuh3578a2e2019-05-25 18:17:59 -0700312// Tests that watcher will receive all messages sent if they are sent after
313// initialization and before running.
314TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
315 auto loop1 = Make();
316 auto loop2 = MakePrimary();
317
318 auto sender = loop1->MakeSender<TestMessage>("/test");
319
320 ::std::vector<int> values;
321
322 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700323 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700324 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700325 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700326 }
327 });
328
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700329 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -0700330 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700331 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
332 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
333 builder.add_value(199);
334 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700335 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700336
337 loop2->OnRun([&]() {
338 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700339 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
340 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
341 builder.add_value(200);
342 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700343 }
344 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700345 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
346 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
347 builder.add_value(201);
348 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700349 }
350 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700351
352 Run();
353
354 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
355}
356
357// Tests that watcher will not receive messages sent before the watcher is
358// created.
359TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
360 auto loop1 = Make();
361 auto loop2 = MakePrimary();
362
363 auto sender = loop1->MakeSender<TestMessage>("/test");
364
365 ::std::vector<int> values;
366
367 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700368 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
369 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
370 builder.add_value(200);
371 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700372 }
373 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700374 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
375 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
376 builder.add_value(201);
377 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700378 }
379
380 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700381 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700382 });
383
384 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700385 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700386 loop2->OnRun([&test_timer, &loop2]() {
387 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
388 });
389
390 Run();
391 EXPECT_EQ(0, values.size());
392}
393
Austin Schuhbbce72d2019-05-26 15:11:46 -0700394// Tests that FetchNext gets all the messages sent after it is constructed.
395TEST_P(AbstractEventLoopTest, FetchNext) {
396 auto loop1 = Make();
397 auto loop2 = MakePrimary();
398
399 auto sender = loop1->MakeSender<TestMessage>("/test");
400 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
401
402 ::std::vector<int> values;
403
404 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700405 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
406 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
407 builder.add_value(200);
408 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700409 }
410 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700411 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
412 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
413 builder.add_value(201);
414 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700415 }
416
417 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700418 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700419 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700420 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700421 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700422 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700423 });
424
425 loop2->OnRun([&test_timer, &loop2]() {
426 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
427 });
428
429 Run();
430 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
431}
432
433// Tests that FetchNext gets no messages sent before it is constructed.
434TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
435 auto loop1 = Make();
436 auto loop2 = MakePrimary();
437
438 auto sender = loop1->MakeSender<TestMessage>("/test");
439
440 ::std::vector<int> values;
441
442 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700443 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
444 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
445 builder.add_value(200);
446 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700447 }
448 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700449 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
450 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
451 builder.add_value(201);
452 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700453 }
454
455 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
456
457 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700458 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700459 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700460 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700461 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700462 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700463 });
464
465 loop2->OnRun([&test_timer, &loop2]() {
466 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
467 });
468
469 Run();
470 EXPECT_THAT(0, values.size());
471}
472
473// Tests that Fetch returns the last message created before the loop was
474// started.
475TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
476 auto loop1 = Make();
477 auto loop2 = MakePrimary();
478
479 auto sender = loop1->MakeSender<TestMessage>("/test");
480
481 ::std::vector<int> values;
482
483 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700484 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
485 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
486 builder.add_value(200);
487 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700488 }
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(201);
493 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700494 }
495
496 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
497
498 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700499 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700500 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700501 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700502 }
503 // Do it again to make sure we don't double fetch.
504 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700505 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700506 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700507 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700508 });
509
510 loop2->OnRun([&test_timer, &loop2]() {
511 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
512 });
513
514 Run();
515 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
516}
517
518// Tests that Fetch and FetchNext interleave as expected.
519TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
520 auto loop1 = Make();
521 auto loop2 = MakePrimary();
522
523 auto sender = loop1->MakeSender<TestMessage>("/test");
524
525 ::std::vector<int> values;
526
527 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700528 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
529 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
530 builder.add_value(200);
531 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700532 }
533 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700534 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
535 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
536 builder.add_value(201);
537 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700538 }
539
540 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
541
542 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700543 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700544 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700545 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700546 }
547
548 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700549 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
550 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
551 builder.add_value(202);
552 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700553 }
554 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700555 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
556 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
557 builder.add_value(203);
558 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700559 }
560 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700561 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
562 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
563 builder.add_value(204);
564 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700565 }
566
567 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700568 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700569 }
570
571 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700572 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700573 }
574
Austin Schuh9fe68f72019-08-10 19:32:03 -0700575 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700576 });
577
578 loop2->OnRun([&test_timer, &loop2]() {
579 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
580 });
581
582 Run();
583 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
584}
585
Austin Schuh3115a202019-05-27 21:02:14 -0700586// Tests that FetchNext behaves correctly when we get two messages in the queue
587// but don't consume the first until after the second has been sent.
588TEST_P(AbstractEventLoopTest, FetchNextTest) {
Austin Schuh3115a202019-05-27 21:02:14 -0700589 auto send_loop = Make();
590 auto fetch_loop = Make();
591 auto sender = send_loop->MakeSender<TestMessage>("/test");
592 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
593
594 {
Tyler Chatow67ddb032020-01-12 14:30:04 -0800595 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
596 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
597 builder.add_value(100);
598 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700599 }
600
601 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700602 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
603 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
604 builder.add_value(200);
605 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700606 }
607
608 ASSERT_TRUE(fetcher.FetchNext());
609 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700610 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700611
612 ASSERT_TRUE(fetcher.FetchNext());
613 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700614 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700615
616 // When we run off the end of the queue, expect to still have the old message:
617 ASSERT_FALSE(fetcher.FetchNext());
618 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700619 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700620}
621
Brian Silverman77162972020-08-12 19:52:40 -0700622// Verify that a fetcher still holds its data, even after falling behind.
623TEST_P(AbstractEventLoopTest, FetcherBehindData) {
624 auto send_loop = Make();
625 auto fetch_loop = Make();
626 auto sender = send_loop->MakeSender<TestMessage>("/test");
627 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
628 {
629 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
630 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
631 builder.add_value(1);
632 ASSERT_TRUE(msg.Send(builder.Finish()));
633 }
634 ASSERT_TRUE(fetcher.Fetch());
635 EXPECT_EQ(1, fetcher.get()->value());
636 for (int i = 0; i < 300; ++i) {
637 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
638 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
639 builder.add_value(i + 2);
640 ASSERT_TRUE(msg.Send(builder.Finish()));
641 }
642 EXPECT_EQ(1, fetcher.get()->value());
643}
644
645// Try a bunch of orderings of operations with fetchers and senders. Verify that
646// all the fetchers have the correct data at each step.
647TEST_P(AbstractEventLoopTest, FetcherPermutations) {
648 for (int max_save = 0; max_save < 5; ++max_save) {
649 SCOPED_TRACE("max_save=" + std::to_string(max_save));
650
651 auto send_loop = Make();
652 auto fetch_loop = Make();
653 auto sender = send_loop->MakeSender<TestMessage>("/test");
654 const auto send_message = [&sender](int i) {
655 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
656 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
657 builder.add_value(i);
658 ASSERT_TRUE(msg.Send(builder.Finish()));
659 };
660 std::vector<Fetcher<TestMessage>> fetchers;
661 for (int i = 0; i < 10; ++i) {
662 fetchers.emplace_back(fetch_loop->MakeFetcher<TestMessage>("/test"));
663 }
664 send_message(1);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700665 const auto verify_buffers = [&]() {
666 std::vector<std::reference_wrapper<const Fetcher<TestMessage>>>
667 fetchers_copy;
668 for (const auto &fetcher : fetchers) {
669 fetchers_copy.emplace_back(fetcher);
670 }
671 std::vector<std::reference_wrapper<const Sender<TestMessage>>>
672 senders_copy;
673 senders_copy.emplace_back(sender);
674 VerifyBuffers(send_loop->NumberBuffers(sender.channel()), fetchers_copy,
675 senders_copy);
676 };
Brian Silverman77162972020-08-12 19:52:40 -0700677 for (auto &fetcher : fetchers) {
678 ASSERT_TRUE(fetcher.Fetch());
Brian Silverman4f4e0612020-08-12 19:54:41 -0700679 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700680 EXPECT_EQ(1, fetcher.get()->value());
681 }
682
683 for (int save = 1; save <= max_save; ++save) {
684 SCOPED_TRACE("save=" + std::to_string(save));
685 send_message(100 + save);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700686 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700687 for (size_t i = 0; i < fetchers.size() - save; ++i) {
688 SCOPED_TRACE("fetcher=" + std::to_string(i));
689 ASSERT_TRUE(fetchers[i].Fetch());
Brian Silverman4f4e0612020-08-12 19:54:41 -0700690 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700691 EXPECT_EQ(100 + save, fetchers[i].get()->value());
692 }
693 for (size_t i = fetchers.size() - save; i < fetchers.size() - 1; ++i) {
694 SCOPED_TRACE("fetcher=" + std::to_string(i));
695 EXPECT_EQ(100 + (fetchers.size() - 1 - i), fetchers[i].get()->value());
696 }
697 EXPECT_EQ(1, fetchers.back().get()->value());
698 }
699
700 for (int i = 0; i < 300; ++i) {
701 send_message(200 + i);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700702 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700703 }
704
705 for (size_t i = 0; i < fetchers.size() - max_save; ++i) {
706 SCOPED_TRACE("fetcher=" + std::to_string(i));
707 if (max_save > 0) {
708 EXPECT_EQ(100 + max_save, fetchers[i].get()->value());
709 } else {
710 EXPECT_EQ(1, fetchers[i].get()->value());
711 }
712 }
713 for (size_t i = fetchers.size() - max_save; i < fetchers.size() - 1; ++i) {
714 SCOPED_TRACE("fetcher=" + std::to_string(i));
715 EXPECT_EQ(100 + (fetchers.size() - 1 - i), fetchers[i].get()->value());
716 }
717 EXPECT_EQ(1, fetchers.back().get()->value());
718 }
719}
720
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800721// Verify that making a fetcher and watcher for "/test" succeeds.
722TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800723 auto loop = Make();
724 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800725 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800726}
727
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800728// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800729TEST_P(AbstractEventLoopTest, TwoFetcher) {
730 auto loop = Make();
731 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800732 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800733}
734
Alex Perrycb7da4b2019-08-28 19:35:56 -0700735// Verify that registering a watcher for an invalid channel name dies.
736TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
737 auto loop = Make();
738 EXPECT_DEATH(
739 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
740 "/test/invalid");
Brian Silverman454bc112020-03-05 14:21:25 -0800741 EXPECT_DEATH(
742 { loop->MakeNoArgWatcher<TestMessage>("/test/invalid", [&]() {}); },
743 "/test/invalid");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700744}
745
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800746// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700747TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800748 auto loop = Make();
749 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800750 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
751 "/test");
Brian Silverman454bc112020-03-05 14:21:25 -0800752 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
753}
754
755// Verify that registering a no-arg watcher twice for "/test" fails.
756TEST_P(AbstractEventLoopDeathTest, TwoNoArgWatcher) {
757 auto loop = Make();
758 loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {});
759 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
760 "/test");
761 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800762}
763
Austin Schuh3115a202019-05-27 21:02:14 -0700764// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700765TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700766 auto loop = MakePrimary();
767 // Confirm that runtime priority calls work when not realtime.
768 loop->SetRuntimeRealtimePriority(5);
769
770 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
771
772 EXPECT_DEATH(Run(), "realtime");
773}
774
Brian Silverman6a54ff32020-04-28 16:41:39 -0700775// Verify that SetRuntimeAffinity fails while running.
776TEST_P(AbstractEventLoopDeathTest, SetRuntimeAffinity) {
777 auto loop = MakePrimary();
778 // Confirm that runtime priority calls work when not running.
779 loop->SetRuntimeAffinity(MakeCpusetFromCpus({0}));
780
781 loop->OnRun([&]() { loop->SetRuntimeAffinity(MakeCpusetFromCpus({1})); });
782
783 EXPECT_DEATH(Run(), "Cannot set affinity while running");
784}
785
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800786// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700787TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800788 auto loop = Make();
789 auto sender = loop->MakeSender<TestMessage>("/test");
790 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
791 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800792}
793
Austin Schuhe516ab02020-05-06 21:37:04 -0700794// Verify that creating too many senders fails.
795TEST_P(AbstractEventLoopDeathTest, TooManySenders) {
796 auto loop = Make();
797 std::vector<aos::Sender<TestMessage>> senders;
798 for (int i = 0; i < 10; ++i) {
799 senders.emplace_back(loop->MakeSender<TestMessage>("/test"));
800 }
801 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); },
802 "Failed to create sender on \\{ \"name\": \"/test\", \"type\": "
Brian Silverman77162972020-08-12 19:52:40 -0700803 "\"aos.TestMessage\"[^}]*\\ }, too many senders.");
804}
805
806// Verify that creating too many fetchers fails.
807TEST_P(AbstractEventLoopDeathTest, TooManyFetchers) {
808 if (read_method() != ReadMethod::PIN) {
809 // Other read methods don't limit the number of readers, so just skip this.
810 return;
811 }
812
813 auto loop = Make();
814 std::vector<aos::Fetcher<TestMessage>> fetchers;
815 for (int i = 0; i < 10; ++i) {
816 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
817 }
818 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
819 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
820 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
821}
822
823// Verify that creating too many fetchers, split between two event loops, fails.
824TEST_P(AbstractEventLoopDeathTest, TooManyFetchersTwoLoops) {
825 if (read_method() != ReadMethod::PIN) {
826 // Other read methods don't limit the number of readers, so just skip this.
827 return;
828 }
829
830 auto loop = Make();
831 auto loop2 = Make();
832 std::vector<aos::Fetcher<TestMessage>> fetchers;
833 for (int i = 0; i < 5; ++i) {
834 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
835 fetchers.emplace_back(loop2->MakeFetcher<TestMessage>("/test"));
836 }
837 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
838 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
839 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
840}
841
842// Verify that creating too many watchers fails.
843TEST_P(AbstractEventLoopDeathTest, TooManyWatchers) {
844 if (read_method() != ReadMethod::PIN) {
845 // Other read methods don't limit the number of readers, so just skip this.
846 return;
847 }
848
849 std::vector<std::unique_ptr<EventLoop>> loops;
850 for (int i = 0; i < 10; ++i) {
851 loops.emplace_back(Make());
852 loops.back()->MakeWatcher("/test", [](const TestMessage &) {});
853 }
854 EXPECT_DEATH({ Make()->MakeWatcher("/test", [](const TestMessage &) {}); },
855 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
856 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
857}
858
859// Verify that creating too many watchers and fetchers combined fails.
860TEST_P(AbstractEventLoopDeathTest, TooManyWatchersAndFetchers) {
861 if (read_method() != ReadMethod::PIN) {
862 // Other read methods don't limit the number of readers, so just skip this.
863 return;
864 }
865
866 auto loop = Make();
867 std::vector<aos::Fetcher<TestMessage>> fetchers;
868 std::vector<std::unique_ptr<EventLoop>> loops;
869 for (int i = 0; i < 5; ++i) {
870 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
871 loops.emplace_back(Make());
872 loops.back()->MakeWatcher("/test", [](const TestMessage &) {});
873 }
874 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
875 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
876 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
Austin Schuhe516ab02020-05-06 21:37:04 -0700877}
878
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700879// Verify that we can't create a sender inside OnRun.
880TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
881 auto loop1 = MakePrimary();
882
883 loop1->OnRun(
884 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
885
886 EXPECT_DEATH(Run(), "running");
887}
888
889// Verify that we can't create a watcher inside OnRun.
890TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
891 auto loop1 = MakePrimary();
892
893 loop1->OnRun(
894 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
895
896 EXPECT_DEATH(Run(), "running");
897}
898
Brian Silverman454bc112020-03-05 14:21:25 -0800899// Verify that we can't create a no-arg watcher inside OnRun.
900TEST_P(AbstractEventLoopDeathTest, NoArgWatcherInOnRun) {
901 auto loop1 = MakePrimary();
902
903 loop1->OnRun(
904 [&]() { loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {}); });
905
906 EXPECT_DEATH(Run(), "running");
907}
908
Parker Schuhe4a70d62017-12-27 20:10:20 -0800909// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800910TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
911 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700912 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800913
Austin Schuh3578a2e2019-05-25 18:17:59 -0700914 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
915 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700916 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700917 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700918 });
919
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800920 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700921
922 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700923 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
924 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
925 builder.add_value(200);
926 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700927 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800928
Austin Schuh44019f92019-05-19 19:58:27 -0700929 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800930}
931
Neil Balch229001a2018-01-07 18:22:52 -0800932// Verify that timer intervals and duration function properly.
933TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800934 // Force a slower rate so we are guarenteed to have reports for our timer.
935 FLAGS_timing_report_ms = 2000;
936
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800937 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800938
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800939 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800940 auto loop2 = Make();
941
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800942 ::std::vector<::aos::monotonic_clock::time_point> times;
943 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
944
Austin Schuh39788ff2019-12-01 18:22:57 -0800945 Fetcher<timing::Report> report_fetcher =
946 loop2->MakeFetcher<timing::Report>("/aos");
947 EXPECT_FALSE(report_fetcher.Fetch());
948
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800949 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
950 times.push_back(loop->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800951 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
952 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
953 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800954 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
955 EXPECT_EQ(loop->context().size, 0u);
956 EXPECT_EQ(loop->context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700957 EXPECT_EQ(loop->context().buffer_index, -1);
Austin Schuh39788ff2019-12-01 18:22:57 -0800958
Austin Schuhad154822019-12-27 15:45:13 -0800959 expected_times.push_back(loop->context().monotonic_event_time);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800960 if (times.size() == kCount) {
961 this->Exit();
962 }
Neil Balch229001a2018-01-07 18:22:52 -0800963 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800964 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800965
Austin Schuh39788ff2019-12-01 18:22:57 -0800966 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700967 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800968 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
969
Austin Schuh44019f92019-05-19 19:58:27 -0700970 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800971
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800972 // Confirm that we got both the right number of samples, and it's odd.
973 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
974 EXPECT_EQ(times.size(), expected_times.size());
975 EXPECT_EQ((times.size() % 2), 1);
976
977 // Grab the middle sample.
978 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
979
980 // Add up all the delays of all the times.
981 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
982 for (const ::aos::monotonic_clock::time_point time : times) {
983 sum += time - average_time;
984 }
985
986 // Average and add to the middle to find the average time.
987 sum /= times.size();
988 average_time += sum;
989
990 // Compute the offset from the average and the expected average. It
991 // should be pretty close to 0.
992 const ::aos::monotonic_clock::duration remainder =
993 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
994
995 const chrono::milliseconds kEpsilon(100);
996 EXPECT_LT(remainder, +kEpsilon);
997 EXPECT_GT(remainder, -kEpsilon);
998
999 // Make sure that the average duration is close to 1 second.
1000 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1001 times.front())
1002 .count() /
1003 static_cast<double>(times.size() - 1),
1004 1.0, 0.1);
1005
1006 // Confirm that the ideal wakeup times increment correctly.
1007 for (size_t i = 1; i < expected_times.size(); ++i) {
1008 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1009 }
1010
1011 for (size_t i = 0; i < expected_times.size(); ++i) {
1012 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
1013 chrono::seconds(0));
1014 }
1015
1016 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1017 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001018
1019 // And, since we are here, check that the timing report makes sense.
1020 // Start by looking for our event loop's timing.
1021 FlatbufferDetachedBuffer<timing::Report> report =
1022 FlatbufferDetachedBuffer<timing::Report>::Empty();
1023 while (report_fetcher.FetchNext()) {
1024 if (report_fetcher->name()->string_view() == "primary") {
1025 report = CopyFlatBuffer(report_fetcher.get());
1026 }
1027 }
1028
1029 // Confirm that we have the right number of reports, and the contents are
1030 // sane.
Ravago Jonescf453ab2020-05-06 21:14:53 -07001031 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001032
1033 EXPECT_EQ(report.message().name()->string_view(), "primary");
1034
1035 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001036 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001037
1038 ASSERT_NE(report.message().timers(), nullptr);
1039 EXPECT_EQ(report.message().timers()->size(), 2);
1040
1041 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
1042 "Test loop");
1043 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
1044
1045 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
1046 "timing_reports");
1047 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
1048
1049 // Make sure there is a single phased loop report with our report in it.
1050 ASSERT_EQ(report.message().phased_loops(), nullptr);
Neil Balch229001a2018-01-07 18:22:52 -08001051}
1052
1053// Verify that we can change a timer's parameters during execution.
1054TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -07001055 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -08001056 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
1057
1058 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
1059 iteration_list.push_back(loop->monotonic_now());
1060 });
1061
1062 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
1063 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
1064 });
1065
Neil Balch229001a2018-01-07 18:22:52 -08001066 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
1067 modifier_timer->Setup(loop->monotonic_now() +
1068 ::std::chrono::milliseconds(45));
1069 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -07001070 Run();
Neil Balch229001a2018-01-07 18:22:52 -08001071
1072 EXPECT_EQ(iteration_list.size(), 7);
1073}
1074
1075// Verify that we can disable a timer during execution.
1076TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -07001077 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -08001078 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
1079
1080 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
1081 iteration_list.push_back(loop->monotonic_now());
1082 });
1083
Tyler Chatow67ddb032020-01-12 14:30:04 -08001084 auto ender_timer = loop->AddTimer([&test_timer]() { test_timer->Disable(); });
Neil Balch229001a2018-01-07 18:22:52 -08001085
1086 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
Tyler Chatow67ddb032020-01-12 14:30:04 -08001087 ender_timer->Setup(loop->monotonic_now() + ::std::chrono::milliseconds(45));
Neil Balch229001a2018-01-07 18:22:52 -08001088 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -07001089 Run();
Neil Balch229001a2018-01-07 18:22:52 -08001090
1091 EXPECT_EQ(iteration_list.size(), 3);
1092}
Austin Schuh7267c532019-05-19 19:55:53 -07001093
Brian Silvermanaf9a4d82020-10-06 15:10:58 -07001094// Verify that a timer can disable itself.
1095//
1096// TODO(Brian): Do something similar with phased loops, both with a quick
1097// handler and a handler that would miss a cycle except it got deferred. Current
1098// behavior doing that is a mess.
1099TEST_P(AbstractEventLoopTest, TimerDisableSelf) {
1100 auto loop = MakePrimary();
1101
1102 int count = 0;
1103 aos::TimerHandler *test_timer;
1104 test_timer = loop->AddTimer([&count, &test_timer]() {
1105 ++count;
1106 test_timer->Disable();
1107 });
1108
1109 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
1110 EndEventLoop(loop.get(), ::std::chrono::milliseconds(80));
1111 Run();
1112
1113 EXPECT_EQ(count, 1);
1114}
1115
Brian Silvermanbd405c02020-06-23 16:25:23 -07001116// Verify that we can disable a timer during execution of another timer
1117// scheduled for the same time, with one ordering of creation for the timers.
1118//
1119// Also schedule some more events to reshuffle the heap in EventLoop used for
1120// tracking events to change up the order. This used to segfault
1121// SimulatedEventLoop.
1122TEST_P(AbstractEventLoopTest, TimerDisableOther) {
1123 for (bool creation_order : {true, false}) {
1124 for (bool setup_order : {true, false}) {
1125 for (int shuffle_events = 0; shuffle_events < 5; ++shuffle_events) {
1126 auto loop = MakePrimary();
1127 aos::TimerHandler *test_timer, *ender_timer;
1128 if (creation_order) {
1129 test_timer = loop->AddTimer([]() {});
1130 ender_timer =
1131 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1132 } else {
1133 ender_timer =
1134 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1135 test_timer = loop->AddTimer([]() {});
1136 }
1137
1138 const auto start = loop->monotonic_now();
1139
1140 for (int i = 0; i < shuffle_events; ++i) {
1141 loop->AddTimer([]() {})->Setup(start + std::chrono::milliseconds(10));
1142 }
1143
1144 if (setup_order) {
1145 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1146 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1147 } else {
1148 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1149 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1150 }
1151 EndEventLoop(loop.get(), ::std::chrono::milliseconds(40));
1152 Run();
1153 }
1154 }
1155 }
1156}
1157
Austin Schuh54cf95f2019-11-29 13:14:18 -08001158// Verifies that the event loop implementations detect when Channel is not a
1159// pointer into confguration()
1160TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
1161 auto loop = MakePrimary();
1162
Tyler Chatow67ddb032020-01-12 14:30:04 -08001163 const Channel *channel = configuration::GetChannel(
1164 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
Austin Schuh54cf95f2019-11-29 13:14:18 -08001165
1166 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
1167
1168 EXPECT_DEATH(
1169 { loop->MakeRawSender(&channel_copy.message()); },
1170 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1171
1172 EXPECT_DEATH(
1173 { loop->MakeRawFetcher(&channel_copy.message()); },
1174 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1175
1176 EXPECT_DEATH(
1177 {
1178 loop->MakeRawWatcher(&channel_copy.message(),
1179 [](const Context, const void *) {});
1180 },
1181 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1182}
1183
Austin Schuhd54780b2020-10-03 16:26:02 -07001184// Verifies that the event loop implementations detect when Channel has an
1185// invalid alignment.
1186TEST_P(AbstractEventLoopDeathTest, InvalidChannelAlignment) {
1187 const char *const kError = "multiple of alignment";
1188 InvalidChannelAlignment();
1189
1190 auto loop = MakePrimary();
1191
1192 const Channel *channel = configuration::GetChannel(
1193 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
1194
1195 EXPECT_DEATH({ loop->MakeRawSender(channel); }, kError);
1196 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); }, kError);
1197
1198 EXPECT_DEATH({ loop->MakeRawFetcher(channel); }, kError);
1199 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); }, kError);
1200
1201 EXPECT_DEATH(
1202 { loop->MakeRawWatcher(channel, [](const Context &, const void *) {}); },
1203 kError);
1204 EXPECT_DEATH({ loop->MakeRawNoArgWatcher(channel, [](const Context &) {}); },
1205 kError);
1206
1207 EXPECT_DEATH({ loop->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1208 kError);
1209 EXPECT_DEATH({ loop->MakeWatcher("/test", [](const TestMessage &) {}); },
1210 kError);
1211}
1212
Brian Silverman454bc112020-03-05 14:21:25 -08001213// Verify that the send time on a message is roughly right when using a watcher.
Austin Schuh7267c532019-05-19 19:55:53 -07001214TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -07001215 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -07001216 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -08001217 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -07001218 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
1219
1220 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -07001221 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1222 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1223 builder.add_value(200);
1224 ASSERT_TRUE(msg.Send(builder.Finish()));
1225 });
1226
Austin Schuhad154822019-12-27 15:45:13 -08001227 bool triggered = false;
Brian Silverman454bc112020-03-05 14:21:25 -08001228 loop1->MakeWatcher("/test", [&](const TestMessage &msg) {
Austin Schuhad154822019-12-27 15:45:13 -08001229 // Confirm that the data pointer makes sense from a watcher, and all the
1230 // timestamps look right.
1231 EXPECT_GT(&msg, loop1->context().data);
1232 EXPECT_EQ(loop1->context().monotonic_remote_time,
1233 loop1->context().monotonic_event_time);
1234 EXPECT_EQ(loop1->context().realtime_remote_time,
1235 loop1->context().realtime_event_time);
1236
1237 const aos::monotonic_clock::time_point monotonic_now =
1238 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -08001239 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001240
1241 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1242 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1243 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1244 monotonic_now);
1245 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1246 realtime_now);
1247
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001248 EXPECT_LT(&msg, reinterpret_cast<const void *>(
1249 reinterpret_cast<const char *>(loop1->context().data) +
Austin Schuhad154822019-12-27 15:45:13 -08001250 loop1->context().size));
Brian Silverman4f4e0612020-08-12 19:54:41 -07001251 if (read_method() == ReadMethod::PIN) {
1252 EXPECT_GE(loop1->context().buffer_index, 0);
1253 EXPECT_LT(loop1->context().buffer_index,
1254 loop1->NumberBuffers(
1255 configuration::GetChannel(loop1->configuration(), "/test",
1256 "aos.TestMessage", "", nullptr)));
1257 } else {
1258 EXPECT_EQ(-1, loop1->context().buffer_index);
1259 }
Austin Schuhad154822019-12-27 15:45:13 -08001260 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -07001261 });
1262
1263 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1264
1265 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -07001266 Run();
Austin Schuh7267c532019-05-19 19:55:53 -07001267
Austin Schuhad154822019-12-27 15:45:13 -08001268 EXPECT_TRUE(triggered);
1269
Brian Silverman454bc112020-03-05 14:21:25 -08001270 ASSERT_TRUE(fetcher.Fetch());
1271
1272 monotonic_clock::duration monotonic_time_offset =
1273 fetcher.context().monotonic_event_time -
1274 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1275 realtime_clock::duration realtime_time_offset =
1276 fetcher.context().realtime_event_time -
1277 (loop1->realtime_now() - ::std::chrono::seconds(1));
1278
1279 EXPECT_EQ(fetcher.context().realtime_event_time,
1280 fetcher.context().realtime_remote_time);
1281 EXPECT_EQ(fetcher.context().monotonic_event_time,
1282 fetcher.context().monotonic_remote_time);
1283
1284 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1285 << ": Got "
1286 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1287 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1288 // Confirm that the data pointer makes sense.
1289 EXPECT_GT(fetcher.get(), fetcher.context().data);
1290 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001291 reinterpret_cast<const void *>(
1292 reinterpret_cast<const char *>(fetcher.context().data) +
Brian Silverman454bc112020-03-05 14:21:25 -08001293 fetcher.context().size));
1294 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1295 << ": Got "
1296 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1297 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1298
1299 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1300 << ": Got "
1301 << fetcher.context().realtime_event_time.time_since_epoch().count()
1302 << " expected " << loop1->realtime_now().time_since_epoch().count();
1303 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1304 << ": Got "
1305 << fetcher.context().realtime_event_time.time_since_epoch().count()
1306 << " expected " << loop1->realtime_now().time_since_epoch().count();
1307}
1308
1309// Verify that the send time on a message is roughly right when using a no-arg
1310// watcher. To get a message, we need to use a fetcher to actually access the
1311// message. This is also the main use case for no-arg fetchers.
1312TEST_P(AbstractEventLoopTest, MessageSendTimeNoArg) {
1313 auto loop1 = MakePrimary();
1314 auto loop2 = Make();
1315 auto sender = loop2->MakeSender<TestMessage>("/test");
1316 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1317
1318 auto test_timer = loop1->AddTimer([&sender]() {
1319 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1320 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1321 builder.add_value(200);
1322 ASSERT_TRUE(msg.Send(builder.Finish()));
1323 });
1324
1325 bool triggered = false;
1326 loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {
1327 // Confirm that we can indeed use a fetcher on this channel from this
1328 // context, and it results in a sane data pointer and timestamps.
1329 ASSERT_TRUE(fetcher.Fetch());
1330
1331 EXPECT_EQ(loop1->context().monotonic_remote_time,
1332 loop1->context().monotonic_event_time);
1333 EXPECT_EQ(loop1->context().realtime_remote_time,
1334 loop1->context().realtime_event_time);
1335
1336 const aos::monotonic_clock::time_point monotonic_now =
1337 loop1->monotonic_now();
1338 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
1339
1340 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1341 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1342 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1343 monotonic_now);
1344 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1345 realtime_now);
1346
1347 triggered = true;
1348 });
1349
1350 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1351
1352 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
1353 Run();
1354
1355 ASSERT_TRUE(triggered);
Austin Schuh7267c532019-05-19 19:55:53 -07001356
Alex Perrycb7da4b2019-08-28 19:35:56 -07001357 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001358 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001359 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1360 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001361 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001362 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -07001363
Austin Schuhad154822019-12-27 15:45:13 -08001364 EXPECT_EQ(fetcher.context().realtime_event_time,
1365 fetcher.context().realtime_remote_time);
1366 EXPECT_EQ(fetcher.context().monotonic_event_time,
1367 fetcher.context().monotonic_remote_time);
1368
Alex Perrycb7da4b2019-08-28 19:35:56 -07001369 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1370 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001371 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -07001372 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001373 // Confirm that the data pointer makes sense.
1374 EXPECT_GT(fetcher.get(), fetcher.context().data);
1375 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001376 reinterpret_cast<const void *>(
1377 reinterpret_cast<const char *>(fetcher.context().data) +
Alex Perrycb7da4b2019-08-28 19:35:56 -07001378 fetcher.context().size));
1379 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1380 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001381 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -07001382 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001383
1384 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1385 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001386 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001387 << " expected " << loop1->realtime_now().time_since_epoch().count();
1388 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1389 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001390 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001391 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -07001392}
1393
Austin Schuh52d325c2019-06-23 18:59:06 -07001394// Tests that a couple phased loops run in a row result in the correct offset
1395// and period.
1396TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -08001397 // Force a slower rate so we are guarenteed to have reports for our phased
1398 // loop.
1399 FLAGS_timing_report_ms = 2000;
1400
Austin Schuh52d325c2019-06-23 18:59:06 -07001401 const chrono::milliseconds kOffset = chrono::milliseconds(400);
1402 const int kCount = 5;
1403
1404 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -08001405 auto loop2 = Make();
1406
1407 Fetcher<timing::Report> report_fetcher =
1408 loop2->MakeFetcher<timing::Report>("/aos");
1409 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001410
1411 // Collect up a couple of samples.
1412 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001413 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -07001414
1415 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -08001416 loop1
1417 ->AddPhasedLoop(
1418 [&times, &expected_times, &loop1, this](int count) {
1419 EXPECT_EQ(count, 1);
1420 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -08001421 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -08001422
Austin Schuhad154822019-12-27 15:45:13 -08001423 EXPECT_EQ(loop1->context().monotonic_remote_time,
1424 monotonic_clock::min_time);
1425 EXPECT_EQ(loop1->context().realtime_event_time,
1426 realtime_clock::min_time);
1427 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -08001428 realtime_clock::min_time);
1429 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
1430 EXPECT_EQ(loop1->context().size, 0u);
1431 EXPECT_EQ(loop1->context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -07001432 EXPECT_EQ(loop1->context().buffer_index, -1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001433
1434 if (times.size() == kCount) {
1435 LOG(INFO) << "Exiting";
1436 this->Exit();
1437 }
1438 },
1439 chrono::seconds(1), kOffset)
1440 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -07001441
1442 // Add a delay to make sure that delay during startup doesn't result in a
1443 // "missed cycle".
1444 SleepFor(chrono::seconds(2));
1445
1446 Run();
1447
1448 // Confirm that we got both the right number of samples, and it's odd.
1449 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001450 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -07001451 EXPECT_EQ((times.size() % 2), 1);
1452
1453 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001454 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -07001455
1456 // Add up all the delays of all the times.
1457 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1458 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001459 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -07001460 }
1461
1462 // Average and add to the middle to find the average time.
1463 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001464 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -07001465
1466 // Compute the offset from the start of the second of the average time. This
1467 // should be pretty close to the offset.
1468 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001469 average_time.time_since_epoch() -
1470 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001471
1472 const chrono::milliseconds kEpsilon(100);
1473 EXPECT_LT(remainder, kOffset + kEpsilon);
1474 EXPECT_GT(remainder, kOffset - kEpsilon);
1475
1476 // Make sure that the average duration is close to 1 second.
1477 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1478 times.front())
1479 .count() /
1480 static_cast<double>(times.size() - 1),
1481 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001482
1483 // Confirm that the ideal wakeup times increment correctly.
1484 for (size_t i = 1; i < expected_times.size(); ++i) {
1485 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1486 }
1487
1488 for (size_t i = 0; i < expected_times.size(); ++i) {
1489 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1490 kOffset);
1491 }
1492
1493 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1494 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001495
1496 // And, since we are here, check that the timing report makes sense.
1497 // Start by looking for our event loop's timing.
1498 FlatbufferDetachedBuffer<timing::Report> report =
1499 FlatbufferDetachedBuffer<timing::Report>::Empty();
1500 while (report_fetcher.FetchNext()) {
1501 if (report_fetcher->name()->string_view() == "primary") {
1502 report = CopyFlatBuffer(report_fetcher.get());
1503 }
1504 }
1505
Ravago Jonescf453ab2020-05-06 21:14:53 -07001506 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001507
1508 EXPECT_EQ(report.message().name()->string_view(), "primary");
1509
1510 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001511 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001512
1513 ASSERT_NE(report.message().timers(), nullptr);
1514 EXPECT_EQ(report.message().timers()->size(), 1);
1515
1516 // Make sure there is a single phased loop report with our report in it.
1517 ASSERT_NE(report.message().phased_loops(), nullptr);
1518 ASSERT_EQ(report.message().phased_loops()->size(), 1);
1519 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
1520 "Test loop");
1521 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
1522}
1523
1524// Tests that senders count correctly in the timing report.
1525TEST_P(AbstractEventLoopTest, SenderTimingReport) {
1526 FLAGS_timing_report_ms = 1000;
1527 auto loop1 = MakePrimary();
1528
1529 auto loop2 = Make("watcher_loop");
1530 loop2->MakeWatcher("/test", [](const TestMessage &) {});
1531
1532 auto loop3 = Make();
1533
1534 Fetcher<timing::Report> report_fetcher =
1535 loop3->MakeFetcher<timing::Report>("/aos");
1536 EXPECT_FALSE(report_fetcher.Fetch());
1537
1538 auto sender = loop1->MakeSender<TestMessage>("/test");
1539
1540 // Add a timer to actually quit.
1541 auto test_timer = loop1->AddTimer([&sender]() {
1542 for (int i = 0; i < 10; ++i) {
1543 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1544 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1545 builder.add_value(200 + i);
1546 ASSERT_TRUE(msg.Send(builder.Finish()));
1547 }
1548 });
1549
1550 // Quit after 1 timing report, mid way through the next cycle.
1551 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1552
1553 loop1->OnRun([&test_timer, &loop1]() {
1554 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1555 });
1556
1557 Run();
1558
1559 // And, since we are here, check that the timing report makes sense.
1560 // Start by looking for our event loop's timing.
1561 FlatbufferDetachedBuffer<timing::Report> primary_report =
1562 FlatbufferDetachedBuffer<timing::Report>::Empty();
1563 while (report_fetcher.FetchNext()) {
1564 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1565 if (report_fetcher->name()->string_view() == "primary") {
1566 primary_report = CopyFlatBuffer(report_fetcher.get());
1567 }
1568 }
1569
Ravago Jonescf453ab2020-05-06 21:14:53 -07001570 LOG(INFO) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001571
1572 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1573
1574 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001575 EXPECT_EQ(primary_report.message().senders()->size(), 3);
Austin Schuh39788ff2019-12-01 18:22:57 -08001576
1577 // Confirm that the sender looks sane.
1578 EXPECT_EQ(
1579 loop1->configuration()
1580 ->channels()
1581 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1582 ->name()
1583 ->string_view(),
1584 "/test");
1585 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1586
1587 // Confirm that the timing primary_report sender looks sane.
1588 EXPECT_EQ(
1589 loop1->configuration()
1590 ->channels()
1591 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1592 ->name()
1593 ->string_view(),
1594 "/aos");
1595 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1596
1597 ASSERT_NE(primary_report.message().timers(), nullptr);
1598 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1599
1600 // Make sure there are no phased loops or watchers.
1601 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1602 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1603}
1604
1605// Tests that senders count correctly in the timing report.
1606TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1607 FLAGS_timing_report_ms = 1000;
1608 auto loop1 = MakePrimary();
1609 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1610
1611 auto loop2 = Make("sender_loop");
1612
1613 auto loop3 = Make();
1614
1615 Fetcher<timing::Report> report_fetcher =
1616 loop3->MakeFetcher<timing::Report>("/aos");
1617 EXPECT_FALSE(report_fetcher.Fetch());
1618
1619 auto sender = loop2->MakeSender<TestMessage>("/test");
1620
1621 // Add a timer to actually quit.
1622 auto test_timer = loop1->AddTimer([&sender]() {
1623 for (int i = 0; i < 10; ++i) {
1624 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1625 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1626 builder.add_value(200 + i);
1627 ASSERT_TRUE(msg.Send(builder.Finish()));
1628 }
1629 });
1630
1631 // Quit after 1 timing report, mid way through the next cycle.
1632 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1633
1634 loop1->OnRun([&test_timer, &loop1]() {
1635 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1636 });
1637
1638 Run();
1639
1640 // And, since we are here, check that the timing report makes sense.
1641 // Start by looking for our event loop's timing.
1642 FlatbufferDetachedBuffer<timing::Report> primary_report =
1643 FlatbufferDetachedBuffer<timing::Report>::Empty();
1644 while (report_fetcher.FetchNext()) {
1645 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1646 if (report_fetcher->name()->string_view() == "primary") {
1647 primary_report = CopyFlatBuffer(report_fetcher.get());
1648 }
1649 }
1650
1651 // Check the watcher report.
Ravago Jonescf453ab2020-05-06 21:14:53 -07001652 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001653
1654 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1655
1656 // Just the timing report timer.
1657 ASSERT_NE(primary_report.message().timers(), nullptr);
1658 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1659
1660 // No phased loops
1661 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1662
1663 ASSERT_NE(primary_report.message().watchers(), nullptr);
1664 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1665 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1666}
1667
1668// Tests that fetchers count correctly in the timing report.
1669TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1670 FLAGS_timing_report_ms = 1000;
1671 auto loop1 = MakePrimary();
1672 auto loop2 = Make("sender_loop");
1673
1674 auto loop3 = Make();
1675
1676 Fetcher<timing::Report> report_fetcher =
1677 loop3->MakeFetcher<timing::Report>("/aos");
1678 EXPECT_FALSE(report_fetcher.Fetch());
1679
1680 auto sender = loop2->MakeSender<TestMessage>("/test");
1681 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1682 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1683 fetcher1.Fetch();
1684 fetcher2.Fetch();
1685
1686 // Add a timer to actually quit.
1687 auto test_timer = loop1->AddTimer([&sender]() {
1688 for (int i = 0; i < 10; ++i) {
1689 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1690 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1691 builder.add_value(200 + i);
1692 ASSERT_TRUE(msg.Send(builder.Finish()));
1693 }
1694 });
1695
1696 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1697 fetcher1.Fetch();
1698 while (fetcher2.FetchNext()) {
1699 }
1700 });
1701
1702 // Quit after 1 timing report, mid way through the next cycle.
1703 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1704
1705 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1706 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1707 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1708 });
1709
1710 Run();
1711
1712 // And, since we are here, check that the timing report makes sense.
1713 // Start by looking for our event loop's timing.
1714 FlatbufferDetachedBuffer<timing::Report> primary_report =
1715 FlatbufferDetachedBuffer<timing::Report>::Empty();
1716 while (report_fetcher.FetchNext()) {
1717 if (report_fetcher->name()->string_view() == "primary") {
1718 primary_report = CopyFlatBuffer(report_fetcher.get());
1719 }
1720 }
1721
Ravago Jonescf453ab2020-05-06 21:14:53 -07001722 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001723
1724 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1725
1726 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001727 EXPECT_EQ(primary_report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001728
1729 ASSERT_NE(primary_report.message().timers(), nullptr);
1730 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1731
1732 // Make sure there are no phased loops or watchers.
1733 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1734 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1735
1736 // Now look at the fetchrs.
1737 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1738 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1739
1740 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1741 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1742 0.1);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001743 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(), 0.1);
1744 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(), 0.1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001745 EXPECT_EQ(primary_report.message()
1746 .fetchers()
1747 ->Get(0)
1748 ->latency()
1749 ->standard_deviation(),
1750 0.0);
1751
1752 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001753}
1754
Austin Schuh67420a42019-12-21 21:55:04 -08001755// Tests that a raw watcher and raw fetcher can receive messages from a raw
1756// sender without messing up offsets.
1757TEST_P(AbstractEventLoopTest, RawBasic) {
1758 auto loop1 = Make();
1759 auto loop2 = MakePrimary();
1760 auto loop3 = Make();
1761
1762 const std::string kData("971 is the best");
1763
1764 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001765 loop1->MakeRawSender(configuration::GetChannel(
1766 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001767
1768 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001769 loop3->MakeRawFetcher(configuration::GetChannel(
1770 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001771
1772 loop2->OnRun(
1773 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1774
1775 bool happened = false;
1776 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001777 configuration::GetChannel(loop2->configuration(), "/test",
1778 "aos.TestMessage", "", nullptr),
Austin Schuh67420a42019-12-21 21:55:04 -08001779 [this, &kData, &fetcher, &happened](const Context &context,
1780 const void *message) {
1781 happened = true;
1782 EXPECT_EQ(std::string_view(kData),
1783 std::string_view(reinterpret_cast<const char *>(message),
1784 context.size));
1785 EXPECT_EQ(std::string_view(kData),
1786 std::string_view(reinterpret_cast<const char *>(context.data),
1787 context.size));
1788
1789 ASSERT_TRUE(fetcher->Fetch());
1790
1791 EXPECT_EQ(std::string_view(kData),
1792 std::string_view(
1793 reinterpret_cast<const char *>(fetcher->context().data),
1794 fetcher->context().size));
1795
1796 this->Exit();
1797 });
1798
1799 EXPECT_FALSE(happened);
1800 Run();
1801 EXPECT_TRUE(happened);
1802}
1803
Austin Schuhad154822019-12-27 15:45:13 -08001804// Tests that a raw watcher and raw fetcher can receive messages from a raw
1805// sender with remote times filled out.
1806TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1807 auto loop1 = Make();
1808 auto loop2 = MakePrimary();
1809 auto loop3 = Make();
1810
1811 const std::string kData("971 is the best");
1812
1813 const aos::monotonic_clock::time_point monotonic_remote_time =
1814 aos::monotonic_clock::time_point(chrono::seconds(1501));
1815 const aos::realtime_clock::time_point realtime_remote_time =
1816 aos::realtime_clock::time_point(chrono::seconds(3132));
1817
1818 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001819 loop1->MakeRawSender(configuration::GetChannel(
1820 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001821
1822 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001823 loop3->MakeRawFetcher(configuration::GetChannel(
1824 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001825
1826 loop2->OnRun([&]() {
1827 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1828 realtime_remote_time));
1829 });
1830
1831 bool happened = false;
1832 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001833 configuration::GetChannel(loop2->configuration(), "/test",
1834 "aos.TestMessage", "", nullptr),
Austin Schuhad154822019-12-27 15:45:13 -08001835 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1836 const Context &context, const void * /*message*/) {
1837 happened = true;
1838 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1839 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1840
1841 ASSERT_TRUE(fetcher->Fetch());
1842 EXPECT_EQ(monotonic_remote_time,
1843 fetcher->context().monotonic_remote_time);
1844 EXPECT_EQ(realtime_remote_time,
1845 fetcher->context().realtime_remote_time);
1846
1847 this->Exit();
1848 });
1849
1850 EXPECT_FALSE(happened);
1851 Run();
1852 EXPECT_TRUE(happened);
1853}
1854
1855// Tests that a raw sender fills out sent data.
1856TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1857 auto loop1 = MakePrimary();
1858
1859 const std::string kData("971 is the best");
1860
1861 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001862 loop1->MakeRawSender(configuration::GetChannel(
1863 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001864
Tyler Chatow67ddb032020-01-12 14:30:04 -08001865 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
1866 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001867
1868 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1869
1870 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1871 EXPECT_LE(sender->monotonic_sent_time(),
1872 monotonic_now + chrono::milliseconds(100));
1873 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1874 EXPECT_LE(sender->realtime_sent_time(),
1875 realtime_now + chrono::milliseconds(100));
1876 EXPECT_EQ(sender->sent_queue_index(), 0u);
1877
1878 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1879
1880 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1881 EXPECT_LE(sender->monotonic_sent_time(),
1882 monotonic_now + chrono::milliseconds(100));
1883 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1884 EXPECT_LE(sender->realtime_sent_time(),
1885 realtime_now + chrono::milliseconds(100));
1886 EXPECT_EQ(sender->sent_queue_index(), 1u);
1887}
1888
Austin Schuh217a9782019-12-21 23:02:50 -08001889// Tests that not setting up nodes results in no node.
1890TEST_P(AbstractEventLoopTest, NoNode) {
1891 auto loop1 = Make();
1892 auto loop2 = MakePrimary();
1893
1894 EXPECT_EQ(loop1->node(), nullptr);
1895 EXPECT_EQ(loop2->node(), nullptr);
1896}
1897
1898// Tests that setting up nodes results in node being set.
1899TEST_P(AbstractEventLoopTest, Node) {
1900 EnableNodes("me");
1901
1902 auto loop1 = Make();
1903 auto loop2 = MakePrimary();
1904
1905 EXPECT_NE(loop1->node(), nullptr);
1906 EXPECT_NE(loop2->node(), nullptr);
1907}
1908
1909// Tests that watchers work with a node setup.
1910TEST_P(AbstractEventLoopTest, NodeWatcher) {
1911 EnableNodes("me");
1912
1913 auto loop1 = Make();
1914 auto loop2 = Make();
1915 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08001916 loop2->MakeRawWatcher(
1917 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1918 nullptr),
1919 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001920}
1921
Brian Silverman454bc112020-03-05 14:21:25 -08001922// Tests that no-arg watchers work with a node setup.
1923TEST_P(AbstractEventLoopTest, NodeNoArgWatcher) {
1924 EnableNodes("me");
1925
1926 auto loop1 = Make();
1927 auto loop2 = Make();
1928 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1929 loop2->MakeRawNoArgWatcher(
1930 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1931 nullptr),
1932 [](const Context &) {});
1933}
1934
Austin Schuh217a9782019-12-21 23:02:50 -08001935// Tests that fetcher work with a node setup.
1936TEST_P(AbstractEventLoopTest, NodeFetcher) {
1937 EnableNodes("me");
1938 auto loop1 = Make();
1939
1940 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08001941 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1942 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001943}
1944
1945// Tests that sender work with a node setup.
1946TEST_P(AbstractEventLoopTest, NodeSender) {
1947 EnableNodes("me");
1948 auto loop1 = Make();
1949
1950 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1951}
1952
Austin Schuhcc6070c2020-10-10 20:25:56 -07001953// Tests that a non-realtime event loop timer is marked non-realtime.
1954TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopTimer) {
1955 auto loop1 = MakePrimary();
1956
1957 // Add a timer to actually quit.
1958 auto test_timer = loop1->AddTimer([this]() {
1959 CheckNotRealtime();
1960 this->Exit();
1961 });
1962
1963 loop1->OnRun([&test_timer, &loop1]() {
1964 CheckNotRealtime();
1965 test_timer->Setup(loop1->monotonic_now(), ::std::chrono::milliseconds(100));
1966 });
1967
1968 Run();
1969}
1970
1971// Tests that a realtime event loop timer is marked realtime.
1972TEST_P(AbstractEventLoopTest, RealtimeEventLoopTimer) {
1973 auto loop1 = MakePrimary();
1974
1975 loop1->SetRuntimeRealtimePriority(1);
1976
1977 // Add a timer to actually quit.
1978 auto test_timer = loop1->AddTimer([this]() {
1979 CheckRealtime();
1980 this->Exit();
1981 });
1982
1983 loop1->OnRun([&test_timer, &loop1]() {
1984 CheckRealtime();
1985 test_timer->Setup(loop1->monotonic_now(), ::std::chrono::milliseconds(100));
1986 });
1987
1988 Run();
1989}
1990
1991// Tests that a non-realtime event loop phased loop is marked non-realtime.
1992TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopPhasedLoop) {
1993 auto loop1 = MakePrimary();
1994
1995 // Add a timer to actually quit.
1996 loop1->AddPhasedLoop(
1997 [this](int) {
1998 CheckNotRealtime();
1999 this->Exit();
2000 },
2001 chrono::seconds(1), chrono::seconds(0));
2002
2003 Run();
2004}
2005
2006// Tests that a realtime event loop phased loop is marked realtime.
2007TEST_P(AbstractEventLoopTest, RealtimeEventLoopPhasedLoop) {
2008 auto loop1 = MakePrimary();
2009
2010 loop1->SetRuntimeRealtimePriority(1);
2011
2012 // Add a timer to actually quit.
2013 loop1->AddPhasedLoop(
2014 [this](int) {
2015 CheckRealtime();
2016 this->Exit();
2017 },
2018 chrono::seconds(1), chrono::seconds(0));
2019
2020 Run();
2021}
2022
2023// Tests that a non-realtime event loop watcher is marked non-realtime.
2024TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopWatcher) {
2025 auto loop1 = MakePrimary();
2026 auto loop2 = Make();
2027
2028 aos::Sender<TestMessage> sender = loop2->MakeSender<TestMessage>("/test");
2029
2030 loop1->OnRun([&]() {
2031 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
2032 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
2033 ASSERT_TRUE(msg.Send(builder.Finish()));
2034 });
2035
2036 loop1->MakeWatcher("/test", [&](const TestMessage &) {
2037 CheckNotRealtime();
2038 this->Exit();
2039 });
2040
2041 Run();
2042}
2043
2044// Tests that a realtime event loop watcher is marked realtime.
2045TEST_P(AbstractEventLoopTest, RealtimeEventLoopWatcher) {
2046 auto loop1 = MakePrimary();
2047 auto loop2 = Make();
2048
2049 loop1->SetRuntimeRealtimePriority(1);
2050
2051 aos::Sender<TestMessage> sender = loop2->MakeSender<TestMessage>("/test");
2052
2053 loop1->OnRun([&]() {
2054 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
2055 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
2056 ASSERT_TRUE(msg.Send(builder.Finish()));
2057 });
2058
2059 loop1->MakeWatcher("/test", [&](const TestMessage &) {
2060 CheckRealtime();
2061 this->Exit();
2062 });
2063
2064 Run();
2065}
2066
Austin Schuh217a9782019-12-21 23:02:50 -08002067// Tests that watchers fail when created on the wrong node.
2068TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
2069 EnableNodes("them");
2070
2071 auto loop1 = Make();
2072 auto loop2 = Make();
2073 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
2074 "node");
2075 EXPECT_DEATH(
2076 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08002077 loop2->MakeRawWatcher(
2078 configuration::GetChannel(configuration(), "/test",
2079 "aos.TestMessage", "", nullptr),
2080 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08002081 },
2082 "node");
Brian Silverman454bc112020-03-05 14:21:25 -08002083 EXPECT_DEATH({ loop1->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
2084 "node");
2085 EXPECT_DEATH(
2086 {
2087 loop2->MakeRawNoArgWatcher(
2088 configuration::GetChannel(configuration(), "/test",
2089 "aos.TestMessage", "", nullptr),
2090 [](const Context &) {});
2091 },
2092 "node");
Austin Schuh217a9782019-12-21 23:02:50 -08002093}
2094
2095// Tests that fetchers fail when created on the wrong node.
2096TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
2097 EnableNodes("them");
2098 auto loop1 = Make();
2099
2100 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
2101 "node");
2102 EXPECT_DEATH(
2103 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08002104 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
2105 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08002106 },
2107 "node");
2108}
2109
2110// Tests that senders fail when created on the wrong node.
2111TEST_P(AbstractEventLoopDeathTest, NodeSender) {
2112 EnableNodes("them");
2113 auto loop1 = Make();
2114
2115 EXPECT_DEATH(
2116 {
2117 aos::Sender<TestMessage> sender =
2118 loop1->MakeSender<TestMessage>("/test");
2119 },
2120 "node");
2121
2122 // Note: Creating raw senders is always supported. Right now, this lets us
2123 // use them to create message_gateway.
2124}
2125
Brian Silverman341b57e2020-06-23 16:23:18 -07002126// Tests creating multiple Builders from a single Sender at the same time.
2127TEST_P(AbstractEventLoopDeathTest, MultipleBuilders) {
2128 auto loop1 = Make();
2129 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
2130
2131 { auto builder = sender.MakeBuilder(); }
2132 {
2133 auto builder = sender.MakeBuilder();
2134 builder.MakeBuilder<TestMessage>().Finish();
2135 }
2136 {
2137 // Creating this after the first one was destroyed should be fine.
2138 auto builder = sender.MakeBuilder();
2139 builder.MakeBuilder<TestMessage>().Finish();
2140 // But not a second one.
2141 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2142 "May not overwrite in-use allocator");
2143 }
2144
2145 FlatbufferDetachedBuffer<TestMessage> detached =
2146 flatbuffers::DetachedBuffer();
2147 {
2148 auto builder = sender.MakeBuilder();
2149 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2150 }
2151 {
2152 // This is the second one, after the detached one, so it should fail.
2153 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2154 "May not overwrite in-use allocator");
2155 }
2156
2157 // Clear the detached one, and then we should be able to create another.
2158 detached = flatbuffers::DetachedBuffer();
2159 {
2160 auto builder = sender.MakeBuilder();
2161 builder.MakeBuilder<TestMessage>().Finish();
2162 }
2163
2164 // And then detach another one.
2165 {
2166 auto builder = sender.MakeBuilder();
2167 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2168 }
2169}
2170
2171// Tests sending a buffer detached from a different builder.
2172TEST_P(AbstractEventLoopDeathTest, WrongDetachedBuffer) {
2173 auto loop1 = Make();
2174 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
2175 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
2176
2177 auto builder = sender1.MakeBuilder();
2178 FlatbufferDetachedBuffer<TestMessage> detached =
2179 builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2180 EXPECT_DEATH(sender2.SendDetached(std::move(detached)),
2181 "May only send the buffer detached from this Sender");
2182}
2183
Parker Schuhe4a70d62017-12-27 20:10:20 -08002184} // namespace testing
2185} // namespace aos