blob: 248dcd38f13776f23cc4f640d97c8cb17b8f618b [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"
8#include "glog/logging.h"
Tyler Chatow67ddb032020-01-12 14:30:04 -08009#include "gmock/gmock.h"
10#include "gtest/gtest.h"
Austin Schuh9fe68f72019-08-10 19:32:03 -070011
Parker Schuhe4a70d62017-12-27 20:10:20 -080012namespace aos {
13namespace testing {
Austin Schuh52d325c2019-06-23 18:59:06 -070014namespace {
15namespace chrono = ::std::chrono;
16} // namespace
Parker Schuhe4a70d62017-12-27 20:10:20 -080017
Brian Silverman4f4e0612020-08-12 19:54:41 -070018::std::unique_ptr<EventLoop> AbstractEventLoopTest::Make(
19 std::string_view name) {
20 std::string name_copy(name);
21 if (name == "") {
22 name_copy = "loop";
23 name_copy += std::to_string(event_loop_count_);
24 }
25 ++event_loop_count_;
26 return factory_->Make(name_copy);
27}
28
29void AbstractEventLoopTest::VerifyBuffers(
30 int number_buffers,
31 std::vector<std::reference_wrapper<const Fetcher<TestMessage>>> fetchers,
32 std::vector<std::reference_wrapper<const Sender<TestMessage>>> senders) {
33 // The buffers which are in a sender.
34 std::unordered_set<int> in_sender;
35 for (const Sender<TestMessage> &sender : senders) {
36 const int this_buffer = sender.buffer_index();
37 CHECK_GE(this_buffer, 0);
38 CHECK_LT(this_buffer, number_buffers);
39 CHECK(in_sender.insert(this_buffer).second) << ": " << this_buffer;
40 }
41
42 if (read_method() != ReadMethod::PIN) {
43 // If we're not using PIN, we can't really verify anything about what
44 // buffers the fetchers have.
45 return;
46 }
47
48 // Mapping from TestMessage::value to buffer index.
49 std::unordered_map<int, int> fetcher_values;
50 for (const Fetcher<TestMessage> &fetcher : fetchers) {
51 if (!fetcher.get()) {
52 continue;
53 }
54 const int this_buffer = fetcher.context().buffer_index;
55 CHECK_GE(this_buffer, 0);
56 CHECK_LT(this_buffer, number_buffers);
57 CHECK(in_sender.count(this_buffer) == 0) << ": " << this_buffer;
58 const auto insert_result = fetcher_values.insert(
59 std::make_pair(fetcher.get()->value(), this_buffer));
60 if (!insert_result.second) {
61 CHECK_EQ(this_buffer, insert_result.first->second);
62 }
63 }
64}
65
Austin Schuh6b6dfa52019-06-12 20:16:20 -070066// Tests that watcher can receive messages from a sender.
Parker Schuhe4a70d62017-12-27 20:10:20 -080067// Also tests that OnRun() works.
68TEST_P(AbstractEventLoopTest, Basic) {
69 auto loop1 = Make();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070070 auto loop2 = MakePrimary();
71
Alex Perrycb7da4b2019-08-28 19:35:56 -070072 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
Austin Schuh6b6dfa52019-06-12 20:16:20 -070073
74 bool happened = false;
75
76 loop2->OnRun([&]() {
77 happened = true;
78
Alex Perrycb7da4b2019-08-28 19:35:56 -070079 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
80 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
81 builder.add_value(200);
82 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -070083 });
84
85 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070086 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -070087 this->Exit();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070088 });
89
90 EXPECT_FALSE(happened);
91 Run();
92 EXPECT_TRUE(happened);
93}
94
Brian Silverman341b57e2020-06-23 16:23:18 -070095// Tests that watcher can receive messages from a sender, sent via SendDetached.
96TEST_P(AbstractEventLoopTest, BasicSendDetached) {
97 auto loop1 = Make();
98 auto loop2 = MakePrimary();
99
100 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
101
102 FlatbufferDetachedBuffer<TestMessage> detached =
103 flatbuffers::DetachedBuffer();
104 {
105 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
106 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
107 builder.add_value(100);
108 detached = msg.Detach(builder.Finish());
109 }
110 detached = flatbuffers::DetachedBuffer();
111 {
112 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
113 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
114 builder.add_value(200);
115 detached = msg.Detach(builder.Finish());
116 }
117 ASSERT_TRUE(sender.SendDetached(std::move(detached)));
118
119 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
120 ASSERT_TRUE(fetcher.Fetch());
121 EXPECT_EQ(fetcher->value(), 200);
122}
123
Brian Silverman6b8a3c32020-03-06 11:26:14 -0800124// Verifies that a no-arg watcher will not have a data pointer.
125TEST_P(AbstractEventLoopTest, NoArgNoData) {
126 auto loop1 = Make();
127 auto loop2 = MakePrimary();
128
129 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
130
131 bool happened = false;
132
133 loop2->OnRun([&]() {
134 happened = true;
135
136 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
137 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
138 ASSERT_TRUE(msg.Send(builder.Finish()));
139 });
140
141 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
142 EXPECT_GT(loop2->context().size, 0u);
143 EXPECT_EQ(nullptr, loop2->context().data);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700144 EXPECT_EQ(-1, loop2->context().buffer_index);
Brian Silverman6b8a3c32020-03-06 11:26:14 -0800145 this->Exit();
146 });
147
148 EXPECT_FALSE(happened);
149 Run();
150 EXPECT_TRUE(happened);
151}
152
Brian Silverman454bc112020-03-05 14:21:25 -0800153// Tests that no-arg watcher can receive messages from a sender.
154// Also tests that OnRun() works.
155TEST_P(AbstractEventLoopTest, BasicNoArg) {
156 auto loop1 = Make();
157 auto loop2 = MakePrimary();
158
159 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
160
161 bool happened = false;
162
163 loop2->OnRun([&]() {
164 happened = true;
165
166 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
167 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
168 builder.add_value(200);
169 ASSERT_TRUE(msg.Send(builder.Finish()));
170 });
171
172 aos::Fetcher<TestMessage> fetcher = loop2->MakeFetcher<TestMessage>("/test");
173 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
174 ASSERT_TRUE(fetcher.Fetch());
175 EXPECT_EQ(fetcher->value(), 200);
176 this->Exit();
177 });
178
179 EXPECT_FALSE(happened);
180 Run();
181 EXPECT_TRUE(happened);
182}
183
184// Tests that a watcher can be created with an std::function.
185TEST_P(AbstractEventLoopTest, BasicFunction) {
186 auto loop1 = Make();
187 auto loop2 = MakePrimary();
188
189 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
190
191 bool happened = false;
192
193 loop2->OnRun([&]() {
194 happened = true;
195
196 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
197 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
198 builder.add_value(200);
199 ASSERT_TRUE(msg.Send(builder.Finish()));
200 });
201
202 loop2->MakeWatcher("/test", std::function<void(const TestMessage &)>(
203 [&](const TestMessage &message) {
204 EXPECT_EQ(message.value(), 200);
205 this->Exit();
206 }));
207
208 EXPECT_FALSE(happened);
209 Run();
210 EXPECT_TRUE(happened);
211}
212
Brian Silverman0fc69932020-01-24 21:54:02 -0800213// Tests that watcher can receive messages from two senders.
214// Also tests that OnRun() works.
215TEST_P(AbstractEventLoopTest, BasicTwoSenders) {
216 auto loop1 = Make();
217 auto loop2 = MakePrimary();
218
219 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
220 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
221
222 bool happened = false;
223
224 loop2->OnRun([&]() {
225 happened = true;
226
227 {
228 aos::Sender<TestMessage>::Builder msg = sender1.MakeBuilder();
229 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
230 builder.add_value(200);
231 ASSERT_TRUE(msg.Send(builder.Finish()));
232 }
233 {
234 aos::Sender<TestMessage>::Builder msg = sender2.MakeBuilder();
235 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
236 builder.add_value(200);
237 ASSERT_TRUE(msg.Send(builder.Finish()));
238 }
239 });
240
241 int messages_received = 0;
242 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
243 EXPECT_EQ(message.value(), 200);
244 this->Exit();
245 ++messages_received;
246 });
247
248 EXPECT_FALSE(happened);
249 Run();
250 EXPECT_TRUE(happened);
251 EXPECT_EQ(messages_received, 2);
252}
253
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700254// Tests that a fetcher can fetch from a sender.
255// Also tests that OnRun() works.
256TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
257 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800258 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700259 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800260
261 auto sender = loop1->MakeSender<TestMessage>("/test");
262
263 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
264
Austin Schuhbbce72d2019-05-26 15:11:46 -0700265 EXPECT_FALSE(fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -0800266 EXPECT_EQ(fetcher.get(), nullptr);
267
Austin Schuhad154822019-12-27 15:45:13 -0800268 EXPECT_EQ(fetcher.context().monotonic_event_time, monotonic_clock::min_time);
269 EXPECT_EQ(fetcher.context().monotonic_remote_time, monotonic_clock::min_time);
270 EXPECT_EQ(fetcher.context().realtime_event_time, realtime_clock::min_time);
271 EXPECT_EQ(fetcher.context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800272 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
273 EXPECT_EQ(fetcher.context().size, 0u);
274 EXPECT_EQ(fetcher.context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700275 EXPECT_EQ(fetcher.context().buffer_index, -1);
Austin Schuhbbce72d2019-05-26 15:11:46 -0700276
Alex Perrycb7da4b2019-08-28 19:35:56 -0700277 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
278 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
279 builder.add_value(200);
280 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700281
282 EXPECT_TRUE(fetcher.Fetch());
283 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700284 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -0800285
286 const chrono::milliseconds kEpsilon(100);
287
Austin Schuhad154822019-12-27 15:45:13 -0800288 const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
289 const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
290 EXPECT_EQ(fetcher.context().monotonic_event_time,
291 fetcher.context().monotonic_remote_time);
292 EXPECT_EQ(fetcher.context().realtime_event_time,
293 fetcher.context().realtime_remote_time);
294
295 EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
296 EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
297 EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
298 EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800299 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
300 EXPECT_EQ(fetcher.context().size, 20u);
301 EXPECT_NE(fetcher.context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700302 if (read_method() == ReadMethod::PIN) {
303 EXPECT_GE(fetcher.context().buffer_index, 0);
304 EXPECT_LT(fetcher.context().buffer_index,
305 loop2->NumberBuffers(fetcher.channel()));
306 } else {
307 EXPECT_EQ(fetcher.context().buffer_index, -1);
308 }
Parker Schuhe4a70d62017-12-27 20:10:20 -0800309}
310
Austin Schuh3578a2e2019-05-25 18:17:59 -0700311// Tests that watcher will receive all messages sent if they are sent after
312// initialization and before running.
313TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
314 auto loop1 = Make();
315 auto loop2 = MakePrimary();
316
317 auto sender = loop1->MakeSender<TestMessage>("/test");
318
319 ::std::vector<int> values;
320
321 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700322 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700323 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700324 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700325 }
326 });
327
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700328 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -0700329 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700330 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
331 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
332 builder.add_value(199);
333 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700334 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700335
336 loop2->OnRun([&]() {
337 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700338 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
339 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
340 builder.add_value(200);
341 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700342 }
343 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700344 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
345 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
346 builder.add_value(201);
347 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700348 }
349 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700350
351 Run();
352
353 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
354}
355
356// Tests that watcher will not receive messages sent before the watcher is
357// created.
358TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
359 auto loop1 = Make();
360 auto loop2 = MakePrimary();
361
362 auto sender = loop1->MakeSender<TestMessage>("/test");
363
364 ::std::vector<int> values;
365
366 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700367 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
368 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
369 builder.add_value(200);
370 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700371 }
372 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700373 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
374 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
375 builder.add_value(201);
376 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700377 }
378
379 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700380 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700381 });
382
383 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700384 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700385 loop2->OnRun([&test_timer, &loop2]() {
386 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
387 });
388
389 Run();
390 EXPECT_EQ(0, values.size());
391}
392
Austin Schuhbbce72d2019-05-26 15:11:46 -0700393// Tests that FetchNext gets all the messages sent after it is constructed.
394TEST_P(AbstractEventLoopTest, FetchNext) {
395 auto loop1 = Make();
396 auto loop2 = MakePrimary();
397
398 auto sender = loop1->MakeSender<TestMessage>("/test");
399 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
400
401 ::std::vector<int> values;
402
403 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700404 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
405 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
406 builder.add_value(200);
407 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700408 }
409 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700410 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
411 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
412 builder.add_value(201);
413 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700414 }
415
416 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700417 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700418 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700419 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700420 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700421 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700422 });
423
424 loop2->OnRun([&test_timer, &loop2]() {
425 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
426 });
427
428 Run();
429 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
430}
431
432// Tests that FetchNext gets no messages sent before it is constructed.
433TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
434 auto loop1 = Make();
435 auto loop2 = MakePrimary();
436
437 auto sender = loop1->MakeSender<TestMessage>("/test");
438
439 ::std::vector<int> values;
440
441 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700442 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
443 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
444 builder.add_value(200);
445 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700446 }
447 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700448 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
449 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
450 builder.add_value(201);
451 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700452 }
453
454 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
455
456 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700457 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700458 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700459 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700460 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700461 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700462 });
463
464 loop2->OnRun([&test_timer, &loop2]() {
465 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
466 });
467
468 Run();
469 EXPECT_THAT(0, values.size());
470}
471
472// Tests that Fetch returns the last message created before the loop was
473// started.
474TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
475 auto loop1 = Make();
476 auto loop2 = MakePrimary();
477
478 auto sender = loop1->MakeSender<TestMessage>("/test");
479
480 ::std::vector<int> values;
481
482 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700483 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
484 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
485 builder.add_value(200);
486 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700487 }
488 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700489 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
490 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
491 builder.add_value(201);
492 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700493 }
494
495 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
496
497 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700498 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700499 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700500 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700501 }
502 // Do it again to make sure we don't double fetch.
503 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700504 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700505 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700506 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700507 });
508
509 loop2->OnRun([&test_timer, &loop2]() {
510 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
511 });
512
513 Run();
514 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
515}
516
517// Tests that Fetch and FetchNext interleave as expected.
518TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
519 auto loop1 = Make();
520 auto loop2 = MakePrimary();
521
522 auto sender = loop1->MakeSender<TestMessage>("/test");
523
524 ::std::vector<int> values;
525
526 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700527 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
528 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
529 builder.add_value(200);
530 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700531 }
532 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700533 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
534 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
535 builder.add_value(201);
536 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700537 }
538
539 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
540
541 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700542 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700543 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700544 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700545 }
546
547 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700548 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
549 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
550 builder.add_value(202);
551 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700552 }
553 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700554 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
555 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
556 builder.add_value(203);
557 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700558 }
559 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700560 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
561 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
562 builder.add_value(204);
563 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700564 }
565
566 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700567 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700568 }
569
570 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700571 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700572 }
573
Austin Schuh9fe68f72019-08-10 19:32:03 -0700574 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700575 });
576
577 loop2->OnRun([&test_timer, &loop2]() {
578 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
579 });
580
581 Run();
582 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
583}
584
Austin Schuh3115a202019-05-27 21:02:14 -0700585// Tests that FetchNext behaves correctly when we get two messages in the queue
586// but don't consume the first until after the second has been sent.
587TEST_P(AbstractEventLoopTest, FetchNextTest) {
Austin Schuh3115a202019-05-27 21:02:14 -0700588 auto send_loop = Make();
589 auto fetch_loop = Make();
590 auto sender = send_loop->MakeSender<TestMessage>("/test");
591 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
592
593 {
Tyler Chatow67ddb032020-01-12 14:30:04 -0800594 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
595 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
596 builder.add_value(100);
597 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700598 }
599
600 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700601 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
602 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
603 builder.add_value(200);
604 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700605 }
606
607 ASSERT_TRUE(fetcher.FetchNext());
608 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700609 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700610
611 ASSERT_TRUE(fetcher.FetchNext());
612 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700613 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700614
615 // When we run off the end of the queue, expect to still have the old message:
616 ASSERT_FALSE(fetcher.FetchNext());
617 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700618 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700619}
620
Brian Silverman77162972020-08-12 19:52:40 -0700621// Verify that a fetcher still holds its data, even after falling behind.
622TEST_P(AbstractEventLoopTest, FetcherBehindData) {
623 auto send_loop = Make();
624 auto fetch_loop = Make();
625 auto sender = send_loop->MakeSender<TestMessage>("/test");
626 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
627 {
628 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
629 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
630 builder.add_value(1);
631 ASSERT_TRUE(msg.Send(builder.Finish()));
632 }
633 ASSERT_TRUE(fetcher.Fetch());
634 EXPECT_EQ(1, fetcher.get()->value());
635 for (int i = 0; i < 300; ++i) {
636 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
637 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
638 builder.add_value(i + 2);
639 ASSERT_TRUE(msg.Send(builder.Finish()));
640 }
641 EXPECT_EQ(1, fetcher.get()->value());
642}
643
644// Try a bunch of orderings of operations with fetchers and senders. Verify that
645// all the fetchers have the correct data at each step.
646TEST_P(AbstractEventLoopTest, FetcherPermutations) {
647 for (int max_save = 0; max_save < 5; ++max_save) {
648 SCOPED_TRACE("max_save=" + std::to_string(max_save));
649
650 auto send_loop = Make();
651 auto fetch_loop = Make();
652 auto sender = send_loop->MakeSender<TestMessage>("/test");
653 const auto send_message = [&sender](int i) {
654 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
655 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
656 builder.add_value(i);
657 ASSERT_TRUE(msg.Send(builder.Finish()));
658 };
659 std::vector<Fetcher<TestMessage>> fetchers;
660 for (int i = 0; i < 10; ++i) {
661 fetchers.emplace_back(fetch_loop->MakeFetcher<TestMessage>("/test"));
662 }
663 send_message(1);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700664 const auto verify_buffers = [&]() {
665 std::vector<std::reference_wrapper<const Fetcher<TestMessage>>>
666 fetchers_copy;
667 for (const auto &fetcher : fetchers) {
668 fetchers_copy.emplace_back(fetcher);
669 }
670 std::vector<std::reference_wrapper<const Sender<TestMessage>>>
671 senders_copy;
672 senders_copy.emplace_back(sender);
673 VerifyBuffers(send_loop->NumberBuffers(sender.channel()), fetchers_copy,
674 senders_copy);
675 };
Brian Silverman77162972020-08-12 19:52:40 -0700676 for (auto &fetcher : fetchers) {
677 ASSERT_TRUE(fetcher.Fetch());
Brian Silverman4f4e0612020-08-12 19:54:41 -0700678 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700679 EXPECT_EQ(1, fetcher.get()->value());
680 }
681
682 for (int save = 1; save <= max_save; ++save) {
683 SCOPED_TRACE("save=" + std::to_string(save));
684 send_message(100 + save);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700685 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700686 for (size_t i = 0; i < fetchers.size() - save; ++i) {
687 SCOPED_TRACE("fetcher=" + std::to_string(i));
688 ASSERT_TRUE(fetchers[i].Fetch());
Brian Silverman4f4e0612020-08-12 19:54:41 -0700689 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700690 EXPECT_EQ(100 + save, fetchers[i].get()->value());
691 }
692 for (size_t i = fetchers.size() - save; i < fetchers.size() - 1; ++i) {
693 SCOPED_TRACE("fetcher=" + std::to_string(i));
694 EXPECT_EQ(100 + (fetchers.size() - 1 - i), fetchers[i].get()->value());
695 }
696 EXPECT_EQ(1, fetchers.back().get()->value());
697 }
698
699 for (int i = 0; i < 300; ++i) {
700 send_message(200 + i);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700701 verify_buffers();
Brian Silverman77162972020-08-12 19:52:40 -0700702 }
703
704 for (size_t i = 0; i < fetchers.size() - max_save; ++i) {
705 SCOPED_TRACE("fetcher=" + std::to_string(i));
706 if (max_save > 0) {
707 EXPECT_EQ(100 + max_save, fetchers[i].get()->value());
708 } else {
709 EXPECT_EQ(1, fetchers[i].get()->value());
710 }
711 }
712 for (size_t i = fetchers.size() - max_save; i < fetchers.size() - 1; ++i) {
713 SCOPED_TRACE("fetcher=" + std::to_string(i));
714 EXPECT_EQ(100 + (fetchers.size() - 1 - i), fetchers[i].get()->value());
715 }
716 EXPECT_EQ(1, fetchers.back().get()->value());
717 }
718}
719
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800720// Verify that making a fetcher and watcher for "/test" succeeds.
721TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800722 auto loop = Make();
723 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800724 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800725}
726
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800727// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800728TEST_P(AbstractEventLoopTest, TwoFetcher) {
729 auto loop = Make();
730 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800731 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800732}
733
Alex Perrycb7da4b2019-08-28 19:35:56 -0700734// Verify that registering a watcher for an invalid channel name dies.
735TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
736 auto loop = Make();
737 EXPECT_DEATH(
738 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
739 "/test/invalid");
Brian Silverman454bc112020-03-05 14:21:25 -0800740 EXPECT_DEATH(
741 { loop->MakeNoArgWatcher<TestMessage>("/test/invalid", [&]() {}); },
742 "/test/invalid");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700743}
744
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800745// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700746TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800747 auto loop = Make();
748 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800749 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
750 "/test");
Brian Silverman454bc112020-03-05 14:21:25 -0800751 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
752}
753
754// Verify that registering a no-arg watcher twice for "/test" fails.
755TEST_P(AbstractEventLoopDeathTest, TwoNoArgWatcher) {
756 auto loop = Make();
757 loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {});
758 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
759 "/test");
760 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800761}
762
Austin Schuh3115a202019-05-27 21:02:14 -0700763// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700764TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700765 auto loop = MakePrimary();
766 // Confirm that runtime priority calls work when not realtime.
767 loop->SetRuntimeRealtimePriority(5);
768
769 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
770
771 EXPECT_DEATH(Run(), "realtime");
772}
773
Brian Silverman6a54ff32020-04-28 16:41:39 -0700774// Verify that SetRuntimeAffinity fails while running.
775TEST_P(AbstractEventLoopDeathTest, SetRuntimeAffinity) {
776 auto loop = MakePrimary();
777 // Confirm that runtime priority calls work when not running.
778 loop->SetRuntimeAffinity(MakeCpusetFromCpus({0}));
779
780 loop->OnRun([&]() { loop->SetRuntimeAffinity(MakeCpusetFromCpus({1})); });
781
782 EXPECT_DEATH(Run(), "Cannot set affinity while running");
783}
784
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800785// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700786TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800787 auto loop = Make();
788 auto sender = loop->MakeSender<TestMessage>("/test");
789 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
790 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800791}
792
Austin Schuhe516ab02020-05-06 21:37:04 -0700793// Verify that creating too many senders fails.
794TEST_P(AbstractEventLoopDeathTest, TooManySenders) {
795 auto loop = Make();
796 std::vector<aos::Sender<TestMessage>> senders;
797 for (int i = 0; i < 10; ++i) {
798 senders.emplace_back(loop->MakeSender<TestMessage>("/test"));
799 }
800 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); },
801 "Failed to create sender on \\{ \"name\": \"/test\", \"type\": "
Brian Silverman77162972020-08-12 19:52:40 -0700802 "\"aos.TestMessage\"[^}]*\\ }, too many senders.");
803}
804
805// Verify that creating too many fetchers fails.
806TEST_P(AbstractEventLoopDeathTest, TooManyFetchers) {
807 if (read_method() != ReadMethod::PIN) {
808 // Other read methods don't limit the number of readers, so just skip this.
809 return;
810 }
811
812 auto loop = Make();
813 std::vector<aos::Fetcher<TestMessage>> fetchers;
814 for (int i = 0; i < 10; ++i) {
815 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
816 }
817 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
818 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
819 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
820}
821
822// Verify that creating too many fetchers, split between two event loops, fails.
823TEST_P(AbstractEventLoopDeathTest, TooManyFetchersTwoLoops) {
824 if (read_method() != ReadMethod::PIN) {
825 // Other read methods don't limit the number of readers, so just skip this.
826 return;
827 }
828
829 auto loop = Make();
830 auto loop2 = Make();
831 std::vector<aos::Fetcher<TestMessage>> fetchers;
832 for (int i = 0; i < 5; ++i) {
833 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
834 fetchers.emplace_back(loop2->MakeFetcher<TestMessage>("/test"));
835 }
836 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
837 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
838 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
839}
840
841// Verify that creating too many watchers fails.
842TEST_P(AbstractEventLoopDeathTest, TooManyWatchers) {
843 if (read_method() != ReadMethod::PIN) {
844 // Other read methods don't limit the number of readers, so just skip this.
845 return;
846 }
847
848 std::vector<std::unique_ptr<EventLoop>> loops;
849 for (int i = 0; i < 10; ++i) {
850 loops.emplace_back(Make());
851 loops.back()->MakeWatcher("/test", [](const TestMessage &) {});
852 }
853 EXPECT_DEATH({ Make()->MakeWatcher("/test", [](const TestMessage &) {}); },
854 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
855 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
856}
857
858// Verify that creating too many watchers and fetchers combined fails.
859TEST_P(AbstractEventLoopDeathTest, TooManyWatchersAndFetchers) {
860 if (read_method() != ReadMethod::PIN) {
861 // Other read methods don't limit the number of readers, so just skip this.
862 return;
863 }
864
865 auto loop = Make();
866 std::vector<aos::Fetcher<TestMessage>> fetchers;
867 std::vector<std::unique_ptr<EventLoop>> loops;
868 for (int i = 0; i < 5; ++i) {
869 fetchers.emplace_back(loop->MakeFetcher<TestMessage>("/test"));
870 loops.emplace_back(Make());
871 loops.back()->MakeWatcher("/test", [](const TestMessage &) {});
872 }
873 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); },
874 "Failed to create reader on \\{ \"name\": \"/test\", \"type\": "
875 "\"aos.TestMessage\"[^}]*\\ }, too many readers.");
Austin Schuhe516ab02020-05-06 21:37:04 -0700876}
877
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700878// Verify that we can't create a sender inside OnRun.
879TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
880 auto loop1 = MakePrimary();
881
882 loop1->OnRun(
883 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
884
885 EXPECT_DEATH(Run(), "running");
886}
887
888// Verify that we can't create a watcher inside OnRun.
889TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
890 auto loop1 = MakePrimary();
891
892 loop1->OnRun(
893 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
894
895 EXPECT_DEATH(Run(), "running");
896}
897
Brian Silverman454bc112020-03-05 14:21:25 -0800898// Verify that we can't create a no-arg watcher inside OnRun.
899TEST_P(AbstractEventLoopDeathTest, NoArgWatcherInOnRun) {
900 auto loop1 = MakePrimary();
901
902 loop1->OnRun(
903 [&]() { loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {}); });
904
905 EXPECT_DEATH(Run(), "running");
906}
907
Parker Schuhe4a70d62017-12-27 20:10:20 -0800908// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800909TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
910 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700911 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800912
Austin Schuh3578a2e2019-05-25 18:17:59 -0700913 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
914 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700915 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700916 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700917 });
918
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800919 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700920
921 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700922 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
923 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
924 builder.add_value(200);
925 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700926 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800927
Austin Schuh44019f92019-05-19 19:58:27 -0700928 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800929}
930
Neil Balch229001a2018-01-07 18:22:52 -0800931// Verify that timer intervals and duration function properly.
932TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800933 // Force a slower rate so we are guarenteed to have reports for our timer.
934 FLAGS_timing_report_ms = 2000;
935
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800936 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800937
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800938 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800939 auto loop2 = Make();
940
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800941 ::std::vector<::aos::monotonic_clock::time_point> times;
942 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
943
Austin Schuh39788ff2019-12-01 18:22:57 -0800944 Fetcher<timing::Report> report_fetcher =
945 loop2->MakeFetcher<timing::Report>("/aos");
946 EXPECT_FALSE(report_fetcher.Fetch());
947
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800948 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
949 times.push_back(loop->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800950 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
951 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
952 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800953 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
954 EXPECT_EQ(loop->context().size, 0u);
955 EXPECT_EQ(loop->context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -0700956 EXPECT_EQ(loop->context().buffer_index, -1);
Austin Schuh39788ff2019-12-01 18:22:57 -0800957
Austin Schuhad154822019-12-27 15:45:13 -0800958 expected_times.push_back(loop->context().monotonic_event_time);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800959 if (times.size() == kCount) {
960 this->Exit();
961 }
Neil Balch229001a2018-01-07 18:22:52 -0800962 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800963 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800964
Austin Schuh39788ff2019-12-01 18:22:57 -0800965 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700966 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800967 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
968
Austin Schuh44019f92019-05-19 19:58:27 -0700969 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800970
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800971 // Confirm that we got both the right number of samples, and it's odd.
972 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
973 EXPECT_EQ(times.size(), expected_times.size());
974 EXPECT_EQ((times.size() % 2), 1);
975
976 // Grab the middle sample.
977 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
978
979 // Add up all the delays of all the times.
980 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
981 for (const ::aos::monotonic_clock::time_point time : times) {
982 sum += time - average_time;
983 }
984
985 // Average and add to the middle to find the average time.
986 sum /= times.size();
987 average_time += sum;
988
989 // Compute the offset from the average and the expected average. It
990 // should be pretty close to 0.
991 const ::aos::monotonic_clock::duration remainder =
992 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
993
994 const chrono::milliseconds kEpsilon(100);
995 EXPECT_LT(remainder, +kEpsilon);
996 EXPECT_GT(remainder, -kEpsilon);
997
998 // Make sure that the average duration is close to 1 second.
999 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1000 times.front())
1001 .count() /
1002 static_cast<double>(times.size() - 1),
1003 1.0, 0.1);
1004
1005 // Confirm that the ideal wakeup times increment correctly.
1006 for (size_t i = 1; i < expected_times.size(); ++i) {
1007 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1008 }
1009
1010 for (size_t i = 0; i < expected_times.size(); ++i) {
1011 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
1012 chrono::seconds(0));
1013 }
1014
1015 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1016 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001017
1018 // And, since we are here, check that the timing report makes sense.
1019 // Start by looking for our event loop's timing.
1020 FlatbufferDetachedBuffer<timing::Report> report =
1021 FlatbufferDetachedBuffer<timing::Report>::Empty();
1022 while (report_fetcher.FetchNext()) {
1023 if (report_fetcher->name()->string_view() == "primary") {
1024 report = CopyFlatBuffer(report_fetcher.get());
1025 }
1026 }
1027
1028 // Confirm that we have the right number of reports, and the contents are
1029 // sane.
Ravago Jonescf453ab2020-05-06 21:14:53 -07001030 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001031
1032 EXPECT_EQ(report.message().name()->string_view(), "primary");
1033
1034 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001035 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001036
1037 ASSERT_NE(report.message().timers(), nullptr);
1038 EXPECT_EQ(report.message().timers()->size(), 2);
1039
1040 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
1041 "Test loop");
1042 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
1043
1044 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
1045 "timing_reports");
1046 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
1047
1048 // Make sure there is a single phased loop report with our report in it.
1049 ASSERT_EQ(report.message().phased_loops(), nullptr);
Neil Balch229001a2018-01-07 18:22:52 -08001050}
1051
1052// Verify that we can change a timer's parameters during execution.
1053TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -07001054 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -08001055 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
1056
1057 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
1058 iteration_list.push_back(loop->monotonic_now());
1059 });
1060
1061 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
1062 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
1063 });
1064
Neil Balch229001a2018-01-07 18:22:52 -08001065 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
1066 modifier_timer->Setup(loop->monotonic_now() +
1067 ::std::chrono::milliseconds(45));
1068 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -07001069 Run();
Neil Balch229001a2018-01-07 18:22:52 -08001070
1071 EXPECT_EQ(iteration_list.size(), 7);
1072}
1073
1074// Verify that we can disable a timer during execution.
1075TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -07001076 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -08001077 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
1078
1079 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
1080 iteration_list.push_back(loop->monotonic_now());
1081 });
1082
Tyler Chatow67ddb032020-01-12 14:30:04 -08001083 auto ender_timer = loop->AddTimer([&test_timer]() { test_timer->Disable(); });
Neil Balch229001a2018-01-07 18:22:52 -08001084
1085 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
Tyler Chatow67ddb032020-01-12 14:30:04 -08001086 ender_timer->Setup(loop->monotonic_now() + ::std::chrono::milliseconds(45));
Neil Balch229001a2018-01-07 18:22:52 -08001087 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -07001088 Run();
Neil Balch229001a2018-01-07 18:22:52 -08001089
1090 EXPECT_EQ(iteration_list.size(), 3);
1091}
Austin Schuh7267c532019-05-19 19:55:53 -07001092
Brian Silvermanaf9a4d82020-10-06 15:10:58 -07001093// Verify that a timer can disable itself.
1094//
1095// TODO(Brian): Do something similar with phased loops, both with a quick
1096// handler and a handler that would miss a cycle except it got deferred. Current
1097// behavior doing that is a mess.
1098TEST_P(AbstractEventLoopTest, TimerDisableSelf) {
1099 auto loop = MakePrimary();
1100
1101 int count = 0;
1102 aos::TimerHandler *test_timer;
1103 test_timer = loop->AddTimer([&count, &test_timer]() {
1104 ++count;
1105 test_timer->Disable();
1106 });
1107
1108 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
1109 EndEventLoop(loop.get(), ::std::chrono::milliseconds(80));
1110 Run();
1111
1112 EXPECT_EQ(count, 1);
1113}
1114
Brian Silvermanbd405c02020-06-23 16:25:23 -07001115// Verify that we can disable a timer during execution of another timer
1116// scheduled for the same time, with one ordering of creation for the timers.
1117//
1118// Also schedule some more events to reshuffle the heap in EventLoop used for
1119// tracking events to change up the order. This used to segfault
1120// SimulatedEventLoop.
1121TEST_P(AbstractEventLoopTest, TimerDisableOther) {
1122 for (bool creation_order : {true, false}) {
1123 for (bool setup_order : {true, false}) {
1124 for (int shuffle_events = 0; shuffle_events < 5; ++shuffle_events) {
1125 auto loop = MakePrimary();
1126 aos::TimerHandler *test_timer, *ender_timer;
1127 if (creation_order) {
1128 test_timer = loop->AddTimer([]() {});
1129 ender_timer =
1130 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1131 } else {
1132 ender_timer =
1133 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1134 test_timer = loop->AddTimer([]() {});
1135 }
1136
1137 const auto start = loop->monotonic_now();
1138
1139 for (int i = 0; i < shuffle_events; ++i) {
1140 loop->AddTimer([]() {})->Setup(start + std::chrono::milliseconds(10));
1141 }
1142
1143 if (setup_order) {
1144 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1145 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1146 } else {
1147 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1148 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1149 }
1150 EndEventLoop(loop.get(), ::std::chrono::milliseconds(40));
1151 Run();
1152 }
1153 }
1154 }
1155}
1156
Austin Schuh54cf95f2019-11-29 13:14:18 -08001157// Verifies that the event loop implementations detect when Channel is not a
1158// pointer into confguration()
1159TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
1160 auto loop = MakePrimary();
1161
Tyler Chatow67ddb032020-01-12 14:30:04 -08001162 const Channel *channel = configuration::GetChannel(
1163 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
Austin Schuh54cf95f2019-11-29 13:14:18 -08001164
1165 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
1166
1167 EXPECT_DEATH(
1168 { loop->MakeRawSender(&channel_copy.message()); },
1169 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1170
1171 EXPECT_DEATH(
1172 { loop->MakeRawFetcher(&channel_copy.message()); },
1173 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1174
1175 EXPECT_DEATH(
1176 {
1177 loop->MakeRawWatcher(&channel_copy.message(),
1178 [](const Context, const void *) {});
1179 },
1180 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1181}
1182
Austin Schuhd54780b2020-10-03 16:26:02 -07001183// Verifies that the event loop implementations detect when Channel has an
1184// invalid alignment.
1185TEST_P(AbstractEventLoopDeathTest, InvalidChannelAlignment) {
1186 const char *const kError = "multiple of alignment";
1187 InvalidChannelAlignment();
1188
1189 auto loop = MakePrimary();
1190
1191 const Channel *channel = configuration::GetChannel(
1192 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
1193
1194 EXPECT_DEATH({ loop->MakeRawSender(channel); }, kError);
1195 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); }, kError);
1196
1197 EXPECT_DEATH({ loop->MakeRawFetcher(channel); }, kError);
1198 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); }, kError);
1199
1200 EXPECT_DEATH(
1201 { loop->MakeRawWatcher(channel, [](const Context &, const void *) {}); },
1202 kError);
1203 EXPECT_DEATH({ loop->MakeRawNoArgWatcher(channel, [](const Context &) {}); },
1204 kError);
1205
1206 EXPECT_DEATH({ loop->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1207 kError);
1208 EXPECT_DEATH({ loop->MakeWatcher("/test", [](const TestMessage &) {}); },
1209 kError);
1210}
1211
Brian Silverman454bc112020-03-05 14:21:25 -08001212// Verify that the send time on a message is roughly right when using a watcher.
Austin Schuh7267c532019-05-19 19:55:53 -07001213TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -07001214 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -07001215 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -08001216 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -07001217 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
1218
1219 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -07001220 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1221 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1222 builder.add_value(200);
1223 ASSERT_TRUE(msg.Send(builder.Finish()));
1224 });
1225
Austin Schuhad154822019-12-27 15:45:13 -08001226 bool triggered = false;
Brian Silverman454bc112020-03-05 14:21:25 -08001227 loop1->MakeWatcher("/test", [&](const TestMessage &msg) {
Austin Schuhad154822019-12-27 15:45:13 -08001228 // Confirm that the data pointer makes sense from a watcher, and all the
1229 // timestamps look right.
1230 EXPECT_GT(&msg, loop1->context().data);
1231 EXPECT_EQ(loop1->context().monotonic_remote_time,
1232 loop1->context().monotonic_event_time);
1233 EXPECT_EQ(loop1->context().realtime_remote_time,
1234 loop1->context().realtime_event_time);
1235
1236 const aos::monotonic_clock::time_point monotonic_now =
1237 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -08001238 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001239
1240 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1241 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1242 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1243 monotonic_now);
1244 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1245 realtime_now);
1246
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001247 EXPECT_LT(&msg, reinterpret_cast<const void *>(
1248 reinterpret_cast<const char *>(loop1->context().data) +
Austin Schuhad154822019-12-27 15:45:13 -08001249 loop1->context().size));
Brian Silverman4f4e0612020-08-12 19:54:41 -07001250 if (read_method() == ReadMethod::PIN) {
1251 EXPECT_GE(loop1->context().buffer_index, 0);
1252 EXPECT_LT(loop1->context().buffer_index,
1253 loop1->NumberBuffers(
1254 configuration::GetChannel(loop1->configuration(), "/test",
1255 "aos.TestMessage", "", nullptr)));
1256 } else {
1257 EXPECT_EQ(-1, loop1->context().buffer_index);
1258 }
Austin Schuhad154822019-12-27 15:45:13 -08001259 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -07001260 });
1261
1262 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1263
1264 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -07001265 Run();
Austin Schuh7267c532019-05-19 19:55:53 -07001266
Austin Schuhad154822019-12-27 15:45:13 -08001267 EXPECT_TRUE(triggered);
1268
Brian Silverman454bc112020-03-05 14:21:25 -08001269 ASSERT_TRUE(fetcher.Fetch());
1270
1271 monotonic_clock::duration monotonic_time_offset =
1272 fetcher.context().monotonic_event_time -
1273 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1274 realtime_clock::duration realtime_time_offset =
1275 fetcher.context().realtime_event_time -
1276 (loop1->realtime_now() - ::std::chrono::seconds(1));
1277
1278 EXPECT_EQ(fetcher.context().realtime_event_time,
1279 fetcher.context().realtime_remote_time);
1280 EXPECT_EQ(fetcher.context().monotonic_event_time,
1281 fetcher.context().monotonic_remote_time);
1282
1283 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1284 << ": Got "
1285 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1286 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1287 // Confirm that the data pointer makes sense.
1288 EXPECT_GT(fetcher.get(), fetcher.context().data);
1289 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001290 reinterpret_cast<const void *>(
1291 reinterpret_cast<const char *>(fetcher.context().data) +
Brian Silverman454bc112020-03-05 14:21:25 -08001292 fetcher.context().size));
1293 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1294 << ": Got "
1295 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1296 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1297
1298 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1299 << ": Got "
1300 << fetcher.context().realtime_event_time.time_since_epoch().count()
1301 << " expected " << loop1->realtime_now().time_since_epoch().count();
1302 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1303 << ": Got "
1304 << fetcher.context().realtime_event_time.time_since_epoch().count()
1305 << " expected " << loop1->realtime_now().time_since_epoch().count();
1306}
1307
1308// Verify that the send time on a message is roughly right when using a no-arg
1309// watcher. To get a message, we need to use a fetcher to actually access the
1310// message. This is also the main use case for no-arg fetchers.
1311TEST_P(AbstractEventLoopTest, MessageSendTimeNoArg) {
1312 auto loop1 = MakePrimary();
1313 auto loop2 = Make();
1314 auto sender = loop2->MakeSender<TestMessage>("/test");
1315 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1316
1317 auto test_timer = loop1->AddTimer([&sender]() {
1318 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1319 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1320 builder.add_value(200);
1321 ASSERT_TRUE(msg.Send(builder.Finish()));
1322 });
1323
1324 bool triggered = false;
1325 loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {
1326 // Confirm that we can indeed use a fetcher on this channel from this
1327 // context, and it results in a sane data pointer and timestamps.
1328 ASSERT_TRUE(fetcher.Fetch());
1329
1330 EXPECT_EQ(loop1->context().monotonic_remote_time,
1331 loop1->context().monotonic_event_time);
1332 EXPECT_EQ(loop1->context().realtime_remote_time,
1333 loop1->context().realtime_event_time);
1334
1335 const aos::monotonic_clock::time_point monotonic_now =
1336 loop1->monotonic_now();
1337 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
1338
1339 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1340 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1341 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1342 monotonic_now);
1343 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1344 realtime_now);
1345
1346 triggered = true;
1347 });
1348
1349 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1350
1351 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
1352 Run();
1353
1354 ASSERT_TRUE(triggered);
Austin Schuh7267c532019-05-19 19:55:53 -07001355
Alex Perrycb7da4b2019-08-28 19:35:56 -07001356 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001357 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001358 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1359 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001360 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001361 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -07001362
Austin Schuhad154822019-12-27 15:45:13 -08001363 EXPECT_EQ(fetcher.context().realtime_event_time,
1364 fetcher.context().realtime_remote_time);
1365 EXPECT_EQ(fetcher.context().monotonic_event_time,
1366 fetcher.context().monotonic_remote_time);
1367
Alex Perrycb7da4b2019-08-28 19:35:56 -07001368 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1369 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001370 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -07001371 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001372 // Confirm that the data pointer makes sense.
1373 EXPECT_GT(fetcher.get(), fetcher.context().data);
1374 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001375 reinterpret_cast<const void *>(
1376 reinterpret_cast<const char *>(fetcher.context().data) +
Alex Perrycb7da4b2019-08-28 19:35:56 -07001377 fetcher.context().size));
1378 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1379 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001380 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -07001381 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001382
1383 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1384 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001385 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001386 << " expected " << loop1->realtime_now().time_since_epoch().count();
1387 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1388 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001389 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001390 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -07001391}
1392
Austin Schuh52d325c2019-06-23 18:59:06 -07001393// Tests that a couple phased loops run in a row result in the correct offset
1394// and period.
1395TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -08001396 // Force a slower rate so we are guarenteed to have reports for our phased
1397 // loop.
1398 FLAGS_timing_report_ms = 2000;
1399
Austin Schuh52d325c2019-06-23 18:59:06 -07001400 const chrono::milliseconds kOffset = chrono::milliseconds(400);
1401 const int kCount = 5;
1402
1403 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -08001404 auto loop2 = Make();
1405
1406 Fetcher<timing::Report> report_fetcher =
1407 loop2->MakeFetcher<timing::Report>("/aos");
1408 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001409
1410 // Collect up a couple of samples.
1411 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001412 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -07001413
1414 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -08001415 loop1
1416 ->AddPhasedLoop(
1417 [&times, &expected_times, &loop1, this](int count) {
1418 EXPECT_EQ(count, 1);
1419 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -08001420 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -08001421
Austin Schuhad154822019-12-27 15:45:13 -08001422 EXPECT_EQ(loop1->context().monotonic_remote_time,
1423 monotonic_clock::min_time);
1424 EXPECT_EQ(loop1->context().realtime_event_time,
1425 realtime_clock::min_time);
1426 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -08001427 realtime_clock::min_time);
1428 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
1429 EXPECT_EQ(loop1->context().size, 0u);
1430 EXPECT_EQ(loop1->context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -07001431 EXPECT_EQ(loop1->context().buffer_index, -1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001432
1433 if (times.size() == kCount) {
1434 LOG(INFO) << "Exiting";
1435 this->Exit();
1436 }
1437 },
1438 chrono::seconds(1), kOffset)
1439 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -07001440
1441 // Add a delay to make sure that delay during startup doesn't result in a
1442 // "missed cycle".
1443 SleepFor(chrono::seconds(2));
1444
1445 Run();
1446
1447 // Confirm that we got both the right number of samples, and it's odd.
1448 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001449 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -07001450 EXPECT_EQ((times.size() % 2), 1);
1451
1452 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001453 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -07001454
1455 // Add up all the delays of all the times.
1456 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1457 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001458 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -07001459 }
1460
1461 // Average and add to the middle to find the average time.
1462 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001463 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -07001464
1465 // Compute the offset from the start of the second of the average time. This
1466 // should be pretty close to the offset.
1467 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001468 average_time.time_since_epoch() -
1469 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001470
1471 const chrono::milliseconds kEpsilon(100);
1472 EXPECT_LT(remainder, kOffset + kEpsilon);
1473 EXPECT_GT(remainder, kOffset - kEpsilon);
1474
1475 // Make sure that the average duration is close to 1 second.
1476 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1477 times.front())
1478 .count() /
1479 static_cast<double>(times.size() - 1),
1480 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001481
1482 // Confirm that the ideal wakeup times increment correctly.
1483 for (size_t i = 1; i < expected_times.size(); ++i) {
1484 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1485 }
1486
1487 for (size_t i = 0; i < expected_times.size(); ++i) {
1488 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1489 kOffset);
1490 }
1491
1492 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1493 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001494
1495 // And, since we are here, check that the timing report makes sense.
1496 // Start by looking for our event loop's timing.
1497 FlatbufferDetachedBuffer<timing::Report> report =
1498 FlatbufferDetachedBuffer<timing::Report>::Empty();
1499 while (report_fetcher.FetchNext()) {
1500 if (report_fetcher->name()->string_view() == "primary") {
1501 report = CopyFlatBuffer(report_fetcher.get());
1502 }
1503 }
1504
Ravago Jonescf453ab2020-05-06 21:14:53 -07001505 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001506
1507 EXPECT_EQ(report.message().name()->string_view(), "primary");
1508
1509 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001510 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001511
1512 ASSERT_NE(report.message().timers(), nullptr);
1513 EXPECT_EQ(report.message().timers()->size(), 1);
1514
1515 // Make sure there is a single phased loop report with our report in it.
1516 ASSERT_NE(report.message().phased_loops(), nullptr);
1517 ASSERT_EQ(report.message().phased_loops()->size(), 1);
1518 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
1519 "Test loop");
1520 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
1521}
1522
1523// Tests that senders count correctly in the timing report.
1524TEST_P(AbstractEventLoopTest, SenderTimingReport) {
1525 FLAGS_timing_report_ms = 1000;
1526 auto loop1 = MakePrimary();
1527
1528 auto loop2 = Make("watcher_loop");
1529 loop2->MakeWatcher("/test", [](const TestMessage &) {});
1530
1531 auto loop3 = Make();
1532
1533 Fetcher<timing::Report> report_fetcher =
1534 loop3->MakeFetcher<timing::Report>("/aos");
1535 EXPECT_FALSE(report_fetcher.Fetch());
1536
1537 auto sender = loop1->MakeSender<TestMessage>("/test");
1538
1539 // Add a timer to actually quit.
1540 auto test_timer = loop1->AddTimer([&sender]() {
1541 for (int i = 0; i < 10; ++i) {
1542 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1543 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1544 builder.add_value(200 + i);
1545 ASSERT_TRUE(msg.Send(builder.Finish()));
1546 }
1547 });
1548
1549 // Quit after 1 timing report, mid way through the next cycle.
1550 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1551
1552 loop1->OnRun([&test_timer, &loop1]() {
1553 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1554 });
1555
1556 Run();
1557
1558 // And, since we are here, check that the timing report makes sense.
1559 // Start by looking for our event loop's timing.
1560 FlatbufferDetachedBuffer<timing::Report> primary_report =
1561 FlatbufferDetachedBuffer<timing::Report>::Empty();
1562 while (report_fetcher.FetchNext()) {
1563 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1564 if (report_fetcher->name()->string_view() == "primary") {
1565 primary_report = CopyFlatBuffer(report_fetcher.get());
1566 }
1567 }
1568
Ravago Jonescf453ab2020-05-06 21:14:53 -07001569 LOG(INFO) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001570
1571 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1572
1573 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001574 EXPECT_EQ(primary_report.message().senders()->size(), 3);
Austin Schuh39788ff2019-12-01 18:22:57 -08001575
1576 // Confirm that the sender looks sane.
1577 EXPECT_EQ(
1578 loop1->configuration()
1579 ->channels()
1580 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1581 ->name()
1582 ->string_view(),
1583 "/test");
1584 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1585
1586 // Confirm that the timing primary_report sender looks sane.
1587 EXPECT_EQ(
1588 loop1->configuration()
1589 ->channels()
1590 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1591 ->name()
1592 ->string_view(),
1593 "/aos");
1594 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1595
1596 ASSERT_NE(primary_report.message().timers(), nullptr);
1597 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1598
1599 // Make sure there are no phased loops or watchers.
1600 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1601 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1602}
1603
1604// Tests that senders count correctly in the timing report.
1605TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1606 FLAGS_timing_report_ms = 1000;
1607 auto loop1 = MakePrimary();
1608 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1609
1610 auto loop2 = Make("sender_loop");
1611
1612 auto loop3 = Make();
1613
1614 Fetcher<timing::Report> report_fetcher =
1615 loop3->MakeFetcher<timing::Report>("/aos");
1616 EXPECT_FALSE(report_fetcher.Fetch());
1617
1618 auto sender = loop2->MakeSender<TestMessage>("/test");
1619
1620 // Add a timer to actually quit.
1621 auto test_timer = loop1->AddTimer([&sender]() {
1622 for (int i = 0; i < 10; ++i) {
1623 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1624 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1625 builder.add_value(200 + i);
1626 ASSERT_TRUE(msg.Send(builder.Finish()));
1627 }
1628 });
1629
1630 // Quit after 1 timing report, mid way through the next cycle.
1631 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1632
1633 loop1->OnRun([&test_timer, &loop1]() {
1634 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1635 });
1636
1637 Run();
1638
1639 // And, since we are here, check that the timing report makes sense.
1640 // Start by looking for our event loop's timing.
1641 FlatbufferDetachedBuffer<timing::Report> primary_report =
1642 FlatbufferDetachedBuffer<timing::Report>::Empty();
1643 while (report_fetcher.FetchNext()) {
1644 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1645 if (report_fetcher->name()->string_view() == "primary") {
1646 primary_report = CopyFlatBuffer(report_fetcher.get());
1647 }
1648 }
1649
1650 // Check the watcher report.
Ravago Jonescf453ab2020-05-06 21:14:53 -07001651 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001652
1653 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1654
1655 // Just the timing report timer.
1656 ASSERT_NE(primary_report.message().timers(), nullptr);
1657 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1658
1659 // No phased loops
1660 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1661
1662 ASSERT_NE(primary_report.message().watchers(), nullptr);
1663 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1664 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1665}
1666
1667// Tests that fetchers count correctly in the timing report.
1668TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1669 FLAGS_timing_report_ms = 1000;
1670 auto loop1 = MakePrimary();
1671 auto loop2 = Make("sender_loop");
1672
1673 auto loop3 = Make();
1674
1675 Fetcher<timing::Report> report_fetcher =
1676 loop3->MakeFetcher<timing::Report>("/aos");
1677 EXPECT_FALSE(report_fetcher.Fetch());
1678
1679 auto sender = loop2->MakeSender<TestMessage>("/test");
1680 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1681 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1682 fetcher1.Fetch();
1683 fetcher2.Fetch();
1684
1685 // Add a timer to actually quit.
1686 auto test_timer = loop1->AddTimer([&sender]() {
1687 for (int i = 0; i < 10; ++i) {
1688 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1689 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1690 builder.add_value(200 + i);
1691 ASSERT_TRUE(msg.Send(builder.Finish()));
1692 }
1693 });
1694
1695 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1696 fetcher1.Fetch();
1697 while (fetcher2.FetchNext()) {
1698 }
1699 });
1700
1701 // Quit after 1 timing report, mid way through the next cycle.
1702 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1703
1704 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1705 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1706 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1707 });
1708
1709 Run();
1710
1711 // And, since we are here, check that the timing report makes sense.
1712 // Start by looking for our event loop's timing.
1713 FlatbufferDetachedBuffer<timing::Report> primary_report =
1714 FlatbufferDetachedBuffer<timing::Report>::Empty();
1715 while (report_fetcher.FetchNext()) {
1716 if (report_fetcher->name()->string_view() == "primary") {
1717 primary_report = CopyFlatBuffer(report_fetcher.get());
1718 }
1719 }
1720
Ravago Jonescf453ab2020-05-06 21:14:53 -07001721 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001722
1723 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1724
1725 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001726 EXPECT_EQ(primary_report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001727
1728 ASSERT_NE(primary_report.message().timers(), nullptr);
1729 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1730
1731 // Make sure there are no phased loops or watchers.
1732 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1733 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1734
1735 // Now look at the fetchrs.
1736 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1737 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1738
1739 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1740 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1741 0.1);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001742 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(), 0.1);
1743 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(), 0.1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001744 EXPECT_EQ(primary_report.message()
1745 .fetchers()
1746 ->Get(0)
1747 ->latency()
1748 ->standard_deviation(),
1749 0.0);
1750
1751 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001752}
1753
Austin Schuh67420a42019-12-21 21:55:04 -08001754// Tests that a raw watcher and raw fetcher can receive messages from a raw
1755// sender without messing up offsets.
1756TEST_P(AbstractEventLoopTest, RawBasic) {
1757 auto loop1 = Make();
1758 auto loop2 = MakePrimary();
1759 auto loop3 = Make();
1760
1761 const std::string kData("971 is the best");
1762
1763 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001764 loop1->MakeRawSender(configuration::GetChannel(
1765 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001766
1767 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001768 loop3->MakeRawFetcher(configuration::GetChannel(
1769 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001770
1771 loop2->OnRun(
1772 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1773
1774 bool happened = false;
1775 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001776 configuration::GetChannel(loop2->configuration(), "/test",
1777 "aos.TestMessage", "", nullptr),
Austin Schuh67420a42019-12-21 21:55:04 -08001778 [this, &kData, &fetcher, &happened](const Context &context,
1779 const void *message) {
1780 happened = true;
1781 EXPECT_EQ(std::string_view(kData),
1782 std::string_view(reinterpret_cast<const char *>(message),
1783 context.size));
1784 EXPECT_EQ(std::string_view(kData),
1785 std::string_view(reinterpret_cast<const char *>(context.data),
1786 context.size));
1787
1788 ASSERT_TRUE(fetcher->Fetch());
1789
1790 EXPECT_EQ(std::string_view(kData),
1791 std::string_view(
1792 reinterpret_cast<const char *>(fetcher->context().data),
1793 fetcher->context().size));
1794
1795 this->Exit();
1796 });
1797
1798 EXPECT_FALSE(happened);
1799 Run();
1800 EXPECT_TRUE(happened);
1801}
1802
Austin Schuhad154822019-12-27 15:45:13 -08001803// Tests that a raw watcher and raw fetcher can receive messages from a raw
1804// sender with remote times filled out.
1805TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1806 auto loop1 = Make();
1807 auto loop2 = MakePrimary();
1808 auto loop3 = Make();
1809
1810 const std::string kData("971 is the best");
1811
1812 const aos::monotonic_clock::time_point monotonic_remote_time =
1813 aos::monotonic_clock::time_point(chrono::seconds(1501));
1814 const aos::realtime_clock::time_point realtime_remote_time =
1815 aos::realtime_clock::time_point(chrono::seconds(3132));
1816
1817 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001818 loop1->MakeRawSender(configuration::GetChannel(
1819 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001820
1821 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001822 loop3->MakeRawFetcher(configuration::GetChannel(
1823 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001824
1825 loop2->OnRun([&]() {
1826 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1827 realtime_remote_time));
1828 });
1829
1830 bool happened = false;
1831 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001832 configuration::GetChannel(loop2->configuration(), "/test",
1833 "aos.TestMessage", "", nullptr),
Austin Schuhad154822019-12-27 15:45:13 -08001834 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1835 const Context &context, const void * /*message*/) {
1836 happened = true;
1837 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1838 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1839
1840 ASSERT_TRUE(fetcher->Fetch());
1841 EXPECT_EQ(monotonic_remote_time,
1842 fetcher->context().monotonic_remote_time);
1843 EXPECT_EQ(realtime_remote_time,
1844 fetcher->context().realtime_remote_time);
1845
1846 this->Exit();
1847 });
1848
1849 EXPECT_FALSE(happened);
1850 Run();
1851 EXPECT_TRUE(happened);
1852}
1853
1854// Tests that a raw sender fills out sent data.
1855TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1856 auto loop1 = MakePrimary();
1857
1858 const std::string kData("971 is the best");
1859
1860 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001861 loop1->MakeRawSender(configuration::GetChannel(
1862 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001863
Tyler Chatow67ddb032020-01-12 14:30:04 -08001864 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
1865 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001866
1867 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1868
1869 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1870 EXPECT_LE(sender->monotonic_sent_time(),
1871 monotonic_now + chrono::milliseconds(100));
1872 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1873 EXPECT_LE(sender->realtime_sent_time(),
1874 realtime_now + chrono::milliseconds(100));
1875 EXPECT_EQ(sender->sent_queue_index(), 0u);
1876
1877 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1878
1879 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1880 EXPECT_LE(sender->monotonic_sent_time(),
1881 monotonic_now + chrono::milliseconds(100));
1882 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1883 EXPECT_LE(sender->realtime_sent_time(),
1884 realtime_now + chrono::milliseconds(100));
1885 EXPECT_EQ(sender->sent_queue_index(), 1u);
1886}
1887
Austin Schuh217a9782019-12-21 23:02:50 -08001888// Tests that not setting up nodes results in no node.
1889TEST_P(AbstractEventLoopTest, NoNode) {
1890 auto loop1 = Make();
1891 auto loop2 = MakePrimary();
1892
1893 EXPECT_EQ(loop1->node(), nullptr);
1894 EXPECT_EQ(loop2->node(), nullptr);
1895}
1896
1897// Tests that setting up nodes results in node being set.
1898TEST_P(AbstractEventLoopTest, Node) {
1899 EnableNodes("me");
1900
1901 auto loop1 = Make();
1902 auto loop2 = MakePrimary();
1903
1904 EXPECT_NE(loop1->node(), nullptr);
1905 EXPECT_NE(loop2->node(), nullptr);
1906}
1907
1908// Tests that watchers work with a node setup.
1909TEST_P(AbstractEventLoopTest, NodeWatcher) {
1910 EnableNodes("me");
1911
1912 auto loop1 = Make();
1913 auto loop2 = Make();
1914 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08001915 loop2->MakeRawWatcher(
1916 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1917 nullptr),
1918 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001919}
1920
Brian Silverman454bc112020-03-05 14:21:25 -08001921// Tests that no-arg watchers work with a node setup.
1922TEST_P(AbstractEventLoopTest, NodeNoArgWatcher) {
1923 EnableNodes("me");
1924
1925 auto loop1 = Make();
1926 auto loop2 = Make();
1927 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1928 loop2->MakeRawNoArgWatcher(
1929 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1930 nullptr),
1931 [](const Context &) {});
1932}
1933
Austin Schuh217a9782019-12-21 23:02:50 -08001934// Tests that fetcher work with a node setup.
1935TEST_P(AbstractEventLoopTest, NodeFetcher) {
1936 EnableNodes("me");
1937 auto loop1 = Make();
1938
1939 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08001940 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1941 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001942}
1943
1944// Tests that sender work with a node setup.
1945TEST_P(AbstractEventLoopTest, NodeSender) {
1946 EnableNodes("me");
1947 auto loop1 = Make();
1948
1949 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1950}
1951
1952// Tests that watchers fail when created on the wrong node.
1953TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
1954 EnableNodes("them");
1955
1956 auto loop1 = Make();
1957 auto loop2 = Make();
1958 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
1959 "node");
1960 EXPECT_DEATH(
1961 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001962 loop2->MakeRawWatcher(
1963 configuration::GetChannel(configuration(), "/test",
1964 "aos.TestMessage", "", nullptr),
1965 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001966 },
1967 "node");
Brian Silverman454bc112020-03-05 14:21:25 -08001968 EXPECT_DEATH({ loop1->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1969 "node");
1970 EXPECT_DEATH(
1971 {
1972 loop2->MakeRawNoArgWatcher(
1973 configuration::GetChannel(configuration(), "/test",
1974 "aos.TestMessage", "", nullptr),
1975 [](const Context &) {});
1976 },
1977 "node");
Austin Schuh217a9782019-12-21 23:02:50 -08001978}
1979
1980// Tests that fetchers fail when created on the wrong node.
1981TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
1982 EnableNodes("them");
1983 auto loop1 = Make();
1984
1985 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
1986 "node");
1987 EXPECT_DEATH(
1988 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001989 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1990 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001991 },
1992 "node");
1993}
1994
1995// Tests that senders fail when created on the wrong node.
1996TEST_P(AbstractEventLoopDeathTest, NodeSender) {
1997 EnableNodes("them");
1998 auto loop1 = Make();
1999
2000 EXPECT_DEATH(
2001 {
2002 aos::Sender<TestMessage> sender =
2003 loop1->MakeSender<TestMessage>("/test");
2004 },
2005 "node");
2006
2007 // Note: Creating raw senders is always supported. Right now, this lets us
2008 // use them to create message_gateway.
2009}
2010
Brian Silverman341b57e2020-06-23 16:23:18 -07002011// Tests creating multiple Builders from a single Sender at the same time.
2012TEST_P(AbstractEventLoopDeathTest, MultipleBuilders) {
2013 auto loop1 = Make();
2014 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
2015
2016 { auto builder = sender.MakeBuilder(); }
2017 {
2018 auto builder = sender.MakeBuilder();
2019 builder.MakeBuilder<TestMessage>().Finish();
2020 }
2021 {
2022 // Creating this after the first one was destroyed should be fine.
2023 auto builder = sender.MakeBuilder();
2024 builder.MakeBuilder<TestMessage>().Finish();
2025 // But not a second one.
2026 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2027 "May not overwrite in-use allocator");
2028 }
2029
2030 FlatbufferDetachedBuffer<TestMessage> detached =
2031 flatbuffers::DetachedBuffer();
2032 {
2033 auto builder = sender.MakeBuilder();
2034 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2035 }
2036 {
2037 // This is the second one, after the detached one, so it should fail.
2038 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2039 "May not overwrite in-use allocator");
2040 }
2041
2042 // Clear the detached one, and then we should be able to create another.
2043 detached = flatbuffers::DetachedBuffer();
2044 {
2045 auto builder = sender.MakeBuilder();
2046 builder.MakeBuilder<TestMessage>().Finish();
2047 }
2048
2049 // And then detach another one.
2050 {
2051 auto builder = sender.MakeBuilder();
2052 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2053 }
2054}
2055
2056// Tests sending a buffer detached from a different builder.
2057TEST_P(AbstractEventLoopDeathTest, WrongDetachedBuffer) {
2058 auto loop1 = Make();
2059 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
2060 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
2061
2062 auto builder = sender1.MakeBuilder();
2063 FlatbufferDetachedBuffer<TestMessage> detached =
2064 builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2065 EXPECT_DEATH(sender2.SendDetached(std::move(detached)),
2066 "May only send the buffer detached from this Sender");
2067}
2068
Parker Schuhe4a70d62017-12-27 20:10:20 -08002069} // namespace testing
2070} // namespace aos