blob: a5b6b19c88cc339ad5a43ac2b55ff9a170955544 [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();
Austin Schuh7f20f512021-01-31 17:56:16 -08001056 std::vector<monotonic_clock::time_point> iteration_list;
Neil Balch229001a2018-01-07 18:22:52 -08001057
1058 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
Austin Schuh7f20f512021-01-31 17:56:16 -08001059 iteration_list.push_back(loop->context().monotonic_event_time);
Neil Balch229001a2018-01-07 18:22:52 -08001060 });
1061
Austin Schuh7f20f512021-01-31 17:56:16 -08001062 monotonic_clock::time_point s;
1063 auto modifier_timer = loop->AddTimer([&test_timer, &s]() {
1064 test_timer->Setup(s + chrono::milliseconds(45), chrono::milliseconds(30));
Neil Balch229001a2018-01-07 18:22:52 -08001065 });
1066
Austin Schuh7f20f512021-01-31 17:56:16 -08001067 s = loop->monotonic_now();
1068 test_timer->Setup(s, chrono::milliseconds(20));
1069 modifier_timer->Setup(s + chrono::milliseconds(45));
1070 EndEventLoop(loop.get(), chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -07001071 Run();
Neil Balch229001a2018-01-07 18:22:52 -08001072
1073 EXPECT_EQ(iteration_list.size(), 7);
Austin Schuh7f20f512021-01-31 17:56:16 -08001074 EXPECT_EQ(iteration_list[0], s);
1075 EXPECT_EQ(iteration_list[1], s + chrono::milliseconds(20));
1076 EXPECT_EQ(iteration_list[2], s + chrono::milliseconds(40));
1077 EXPECT_EQ(iteration_list[3], s + chrono::milliseconds(45));
1078 EXPECT_EQ(iteration_list[4], s + chrono::milliseconds(75));
1079 EXPECT_EQ(iteration_list[5], s + chrono::milliseconds(105));
1080 EXPECT_EQ(iteration_list[6], s + chrono::milliseconds(135));
Neil Balch229001a2018-01-07 18:22:52 -08001081}
1082
1083// Verify that we can disable a timer during execution.
1084TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -07001085 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -08001086 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
1087
1088 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
1089 iteration_list.push_back(loop->monotonic_now());
1090 });
1091
Tyler Chatow67ddb032020-01-12 14:30:04 -08001092 auto ender_timer = loop->AddTimer([&test_timer]() { test_timer->Disable(); });
Neil Balch229001a2018-01-07 18:22:52 -08001093
1094 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
Tyler Chatow67ddb032020-01-12 14:30:04 -08001095 ender_timer->Setup(loop->monotonic_now() + ::std::chrono::milliseconds(45));
Neil Balch229001a2018-01-07 18:22:52 -08001096 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -07001097 Run();
Neil Balch229001a2018-01-07 18:22:52 -08001098
1099 EXPECT_EQ(iteration_list.size(), 3);
1100}
Austin Schuh7267c532019-05-19 19:55:53 -07001101
Brian Silvermanaf9a4d82020-10-06 15:10:58 -07001102// Verify that a timer can disable itself.
1103//
1104// TODO(Brian): Do something similar with phased loops, both with a quick
1105// handler and a handler that would miss a cycle except it got deferred. Current
1106// behavior doing that is a mess.
1107TEST_P(AbstractEventLoopTest, TimerDisableSelf) {
1108 auto loop = MakePrimary();
1109
1110 int count = 0;
1111 aos::TimerHandler *test_timer;
1112 test_timer = loop->AddTimer([&count, &test_timer]() {
1113 ++count;
1114 test_timer->Disable();
1115 });
1116
1117 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
1118 EndEventLoop(loop.get(), ::std::chrono::milliseconds(80));
1119 Run();
1120
1121 EXPECT_EQ(count, 1);
1122}
1123
Brian Silvermanbd405c02020-06-23 16:25:23 -07001124// Verify that we can disable a timer during execution of another timer
1125// scheduled for the same time, with one ordering of creation for the timers.
1126//
1127// Also schedule some more events to reshuffle the heap in EventLoop used for
1128// tracking events to change up the order. This used to segfault
1129// SimulatedEventLoop.
1130TEST_P(AbstractEventLoopTest, TimerDisableOther) {
1131 for (bool creation_order : {true, false}) {
1132 for (bool setup_order : {true, false}) {
1133 for (int shuffle_events = 0; shuffle_events < 5; ++shuffle_events) {
1134 auto loop = MakePrimary();
1135 aos::TimerHandler *test_timer, *ender_timer;
1136 if (creation_order) {
1137 test_timer = loop->AddTimer([]() {});
1138 ender_timer =
1139 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1140 } else {
1141 ender_timer =
1142 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1143 test_timer = loop->AddTimer([]() {});
1144 }
1145
1146 const auto start = loop->monotonic_now();
1147
1148 for (int i = 0; i < shuffle_events; ++i) {
1149 loop->AddTimer([]() {})->Setup(start + std::chrono::milliseconds(10));
1150 }
1151
1152 if (setup_order) {
1153 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1154 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1155 } else {
1156 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1157 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1158 }
1159 EndEventLoop(loop.get(), ::std::chrono::milliseconds(40));
1160 Run();
1161 }
1162 }
1163 }
1164}
1165
Austin Schuh54cf95f2019-11-29 13:14:18 -08001166// Verifies that the event loop implementations detect when Channel is not a
1167// pointer into confguration()
1168TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
1169 auto loop = MakePrimary();
1170
Tyler Chatow67ddb032020-01-12 14:30:04 -08001171 const Channel *channel = configuration::GetChannel(
1172 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
Austin Schuh54cf95f2019-11-29 13:14:18 -08001173
1174 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
1175
1176 EXPECT_DEATH(
1177 { loop->MakeRawSender(&channel_copy.message()); },
1178 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1179
1180 EXPECT_DEATH(
1181 { loop->MakeRawFetcher(&channel_copy.message()); },
1182 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1183
1184 EXPECT_DEATH(
1185 {
1186 loop->MakeRawWatcher(&channel_copy.message(),
1187 [](const Context, const void *) {});
1188 },
1189 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1190}
1191
Austin Schuhd54780b2020-10-03 16:26:02 -07001192// Verifies that the event loop implementations detect when Channel has an
1193// invalid alignment.
1194TEST_P(AbstractEventLoopDeathTest, InvalidChannelAlignment) {
1195 const char *const kError = "multiple of alignment";
1196 InvalidChannelAlignment();
1197
1198 auto loop = MakePrimary();
1199
1200 const Channel *channel = configuration::GetChannel(
1201 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
1202
1203 EXPECT_DEATH({ loop->MakeRawSender(channel); }, kError);
1204 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); }, kError);
1205
1206 EXPECT_DEATH({ loop->MakeRawFetcher(channel); }, kError);
1207 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); }, kError);
1208
1209 EXPECT_DEATH(
1210 { loop->MakeRawWatcher(channel, [](const Context &, const void *) {}); },
1211 kError);
1212 EXPECT_DEATH({ loop->MakeRawNoArgWatcher(channel, [](const Context &) {}); },
1213 kError);
1214
1215 EXPECT_DEATH({ loop->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1216 kError);
1217 EXPECT_DEATH({ loop->MakeWatcher("/test", [](const TestMessage &) {}); },
1218 kError);
1219}
1220
Brian Silverman454bc112020-03-05 14:21:25 -08001221// Verify that the send time on a message is roughly right when using a watcher.
Austin Schuh7267c532019-05-19 19:55:53 -07001222TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -07001223 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -07001224 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -08001225 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -07001226 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
1227
1228 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -07001229 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1230 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1231 builder.add_value(200);
1232 ASSERT_TRUE(msg.Send(builder.Finish()));
1233 });
1234
Austin Schuhad154822019-12-27 15:45:13 -08001235 bool triggered = false;
Brian Silverman454bc112020-03-05 14:21:25 -08001236 loop1->MakeWatcher("/test", [&](const TestMessage &msg) {
Austin Schuhad154822019-12-27 15:45:13 -08001237 // Confirm that the data pointer makes sense from a watcher, and all the
1238 // timestamps look right.
1239 EXPECT_GT(&msg, loop1->context().data);
1240 EXPECT_EQ(loop1->context().monotonic_remote_time,
1241 loop1->context().monotonic_event_time);
1242 EXPECT_EQ(loop1->context().realtime_remote_time,
1243 loop1->context().realtime_event_time);
1244
1245 const aos::monotonic_clock::time_point monotonic_now =
1246 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -08001247 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001248
1249 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1250 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1251 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1252 monotonic_now);
1253 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1254 realtime_now);
1255
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001256 EXPECT_LT(&msg, reinterpret_cast<const void *>(
1257 reinterpret_cast<const char *>(loop1->context().data) +
Austin Schuhad154822019-12-27 15:45:13 -08001258 loop1->context().size));
Brian Silverman4f4e0612020-08-12 19:54:41 -07001259 if (read_method() == ReadMethod::PIN) {
1260 EXPECT_GE(loop1->context().buffer_index, 0);
1261 EXPECT_LT(loop1->context().buffer_index,
1262 loop1->NumberBuffers(
1263 configuration::GetChannel(loop1->configuration(), "/test",
1264 "aos.TestMessage", "", nullptr)));
1265 } else {
1266 EXPECT_EQ(-1, loop1->context().buffer_index);
1267 }
Austin Schuhad154822019-12-27 15:45:13 -08001268 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -07001269 });
1270
1271 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1272
1273 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -07001274 Run();
Austin Schuh7267c532019-05-19 19:55:53 -07001275
Austin Schuhad154822019-12-27 15:45:13 -08001276 EXPECT_TRUE(triggered);
1277
Brian Silverman454bc112020-03-05 14:21:25 -08001278 ASSERT_TRUE(fetcher.Fetch());
1279
1280 monotonic_clock::duration monotonic_time_offset =
1281 fetcher.context().monotonic_event_time -
1282 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1283 realtime_clock::duration realtime_time_offset =
1284 fetcher.context().realtime_event_time -
1285 (loop1->realtime_now() - ::std::chrono::seconds(1));
1286
1287 EXPECT_EQ(fetcher.context().realtime_event_time,
1288 fetcher.context().realtime_remote_time);
1289 EXPECT_EQ(fetcher.context().monotonic_event_time,
1290 fetcher.context().monotonic_remote_time);
1291
1292 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1293 << ": Got "
1294 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1295 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1296 // Confirm that the data pointer makes sense.
1297 EXPECT_GT(fetcher.get(), fetcher.context().data);
1298 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001299 reinterpret_cast<const void *>(
1300 reinterpret_cast<const char *>(fetcher.context().data) +
Brian Silverman454bc112020-03-05 14:21:25 -08001301 fetcher.context().size));
1302 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1303 << ": Got "
1304 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1305 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1306
1307 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1308 << ": Got "
1309 << fetcher.context().realtime_event_time.time_since_epoch().count()
1310 << " expected " << loop1->realtime_now().time_since_epoch().count();
1311 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1312 << ": Got "
1313 << fetcher.context().realtime_event_time.time_since_epoch().count()
1314 << " expected " << loop1->realtime_now().time_since_epoch().count();
1315}
1316
1317// Verify that the send time on a message is roughly right when using a no-arg
1318// watcher. To get a message, we need to use a fetcher to actually access the
1319// message. This is also the main use case for no-arg fetchers.
1320TEST_P(AbstractEventLoopTest, MessageSendTimeNoArg) {
1321 auto loop1 = MakePrimary();
1322 auto loop2 = Make();
1323 auto sender = loop2->MakeSender<TestMessage>("/test");
1324 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1325
1326 auto test_timer = loop1->AddTimer([&sender]() {
1327 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1328 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1329 builder.add_value(200);
1330 ASSERT_TRUE(msg.Send(builder.Finish()));
1331 });
1332
1333 bool triggered = false;
1334 loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {
1335 // Confirm that we can indeed use a fetcher on this channel from this
1336 // context, and it results in a sane data pointer and timestamps.
1337 ASSERT_TRUE(fetcher.Fetch());
1338
1339 EXPECT_EQ(loop1->context().monotonic_remote_time,
1340 loop1->context().monotonic_event_time);
1341 EXPECT_EQ(loop1->context().realtime_remote_time,
1342 loop1->context().realtime_event_time);
1343
1344 const aos::monotonic_clock::time_point monotonic_now =
1345 loop1->monotonic_now();
1346 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
1347
1348 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1349 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1350 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1351 monotonic_now);
1352 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1353 realtime_now);
1354
1355 triggered = true;
1356 });
1357
1358 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1359
1360 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
1361 Run();
1362
1363 ASSERT_TRUE(triggered);
Austin Schuh7267c532019-05-19 19:55:53 -07001364
Alex Perrycb7da4b2019-08-28 19:35:56 -07001365 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001366 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001367 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1368 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001369 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001370 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -07001371
Austin Schuhad154822019-12-27 15:45:13 -08001372 EXPECT_EQ(fetcher.context().realtime_event_time,
1373 fetcher.context().realtime_remote_time);
1374 EXPECT_EQ(fetcher.context().monotonic_event_time,
1375 fetcher.context().monotonic_remote_time);
1376
Alex Perrycb7da4b2019-08-28 19:35:56 -07001377 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1378 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001379 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -07001380 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001381 // Confirm that the data pointer makes sense.
1382 EXPECT_GT(fetcher.get(), fetcher.context().data);
1383 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001384 reinterpret_cast<const void *>(
1385 reinterpret_cast<const char *>(fetcher.context().data) +
Alex Perrycb7da4b2019-08-28 19:35:56 -07001386 fetcher.context().size));
1387 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1388 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001389 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -07001390 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001391
1392 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1393 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001394 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001395 << " expected " << loop1->realtime_now().time_since_epoch().count();
1396 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1397 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001398 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001399 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -07001400}
1401
Austin Schuh52d325c2019-06-23 18:59:06 -07001402// Tests that a couple phased loops run in a row result in the correct offset
1403// and period.
1404TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -08001405 // Force a slower rate so we are guarenteed to have reports for our phased
1406 // loop.
1407 FLAGS_timing_report_ms = 2000;
1408
Austin Schuh52d325c2019-06-23 18:59:06 -07001409 const chrono::milliseconds kOffset = chrono::milliseconds(400);
1410 const int kCount = 5;
1411
1412 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -08001413 auto loop2 = Make();
1414
1415 Fetcher<timing::Report> report_fetcher =
1416 loop2->MakeFetcher<timing::Report>("/aos");
1417 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001418
1419 // Collect up a couple of samples.
1420 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001421 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -07001422
1423 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -08001424 loop1
1425 ->AddPhasedLoop(
1426 [&times, &expected_times, &loop1, this](int count) {
1427 EXPECT_EQ(count, 1);
1428 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -08001429 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -08001430
Austin Schuhad154822019-12-27 15:45:13 -08001431 EXPECT_EQ(loop1->context().monotonic_remote_time,
1432 monotonic_clock::min_time);
1433 EXPECT_EQ(loop1->context().realtime_event_time,
1434 realtime_clock::min_time);
1435 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -08001436 realtime_clock::min_time);
1437 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
1438 EXPECT_EQ(loop1->context().size, 0u);
1439 EXPECT_EQ(loop1->context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -07001440 EXPECT_EQ(loop1->context().buffer_index, -1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001441
1442 if (times.size() == kCount) {
1443 LOG(INFO) << "Exiting";
1444 this->Exit();
1445 }
1446 },
1447 chrono::seconds(1), kOffset)
1448 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -07001449
1450 // Add a delay to make sure that delay during startup doesn't result in a
1451 // "missed cycle".
1452 SleepFor(chrono::seconds(2));
1453
1454 Run();
1455
1456 // Confirm that we got both the right number of samples, and it's odd.
1457 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001458 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -07001459 EXPECT_EQ((times.size() % 2), 1);
1460
1461 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001462 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -07001463
1464 // Add up all the delays of all the times.
1465 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1466 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001467 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -07001468 }
1469
1470 // Average and add to the middle to find the average time.
1471 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001472 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -07001473
1474 // Compute the offset from the start of the second of the average time. This
1475 // should be pretty close to the offset.
1476 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001477 average_time.time_since_epoch() -
1478 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001479
1480 const chrono::milliseconds kEpsilon(100);
1481 EXPECT_LT(remainder, kOffset + kEpsilon);
1482 EXPECT_GT(remainder, kOffset - kEpsilon);
1483
1484 // Make sure that the average duration is close to 1 second.
1485 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1486 times.front())
1487 .count() /
1488 static_cast<double>(times.size() - 1),
1489 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001490
1491 // Confirm that the ideal wakeup times increment correctly.
1492 for (size_t i = 1; i < expected_times.size(); ++i) {
1493 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1494 }
1495
1496 for (size_t i = 0; i < expected_times.size(); ++i) {
1497 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1498 kOffset);
1499 }
1500
1501 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1502 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001503
1504 // And, since we are here, check that the timing report makes sense.
1505 // Start by looking for our event loop's timing.
1506 FlatbufferDetachedBuffer<timing::Report> report =
1507 FlatbufferDetachedBuffer<timing::Report>::Empty();
1508 while (report_fetcher.FetchNext()) {
1509 if (report_fetcher->name()->string_view() == "primary") {
1510 report = CopyFlatBuffer(report_fetcher.get());
1511 }
1512 }
1513
Ravago Jonescf453ab2020-05-06 21:14:53 -07001514 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001515
1516 EXPECT_EQ(report.message().name()->string_view(), "primary");
1517
1518 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001519 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001520
1521 ASSERT_NE(report.message().timers(), nullptr);
1522 EXPECT_EQ(report.message().timers()->size(), 1);
1523
1524 // Make sure there is a single phased loop report with our report in it.
1525 ASSERT_NE(report.message().phased_loops(), nullptr);
1526 ASSERT_EQ(report.message().phased_loops()->size(), 1);
1527 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
1528 "Test loop");
1529 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
1530}
1531
1532// Tests that senders count correctly in the timing report.
1533TEST_P(AbstractEventLoopTest, SenderTimingReport) {
1534 FLAGS_timing_report_ms = 1000;
1535 auto loop1 = MakePrimary();
1536
1537 auto loop2 = Make("watcher_loop");
1538 loop2->MakeWatcher("/test", [](const TestMessage &) {});
1539
1540 auto loop3 = Make();
1541
1542 Fetcher<timing::Report> report_fetcher =
1543 loop3->MakeFetcher<timing::Report>("/aos");
1544 EXPECT_FALSE(report_fetcher.Fetch());
1545
1546 auto sender = loop1->MakeSender<TestMessage>("/test");
1547
1548 // Add a timer to actually quit.
1549 auto test_timer = loop1->AddTimer([&sender]() {
1550 for (int i = 0; i < 10; ++i) {
1551 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1552 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1553 builder.add_value(200 + i);
1554 ASSERT_TRUE(msg.Send(builder.Finish()));
1555 }
1556 });
1557
1558 // Quit after 1 timing report, mid way through the next cycle.
1559 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1560
1561 loop1->OnRun([&test_timer, &loop1]() {
1562 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1563 });
1564
1565 Run();
1566
1567 // And, since we are here, check that the timing report makes sense.
1568 // Start by looking for our event loop's timing.
1569 FlatbufferDetachedBuffer<timing::Report> primary_report =
1570 FlatbufferDetachedBuffer<timing::Report>::Empty();
1571 while (report_fetcher.FetchNext()) {
1572 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1573 if (report_fetcher->name()->string_view() == "primary") {
1574 primary_report = CopyFlatBuffer(report_fetcher.get());
1575 }
1576 }
1577
Ravago Jonescf453ab2020-05-06 21:14:53 -07001578 LOG(INFO) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001579
1580 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1581
1582 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001583 EXPECT_EQ(primary_report.message().senders()->size(), 3);
Austin Schuh39788ff2019-12-01 18:22:57 -08001584
1585 // Confirm that the sender looks sane.
1586 EXPECT_EQ(
1587 loop1->configuration()
1588 ->channels()
1589 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1590 ->name()
1591 ->string_view(),
1592 "/test");
1593 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1594
1595 // Confirm that the timing primary_report sender looks sane.
1596 EXPECT_EQ(
1597 loop1->configuration()
1598 ->channels()
1599 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1600 ->name()
1601 ->string_view(),
1602 "/aos");
1603 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1604
1605 ASSERT_NE(primary_report.message().timers(), nullptr);
1606 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1607
1608 // Make sure there are no phased loops or watchers.
1609 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1610 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1611}
1612
1613// Tests that senders count correctly in the timing report.
1614TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1615 FLAGS_timing_report_ms = 1000;
1616 auto loop1 = MakePrimary();
1617 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1618
1619 auto loop2 = Make("sender_loop");
1620
1621 auto loop3 = Make();
1622
1623 Fetcher<timing::Report> report_fetcher =
1624 loop3->MakeFetcher<timing::Report>("/aos");
1625 EXPECT_FALSE(report_fetcher.Fetch());
1626
1627 auto sender = loop2->MakeSender<TestMessage>("/test");
1628
1629 // Add a timer to actually quit.
1630 auto test_timer = loop1->AddTimer([&sender]() {
1631 for (int i = 0; i < 10; ++i) {
1632 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1633 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1634 builder.add_value(200 + i);
1635 ASSERT_TRUE(msg.Send(builder.Finish()));
1636 }
1637 });
1638
1639 // Quit after 1 timing report, mid way through the next cycle.
1640 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1641
1642 loop1->OnRun([&test_timer, &loop1]() {
1643 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1644 });
1645
1646 Run();
1647
1648 // And, since we are here, check that the timing report makes sense.
1649 // Start by looking for our event loop's timing.
1650 FlatbufferDetachedBuffer<timing::Report> primary_report =
1651 FlatbufferDetachedBuffer<timing::Report>::Empty();
1652 while (report_fetcher.FetchNext()) {
1653 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1654 if (report_fetcher->name()->string_view() == "primary") {
1655 primary_report = CopyFlatBuffer(report_fetcher.get());
1656 }
1657 }
1658
1659 // Check the watcher report.
Ravago Jonescf453ab2020-05-06 21:14:53 -07001660 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001661
1662 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1663
1664 // Just the timing report timer.
1665 ASSERT_NE(primary_report.message().timers(), nullptr);
1666 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1667
1668 // No phased loops
1669 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1670
1671 ASSERT_NE(primary_report.message().watchers(), nullptr);
1672 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1673 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1674}
1675
1676// Tests that fetchers count correctly in the timing report.
1677TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1678 FLAGS_timing_report_ms = 1000;
1679 auto loop1 = MakePrimary();
1680 auto loop2 = Make("sender_loop");
1681
1682 auto loop3 = Make();
1683
1684 Fetcher<timing::Report> report_fetcher =
1685 loop3->MakeFetcher<timing::Report>("/aos");
1686 EXPECT_FALSE(report_fetcher.Fetch());
1687
1688 auto sender = loop2->MakeSender<TestMessage>("/test");
1689 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1690 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1691 fetcher1.Fetch();
1692 fetcher2.Fetch();
1693
1694 // Add a timer to actually quit.
1695 auto test_timer = loop1->AddTimer([&sender]() {
1696 for (int i = 0; i < 10; ++i) {
1697 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1698 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1699 builder.add_value(200 + i);
1700 ASSERT_TRUE(msg.Send(builder.Finish()));
1701 }
1702 });
1703
1704 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1705 fetcher1.Fetch();
1706 while (fetcher2.FetchNext()) {
1707 }
1708 });
1709
1710 // Quit after 1 timing report, mid way through the next cycle.
1711 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1712
1713 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1714 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1715 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1716 });
1717
1718 Run();
1719
1720 // And, since we are here, check that the timing report makes sense.
1721 // Start by looking for our event loop's timing.
1722 FlatbufferDetachedBuffer<timing::Report> primary_report =
1723 FlatbufferDetachedBuffer<timing::Report>::Empty();
1724 while (report_fetcher.FetchNext()) {
1725 if (report_fetcher->name()->string_view() == "primary") {
1726 primary_report = CopyFlatBuffer(report_fetcher.get());
1727 }
1728 }
1729
Ravago Jonescf453ab2020-05-06 21:14:53 -07001730 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001731
1732 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1733
1734 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001735 EXPECT_EQ(primary_report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001736
1737 ASSERT_NE(primary_report.message().timers(), nullptr);
1738 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1739
1740 // Make sure there are no phased loops or watchers.
1741 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1742 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1743
1744 // Now look at the fetchrs.
1745 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1746 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1747
1748 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1749 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1750 0.1);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001751 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(), 0.1);
1752 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(), 0.1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001753 EXPECT_EQ(primary_report.message()
1754 .fetchers()
1755 ->Get(0)
1756 ->latency()
1757 ->standard_deviation(),
1758 0.0);
1759
1760 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001761}
1762
Austin Schuh67420a42019-12-21 21:55:04 -08001763// Tests that a raw watcher and raw fetcher can receive messages from a raw
1764// sender without messing up offsets.
1765TEST_P(AbstractEventLoopTest, RawBasic) {
1766 auto loop1 = Make();
1767 auto loop2 = MakePrimary();
1768 auto loop3 = Make();
1769
1770 const std::string kData("971 is the best");
1771
1772 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001773 loop1->MakeRawSender(configuration::GetChannel(
1774 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001775
1776 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001777 loop3->MakeRawFetcher(configuration::GetChannel(
1778 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001779
1780 loop2->OnRun(
1781 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1782
1783 bool happened = false;
1784 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001785 configuration::GetChannel(loop2->configuration(), "/test",
1786 "aos.TestMessage", "", nullptr),
Austin Schuh67420a42019-12-21 21:55:04 -08001787 [this, &kData, &fetcher, &happened](const Context &context,
1788 const void *message) {
1789 happened = true;
1790 EXPECT_EQ(std::string_view(kData),
1791 std::string_view(reinterpret_cast<const char *>(message),
1792 context.size));
1793 EXPECT_EQ(std::string_view(kData),
1794 std::string_view(reinterpret_cast<const char *>(context.data),
1795 context.size));
1796
1797 ASSERT_TRUE(fetcher->Fetch());
1798
1799 EXPECT_EQ(std::string_view(kData),
1800 std::string_view(
1801 reinterpret_cast<const char *>(fetcher->context().data),
1802 fetcher->context().size));
1803
1804 this->Exit();
1805 });
1806
1807 EXPECT_FALSE(happened);
1808 Run();
1809 EXPECT_TRUE(happened);
1810}
1811
Austin Schuhad154822019-12-27 15:45:13 -08001812// Tests that a raw watcher and raw fetcher can receive messages from a raw
1813// sender with remote times filled out.
1814TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1815 auto loop1 = Make();
1816 auto loop2 = MakePrimary();
1817 auto loop3 = Make();
1818
1819 const std::string kData("971 is the best");
1820
1821 const aos::monotonic_clock::time_point monotonic_remote_time =
1822 aos::monotonic_clock::time_point(chrono::seconds(1501));
1823 const aos::realtime_clock::time_point realtime_remote_time =
1824 aos::realtime_clock::time_point(chrono::seconds(3132));
1825
1826 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001827 loop1->MakeRawSender(configuration::GetChannel(
1828 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001829
1830 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001831 loop3->MakeRawFetcher(configuration::GetChannel(
1832 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001833
1834 loop2->OnRun([&]() {
1835 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1836 realtime_remote_time));
1837 });
1838
1839 bool happened = false;
1840 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001841 configuration::GetChannel(loop2->configuration(), "/test",
1842 "aos.TestMessage", "", nullptr),
Austin Schuhad154822019-12-27 15:45:13 -08001843 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1844 const Context &context, const void * /*message*/) {
1845 happened = true;
1846 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1847 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1848
1849 ASSERT_TRUE(fetcher->Fetch());
1850 EXPECT_EQ(monotonic_remote_time,
1851 fetcher->context().monotonic_remote_time);
1852 EXPECT_EQ(realtime_remote_time,
1853 fetcher->context().realtime_remote_time);
1854
1855 this->Exit();
1856 });
1857
1858 EXPECT_FALSE(happened);
1859 Run();
1860 EXPECT_TRUE(happened);
1861}
1862
1863// Tests that a raw sender fills out sent data.
1864TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1865 auto loop1 = MakePrimary();
1866
1867 const std::string kData("971 is the best");
1868
1869 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001870 loop1->MakeRawSender(configuration::GetChannel(
1871 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001872
Tyler Chatow67ddb032020-01-12 14:30:04 -08001873 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
1874 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001875
1876 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1877
1878 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1879 EXPECT_LE(sender->monotonic_sent_time(),
1880 monotonic_now + chrono::milliseconds(100));
1881 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1882 EXPECT_LE(sender->realtime_sent_time(),
1883 realtime_now + chrono::milliseconds(100));
1884 EXPECT_EQ(sender->sent_queue_index(), 0u);
1885
1886 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1887
1888 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1889 EXPECT_LE(sender->monotonic_sent_time(),
1890 monotonic_now + chrono::milliseconds(100));
1891 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1892 EXPECT_LE(sender->realtime_sent_time(),
1893 realtime_now + chrono::milliseconds(100));
1894 EXPECT_EQ(sender->sent_queue_index(), 1u);
1895}
1896
Austin Schuh217a9782019-12-21 23:02:50 -08001897// Tests that not setting up nodes results in no node.
1898TEST_P(AbstractEventLoopTest, NoNode) {
1899 auto loop1 = Make();
1900 auto loop2 = MakePrimary();
1901
1902 EXPECT_EQ(loop1->node(), nullptr);
1903 EXPECT_EQ(loop2->node(), nullptr);
1904}
1905
1906// Tests that setting up nodes results in node being set.
1907TEST_P(AbstractEventLoopTest, Node) {
1908 EnableNodes("me");
1909
1910 auto loop1 = Make();
1911 auto loop2 = MakePrimary();
1912
1913 EXPECT_NE(loop1->node(), nullptr);
1914 EXPECT_NE(loop2->node(), nullptr);
1915}
1916
1917// Tests that watchers work with a node setup.
1918TEST_P(AbstractEventLoopTest, NodeWatcher) {
1919 EnableNodes("me");
1920
1921 auto loop1 = Make();
1922 auto loop2 = Make();
1923 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08001924 loop2->MakeRawWatcher(
1925 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1926 nullptr),
1927 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001928}
1929
Brian Silverman454bc112020-03-05 14:21:25 -08001930// Tests that no-arg watchers work with a node setup.
1931TEST_P(AbstractEventLoopTest, NodeNoArgWatcher) {
1932 EnableNodes("me");
1933
1934 auto loop1 = Make();
1935 auto loop2 = Make();
1936 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1937 loop2->MakeRawNoArgWatcher(
1938 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1939 nullptr),
1940 [](const Context &) {});
1941}
1942
Austin Schuh217a9782019-12-21 23:02:50 -08001943// Tests that fetcher work with a node setup.
1944TEST_P(AbstractEventLoopTest, NodeFetcher) {
1945 EnableNodes("me");
1946 auto loop1 = Make();
1947
1948 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08001949 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1950 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001951}
1952
1953// Tests that sender work with a node setup.
1954TEST_P(AbstractEventLoopTest, NodeSender) {
1955 EnableNodes("me");
1956 auto loop1 = Make();
1957
1958 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1959}
1960
Austin Schuhcc6070c2020-10-10 20:25:56 -07001961// Tests that a non-realtime event loop timer is marked non-realtime.
1962TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopTimer) {
1963 auto loop1 = MakePrimary();
1964
1965 // Add a timer to actually quit.
1966 auto test_timer = loop1->AddTimer([this]() {
1967 CheckNotRealtime();
1968 this->Exit();
1969 });
1970
1971 loop1->OnRun([&test_timer, &loop1]() {
1972 CheckNotRealtime();
1973 test_timer->Setup(loop1->monotonic_now(), ::std::chrono::milliseconds(100));
1974 });
1975
1976 Run();
1977}
1978
1979// Tests that a realtime event loop timer is marked realtime.
1980TEST_P(AbstractEventLoopTest, RealtimeEventLoopTimer) {
1981 auto loop1 = MakePrimary();
1982
1983 loop1->SetRuntimeRealtimePriority(1);
1984
1985 // Add a timer to actually quit.
1986 auto test_timer = loop1->AddTimer([this]() {
1987 CheckRealtime();
1988 this->Exit();
1989 });
1990
1991 loop1->OnRun([&test_timer, &loop1]() {
1992 CheckRealtime();
1993 test_timer->Setup(loop1->monotonic_now(), ::std::chrono::milliseconds(100));
1994 });
1995
1996 Run();
1997}
1998
1999// Tests that a non-realtime event loop phased loop is marked non-realtime.
2000TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopPhasedLoop) {
2001 auto loop1 = MakePrimary();
2002
2003 // Add a timer to actually quit.
2004 loop1->AddPhasedLoop(
2005 [this](int) {
2006 CheckNotRealtime();
2007 this->Exit();
2008 },
2009 chrono::seconds(1), chrono::seconds(0));
2010
2011 Run();
2012}
2013
2014// Tests that a realtime event loop phased loop is marked realtime.
2015TEST_P(AbstractEventLoopTest, RealtimeEventLoopPhasedLoop) {
2016 auto loop1 = MakePrimary();
2017
2018 loop1->SetRuntimeRealtimePriority(1);
2019
2020 // Add a timer to actually quit.
2021 loop1->AddPhasedLoop(
2022 [this](int) {
2023 CheckRealtime();
2024 this->Exit();
2025 },
2026 chrono::seconds(1), chrono::seconds(0));
2027
2028 Run();
2029}
2030
2031// Tests that a non-realtime event loop watcher is marked non-realtime.
2032TEST_P(AbstractEventLoopTest, NonRealtimeEventLoopWatcher) {
2033 auto loop1 = MakePrimary();
2034 auto loop2 = Make();
2035
2036 aos::Sender<TestMessage> sender = loop2->MakeSender<TestMessage>("/test");
2037
2038 loop1->OnRun([&]() {
2039 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
2040 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
2041 ASSERT_TRUE(msg.Send(builder.Finish()));
2042 });
2043
2044 loop1->MakeWatcher("/test", [&](const TestMessage &) {
2045 CheckNotRealtime();
2046 this->Exit();
2047 });
2048
2049 Run();
2050}
2051
2052// Tests that a realtime event loop watcher is marked realtime.
2053TEST_P(AbstractEventLoopTest, RealtimeEventLoopWatcher) {
2054 auto loop1 = MakePrimary();
2055 auto loop2 = Make();
2056
2057 loop1->SetRuntimeRealtimePriority(1);
2058
2059 aos::Sender<TestMessage> sender = loop2->MakeSender<TestMessage>("/test");
2060
2061 loop1->OnRun([&]() {
2062 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
2063 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
2064 ASSERT_TRUE(msg.Send(builder.Finish()));
2065 });
2066
2067 loop1->MakeWatcher("/test", [&](const TestMessage &) {
2068 CheckRealtime();
2069 this->Exit();
2070 });
2071
2072 Run();
2073}
2074
Austin Schuh217a9782019-12-21 23:02:50 -08002075// Tests that watchers fail when created on the wrong node.
2076TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
2077 EnableNodes("them");
2078
2079 auto loop1 = Make();
2080 auto loop2 = Make();
2081 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
2082 "node");
2083 EXPECT_DEATH(
2084 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08002085 loop2->MakeRawWatcher(
2086 configuration::GetChannel(configuration(), "/test",
2087 "aos.TestMessage", "", nullptr),
2088 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08002089 },
2090 "node");
Brian Silverman454bc112020-03-05 14:21:25 -08002091 EXPECT_DEATH({ loop1->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
2092 "node");
2093 EXPECT_DEATH(
2094 {
2095 loop2->MakeRawNoArgWatcher(
2096 configuration::GetChannel(configuration(), "/test",
2097 "aos.TestMessage", "", nullptr),
2098 [](const Context &) {});
2099 },
2100 "node");
Austin Schuh217a9782019-12-21 23:02:50 -08002101}
2102
2103// Tests that fetchers fail when created on the wrong node.
2104TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
2105 EnableNodes("them");
2106 auto loop1 = Make();
2107
2108 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
2109 "node");
2110 EXPECT_DEATH(
2111 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08002112 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
2113 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08002114 },
2115 "node");
2116}
2117
2118// Tests that senders fail when created on the wrong node.
2119TEST_P(AbstractEventLoopDeathTest, NodeSender) {
2120 EnableNodes("them");
2121 auto loop1 = Make();
2122
2123 EXPECT_DEATH(
2124 {
2125 aos::Sender<TestMessage> sender =
2126 loop1->MakeSender<TestMessage>("/test");
2127 },
2128 "node");
2129
2130 // Note: Creating raw senders is always supported. Right now, this lets us
2131 // use them to create message_gateway.
2132}
2133
Brian Silverman341b57e2020-06-23 16:23:18 -07002134// Tests creating multiple Builders from a single Sender at the same time.
2135TEST_P(AbstractEventLoopDeathTest, MultipleBuilders) {
2136 auto loop1 = Make();
2137 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
2138
2139 { auto builder = sender.MakeBuilder(); }
2140 {
2141 auto builder = sender.MakeBuilder();
2142 builder.MakeBuilder<TestMessage>().Finish();
2143 }
2144 {
2145 // Creating this after the first one was destroyed should be fine.
2146 auto builder = sender.MakeBuilder();
2147 builder.MakeBuilder<TestMessage>().Finish();
2148 // But not a second one.
2149 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2150 "May not overwrite in-use allocator");
2151 }
2152
2153 FlatbufferDetachedBuffer<TestMessage> detached =
2154 flatbuffers::DetachedBuffer();
2155 {
2156 auto builder = sender.MakeBuilder();
2157 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2158 }
2159 {
2160 // This is the second one, after the detached one, so it should fail.
2161 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2162 "May not overwrite in-use allocator");
2163 }
2164
2165 // Clear the detached one, and then we should be able to create another.
2166 detached = flatbuffers::DetachedBuffer();
2167 {
2168 auto builder = sender.MakeBuilder();
2169 builder.MakeBuilder<TestMessage>().Finish();
2170 }
2171
2172 // And then detach another one.
2173 {
2174 auto builder = sender.MakeBuilder();
2175 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2176 }
2177}
2178
2179// Tests sending a buffer detached from a different builder.
2180TEST_P(AbstractEventLoopDeathTest, WrongDetachedBuffer) {
2181 auto loop1 = Make();
2182 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
2183 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
2184
2185 auto builder = sender1.MakeBuilder();
2186 FlatbufferDetachedBuffer<TestMessage> detached =
2187 builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2188 EXPECT_DEATH(sender2.SendDetached(std::move(detached)),
2189 "May only send the buffer detached from this Sender");
2190}
2191
Parker Schuhe4a70d62017-12-27 20:10:20 -08002192} // namespace testing
2193} // namespace aos