blob: 993011fa2061475b31313c3429923b396d28a7ee [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 Silvermanbd405c02020-06-23 16:25:23 -07001093// Verify that we can disable a timer during execution of another timer
1094// scheduled for the same time, with one ordering of creation for the timers.
1095//
1096// Also schedule some more events to reshuffle the heap in EventLoop used for
1097// tracking events to change up the order. This used to segfault
1098// SimulatedEventLoop.
1099TEST_P(AbstractEventLoopTest, TimerDisableOther) {
1100 for (bool creation_order : {true, false}) {
1101 for (bool setup_order : {true, false}) {
1102 for (int shuffle_events = 0; shuffle_events < 5; ++shuffle_events) {
1103 auto loop = MakePrimary();
1104 aos::TimerHandler *test_timer, *ender_timer;
1105 if (creation_order) {
1106 test_timer = loop->AddTimer([]() {});
1107 ender_timer =
1108 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1109 } else {
1110 ender_timer =
1111 loop->AddTimer([&test_timer]() { test_timer->Disable(); });
1112 test_timer = loop->AddTimer([]() {});
1113 }
1114
1115 const auto start = loop->monotonic_now();
1116
1117 for (int i = 0; i < shuffle_events; ++i) {
1118 loop->AddTimer([]() {})->Setup(start + std::chrono::milliseconds(10));
1119 }
1120
1121 if (setup_order) {
1122 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1123 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1124 } else {
1125 ender_timer->Setup(start + ::std::chrono::milliseconds(20));
1126 test_timer->Setup(start + ::std::chrono::milliseconds(20));
1127 }
1128 EndEventLoop(loop.get(), ::std::chrono::milliseconds(40));
1129 Run();
1130 }
1131 }
1132 }
1133}
1134
Austin Schuh54cf95f2019-11-29 13:14:18 -08001135// Verifies that the event loop implementations detect when Channel is not a
1136// pointer into confguration()
1137TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
1138 auto loop = MakePrimary();
1139
Tyler Chatow67ddb032020-01-12 14:30:04 -08001140 const Channel *channel = configuration::GetChannel(
1141 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
Austin Schuh54cf95f2019-11-29 13:14:18 -08001142
1143 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
1144
1145 EXPECT_DEATH(
1146 { loop->MakeRawSender(&channel_copy.message()); },
1147 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1148
1149 EXPECT_DEATH(
1150 { loop->MakeRawFetcher(&channel_copy.message()); },
1151 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1152
1153 EXPECT_DEATH(
1154 {
1155 loop->MakeRawWatcher(&channel_copy.message(),
1156 [](const Context, const void *) {});
1157 },
1158 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
1159}
1160
Brian Silverman454bc112020-03-05 14:21:25 -08001161// Verify that the send time on a message is roughly right when using a watcher.
Austin Schuh7267c532019-05-19 19:55:53 -07001162TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -07001163 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -07001164 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -08001165 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -07001166 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
1167
1168 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -07001169 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1170 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1171 builder.add_value(200);
1172 ASSERT_TRUE(msg.Send(builder.Finish()));
1173 });
1174
Austin Schuhad154822019-12-27 15:45:13 -08001175 bool triggered = false;
Brian Silverman454bc112020-03-05 14:21:25 -08001176 loop1->MakeWatcher("/test", [&](const TestMessage &msg) {
Austin Schuhad154822019-12-27 15:45:13 -08001177 // Confirm that the data pointer makes sense from a watcher, and all the
1178 // timestamps look right.
1179 EXPECT_GT(&msg, loop1->context().data);
1180 EXPECT_EQ(loop1->context().monotonic_remote_time,
1181 loop1->context().monotonic_event_time);
1182 EXPECT_EQ(loop1->context().realtime_remote_time,
1183 loop1->context().realtime_event_time);
1184
1185 const aos::monotonic_clock::time_point monotonic_now =
1186 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -08001187 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001188
1189 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1190 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1191 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1192 monotonic_now);
1193 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1194 realtime_now);
1195
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001196 EXPECT_LT(&msg, reinterpret_cast<const void *>(
1197 reinterpret_cast<const char *>(loop1->context().data) +
Austin Schuhad154822019-12-27 15:45:13 -08001198 loop1->context().size));
Brian Silverman4f4e0612020-08-12 19:54:41 -07001199 if (read_method() == ReadMethod::PIN) {
1200 EXPECT_GE(loop1->context().buffer_index, 0);
1201 EXPECT_LT(loop1->context().buffer_index,
1202 loop1->NumberBuffers(
1203 configuration::GetChannel(loop1->configuration(), "/test",
1204 "aos.TestMessage", "", nullptr)));
1205 } else {
1206 EXPECT_EQ(-1, loop1->context().buffer_index);
1207 }
Austin Schuhad154822019-12-27 15:45:13 -08001208 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -07001209 });
1210
1211 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1212
1213 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -07001214 Run();
Austin Schuh7267c532019-05-19 19:55:53 -07001215
Austin Schuhad154822019-12-27 15:45:13 -08001216 EXPECT_TRUE(triggered);
1217
Brian Silverman454bc112020-03-05 14:21:25 -08001218 ASSERT_TRUE(fetcher.Fetch());
1219
1220 monotonic_clock::duration monotonic_time_offset =
1221 fetcher.context().monotonic_event_time -
1222 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1223 realtime_clock::duration realtime_time_offset =
1224 fetcher.context().realtime_event_time -
1225 (loop1->realtime_now() - ::std::chrono::seconds(1));
1226
1227 EXPECT_EQ(fetcher.context().realtime_event_time,
1228 fetcher.context().realtime_remote_time);
1229 EXPECT_EQ(fetcher.context().monotonic_event_time,
1230 fetcher.context().monotonic_remote_time);
1231
1232 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1233 << ": Got "
1234 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1235 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1236 // Confirm that the data pointer makes sense.
1237 EXPECT_GT(fetcher.get(), fetcher.context().data);
1238 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001239 reinterpret_cast<const void *>(
1240 reinterpret_cast<const char *>(fetcher.context().data) +
Brian Silverman454bc112020-03-05 14:21:25 -08001241 fetcher.context().size));
1242 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1243 << ": Got "
1244 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1245 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1246
1247 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1248 << ": Got "
1249 << fetcher.context().realtime_event_time.time_since_epoch().count()
1250 << " expected " << loop1->realtime_now().time_since_epoch().count();
1251 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1252 << ": Got "
1253 << fetcher.context().realtime_event_time.time_since_epoch().count()
1254 << " expected " << loop1->realtime_now().time_since_epoch().count();
1255}
1256
1257// Verify that the send time on a message is roughly right when using a no-arg
1258// watcher. To get a message, we need to use a fetcher to actually access the
1259// message. This is also the main use case for no-arg fetchers.
1260TEST_P(AbstractEventLoopTest, MessageSendTimeNoArg) {
1261 auto loop1 = MakePrimary();
1262 auto loop2 = Make();
1263 auto sender = loop2->MakeSender<TestMessage>("/test");
1264 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1265
1266 auto test_timer = loop1->AddTimer([&sender]() {
1267 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1268 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1269 builder.add_value(200);
1270 ASSERT_TRUE(msg.Send(builder.Finish()));
1271 });
1272
1273 bool triggered = false;
1274 loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {
1275 // Confirm that we can indeed use a fetcher on this channel from this
1276 // context, and it results in a sane data pointer and timestamps.
1277 ASSERT_TRUE(fetcher.Fetch());
1278
1279 EXPECT_EQ(loop1->context().monotonic_remote_time,
1280 loop1->context().monotonic_event_time);
1281 EXPECT_EQ(loop1->context().realtime_remote_time,
1282 loop1->context().realtime_event_time);
1283
1284 const aos::monotonic_clock::time_point monotonic_now =
1285 loop1->monotonic_now();
1286 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
1287
1288 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1289 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1290 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1291 monotonic_now);
1292 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1293 realtime_now);
1294
1295 triggered = true;
1296 });
1297
1298 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1299
1300 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
1301 Run();
1302
1303 ASSERT_TRUE(triggered);
Austin Schuh7267c532019-05-19 19:55:53 -07001304
Alex Perrycb7da4b2019-08-28 19:35:56 -07001305 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001306 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001307 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1308 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001309 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001310 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -07001311
Austin Schuhad154822019-12-27 15:45:13 -08001312 EXPECT_EQ(fetcher.context().realtime_event_time,
1313 fetcher.context().realtime_remote_time);
1314 EXPECT_EQ(fetcher.context().monotonic_event_time,
1315 fetcher.context().monotonic_remote_time);
1316
Alex Perrycb7da4b2019-08-28 19:35:56 -07001317 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1318 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001319 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -07001320 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001321 // Confirm that the data pointer makes sense.
1322 EXPECT_GT(fetcher.get(), fetcher.context().data);
1323 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001324 reinterpret_cast<const void *>(
1325 reinterpret_cast<const char *>(fetcher.context().data) +
Alex Perrycb7da4b2019-08-28 19:35:56 -07001326 fetcher.context().size));
1327 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1328 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001329 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -07001330 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001331
1332 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1333 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001334 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001335 << " expected " << loop1->realtime_now().time_since_epoch().count();
1336 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1337 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001338 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001339 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -07001340}
1341
Austin Schuh52d325c2019-06-23 18:59:06 -07001342// Tests that a couple phased loops run in a row result in the correct offset
1343// and period.
1344TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -08001345 // Force a slower rate so we are guarenteed to have reports for our phased
1346 // loop.
1347 FLAGS_timing_report_ms = 2000;
1348
Austin Schuh52d325c2019-06-23 18:59:06 -07001349 const chrono::milliseconds kOffset = chrono::milliseconds(400);
1350 const int kCount = 5;
1351
1352 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -08001353 auto loop2 = Make();
1354
1355 Fetcher<timing::Report> report_fetcher =
1356 loop2->MakeFetcher<timing::Report>("/aos");
1357 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001358
1359 // Collect up a couple of samples.
1360 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001361 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -07001362
1363 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -08001364 loop1
1365 ->AddPhasedLoop(
1366 [&times, &expected_times, &loop1, this](int count) {
1367 EXPECT_EQ(count, 1);
1368 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -08001369 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -08001370
Austin Schuhad154822019-12-27 15:45:13 -08001371 EXPECT_EQ(loop1->context().monotonic_remote_time,
1372 monotonic_clock::min_time);
1373 EXPECT_EQ(loop1->context().realtime_event_time,
1374 realtime_clock::min_time);
1375 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -08001376 realtime_clock::min_time);
1377 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
1378 EXPECT_EQ(loop1->context().size, 0u);
1379 EXPECT_EQ(loop1->context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -07001380 EXPECT_EQ(loop1->context().buffer_index, -1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001381
1382 if (times.size() == kCount) {
1383 LOG(INFO) << "Exiting";
1384 this->Exit();
1385 }
1386 },
1387 chrono::seconds(1), kOffset)
1388 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -07001389
1390 // Add a delay to make sure that delay during startup doesn't result in a
1391 // "missed cycle".
1392 SleepFor(chrono::seconds(2));
1393
1394 Run();
1395
1396 // Confirm that we got both the right number of samples, and it's odd.
1397 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001398 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -07001399 EXPECT_EQ((times.size() % 2), 1);
1400
1401 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001402 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -07001403
1404 // Add up all the delays of all the times.
1405 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1406 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001407 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -07001408 }
1409
1410 // Average and add to the middle to find the average time.
1411 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001412 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -07001413
1414 // Compute the offset from the start of the second of the average time. This
1415 // should be pretty close to the offset.
1416 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001417 average_time.time_since_epoch() -
1418 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001419
1420 const chrono::milliseconds kEpsilon(100);
1421 EXPECT_LT(remainder, kOffset + kEpsilon);
1422 EXPECT_GT(remainder, kOffset - kEpsilon);
1423
1424 // Make sure that the average duration is close to 1 second.
1425 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1426 times.front())
1427 .count() /
1428 static_cast<double>(times.size() - 1),
1429 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001430
1431 // Confirm that the ideal wakeup times increment correctly.
1432 for (size_t i = 1; i < expected_times.size(); ++i) {
1433 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1434 }
1435
1436 for (size_t i = 0; i < expected_times.size(); ++i) {
1437 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1438 kOffset);
1439 }
1440
1441 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1442 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001443
1444 // And, since we are here, check that the timing report makes sense.
1445 // Start by looking for our event loop's timing.
1446 FlatbufferDetachedBuffer<timing::Report> report =
1447 FlatbufferDetachedBuffer<timing::Report>::Empty();
1448 while (report_fetcher.FetchNext()) {
1449 if (report_fetcher->name()->string_view() == "primary") {
1450 report = CopyFlatBuffer(report_fetcher.get());
1451 }
1452 }
1453
Ravago Jonescf453ab2020-05-06 21:14:53 -07001454 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001455
1456 EXPECT_EQ(report.message().name()->string_view(), "primary");
1457
1458 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001459 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001460
1461 ASSERT_NE(report.message().timers(), nullptr);
1462 EXPECT_EQ(report.message().timers()->size(), 1);
1463
1464 // Make sure there is a single phased loop report with our report in it.
1465 ASSERT_NE(report.message().phased_loops(), nullptr);
1466 ASSERT_EQ(report.message().phased_loops()->size(), 1);
1467 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
1468 "Test loop");
1469 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
1470}
1471
1472// Tests that senders count correctly in the timing report.
1473TEST_P(AbstractEventLoopTest, SenderTimingReport) {
1474 FLAGS_timing_report_ms = 1000;
1475 auto loop1 = MakePrimary();
1476
1477 auto loop2 = Make("watcher_loop");
1478 loop2->MakeWatcher("/test", [](const TestMessage &) {});
1479
1480 auto loop3 = Make();
1481
1482 Fetcher<timing::Report> report_fetcher =
1483 loop3->MakeFetcher<timing::Report>("/aos");
1484 EXPECT_FALSE(report_fetcher.Fetch());
1485
1486 auto sender = loop1->MakeSender<TestMessage>("/test");
1487
1488 // Add a timer to actually quit.
1489 auto test_timer = loop1->AddTimer([&sender]() {
1490 for (int i = 0; i < 10; ++i) {
1491 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1492 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1493 builder.add_value(200 + i);
1494 ASSERT_TRUE(msg.Send(builder.Finish()));
1495 }
1496 });
1497
1498 // Quit after 1 timing report, mid way through the next cycle.
1499 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1500
1501 loop1->OnRun([&test_timer, &loop1]() {
1502 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1503 });
1504
1505 Run();
1506
1507 // And, since we are here, check that the timing report makes sense.
1508 // Start by looking for our event loop's timing.
1509 FlatbufferDetachedBuffer<timing::Report> primary_report =
1510 FlatbufferDetachedBuffer<timing::Report>::Empty();
1511 while (report_fetcher.FetchNext()) {
1512 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1513 if (report_fetcher->name()->string_view() == "primary") {
1514 primary_report = CopyFlatBuffer(report_fetcher.get());
1515 }
1516 }
1517
Ravago Jonescf453ab2020-05-06 21:14:53 -07001518 LOG(INFO) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001519
1520 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1521
1522 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001523 EXPECT_EQ(primary_report.message().senders()->size(), 3);
Austin Schuh39788ff2019-12-01 18:22:57 -08001524
1525 // Confirm that the sender looks sane.
1526 EXPECT_EQ(
1527 loop1->configuration()
1528 ->channels()
1529 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1530 ->name()
1531 ->string_view(),
1532 "/test");
1533 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1534
1535 // Confirm that the timing primary_report sender looks sane.
1536 EXPECT_EQ(
1537 loop1->configuration()
1538 ->channels()
1539 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1540 ->name()
1541 ->string_view(),
1542 "/aos");
1543 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1544
1545 ASSERT_NE(primary_report.message().timers(), nullptr);
1546 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1547
1548 // Make sure there are no phased loops or watchers.
1549 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1550 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1551}
1552
1553// Tests that senders count correctly in the timing report.
1554TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1555 FLAGS_timing_report_ms = 1000;
1556 auto loop1 = MakePrimary();
1557 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1558
1559 auto loop2 = Make("sender_loop");
1560
1561 auto loop3 = Make();
1562
1563 Fetcher<timing::Report> report_fetcher =
1564 loop3->MakeFetcher<timing::Report>("/aos");
1565 EXPECT_FALSE(report_fetcher.Fetch());
1566
1567 auto sender = loop2->MakeSender<TestMessage>("/test");
1568
1569 // Add a timer to actually quit.
1570 auto test_timer = loop1->AddTimer([&sender]() {
1571 for (int i = 0; i < 10; ++i) {
1572 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1573 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1574 builder.add_value(200 + i);
1575 ASSERT_TRUE(msg.Send(builder.Finish()));
1576 }
1577 });
1578
1579 // Quit after 1 timing report, mid way through the next cycle.
1580 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1581
1582 loop1->OnRun([&test_timer, &loop1]() {
1583 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1584 });
1585
1586 Run();
1587
1588 // And, since we are here, check that the timing report makes sense.
1589 // Start by looking for our event loop's timing.
1590 FlatbufferDetachedBuffer<timing::Report> primary_report =
1591 FlatbufferDetachedBuffer<timing::Report>::Empty();
1592 while (report_fetcher.FetchNext()) {
1593 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1594 if (report_fetcher->name()->string_view() == "primary") {
1595 primary_report = CopyFlatBuffer(report_fetcher.get());
1596 }
1597 }
1598
1599 // Check the watcher report.
Ravago Jonescf453ab2020-05-06 21:14:53 -07001600 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001601
1602 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1603
1604 // Just the timing report timer.
1605 ASSERT_NE(primary_report.message().timers(), nullptr);
1606 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1607
1608 // No phased loops
1609 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1610
1611 ASSERT_NE(primary_report.message().watchers(), nullptr);
1612 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1613 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1614}
1615
1616// Tests that fetchers count correctly in the timing report.
1617TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1618 FLAGS_timing_report_ms = 1000;
1619 auto loop1 = MakePrimary();
1620 auto loop2 = Make("sender_loop");
1621
1622 auto loop3 = Make();
1623
1624 Fetcher<timing::Report> report_fetcher =
1625 loop3->MakeFetcher<timing::Report>("/aos");
1626 EXPECT_FALSE(report_fetcher.Fetch());
1627
1628 auto sender = loop2->MakeSender<TestMessage>("/test");
1629 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1630 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1631 fetcher1.Fetch();
1632 fetcher2.Fetch();
1633
1634 // Add a timer to actually quit.
1635 auto test_timer = loop1->AddTimer([&sender]() {
1636 for (int i = 0; i < 10; ++i) {
1637 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1638 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1639 builder.add_value(200 + i);
1640 ASSERT_TRUE(msg.Send(builder.Finish()));
1641 }
1642 });
1643
1644 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1645 fetcher1.Fetch();
1646 while (fetcher2.FetchNext()) {
1647 }
1648 });
1649
1650 // Quit after 1 timing report, mid way through the next cycle.
1651 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1652
1653 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1654 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1655 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1656 });
1657
1658 Run();
1659
1660 // And, since we are here, check that the timing report makes sense.
1661 // Start by looking for our event loop's timing.
1662 FlatbufferDetachedBuffer<timing::Report> primary_report =
1663 FlatbufferDetachedBuffer<timing::Report>::Empty();
1664 while (report_fetcher.FetchNext()) {
1665 if (report_fetcher->name()->string_view() == "primary") {
1666 primary_report = CopyFlatBuffer(report_fetcher.get());
1667 }
1668 }
1669
Ravago Jonescf453ab2020-05-06 21:14:53 -07001670 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001671
1672 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1673
1674 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001675 EXPECT_EQ(primary_report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001676
1677 ASSERT_NE(primary_report.message().timers(), nullptr);
1678 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1679
1680 // Make sure there are no phased loops or watchers.
1681 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1682 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1683
1684 // Now look at the fetchrs.
1685 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1686 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1687
1688 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1689 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1690 0.1);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001691 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(), 0.1);
1692 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(), 0.1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001693 EXPECT_EQ(primary_report.message()
1694 .fetchers()
1695 ->Get(0)
1696 ->latency()
1697 ->standard_deviation(),
1698 0.0);
1699
1700 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001701}
1702
Austin Schuh67420a42019-12-21 21:55:04 -08001703// Tests that a raw watcher and raw fetcher can receive messages from a raw
1704// sender without messing up offsets.
1705TEST_P(AbstractEventLoopTest, RawBasic) {
1706 auto loop1 = Make();
1707 auto loop2 = MakePrimary();
1708 auto loop3 = Make();
1709
1710 const std::string kData("971 is the best");
1711
1712 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001713 loop1->MakeRawSender(configuration::GetChannel(
1714 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001715
1716 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001717 loop3->MakeRawFetcher(configuration::GetChannel(
1718 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001719
1720 loop2->OnRun(
1721 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1722
1723 bool happened = false;
1724 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001725 configuration::GetChannel(loop2->configuration(), "/test",
1726 "aos.TestMessage", "", nullptr),
Austin Schuh67420a42019-12-21 21:55:04 -08001727 [this, &kData, &fetcher, &happened](const Context &context,
1728 const void *message) {
1729 happened = true;
1730 EXPECT_EQ(std::string_view(kData),
1731 std::string_view(reinterpret_cast<const char *>(message),
1732 context.size));
1733 EXPECT_EQ(std::string_view(kData),
1734 std::string_view(reinterpret_cast<const char *>(context.data),
1735 context.size));
1736
1737 ASSERT_TRUE(fetcher->Fetch());
1738
1739 EXPECT_EQ(std::string_view(kData),
1740 std::string_view(
1741 reinterpret_cast<const char *>(fetcher->context().data),
1742 fetcher->context().size));
1743
1744 this->Exit();
1745 });
1746
1747 EXPECT_FALSE(happened);
1748 Run();
1749 EXPECT_TRUE(happened);
1750}
1751
Austin Schuhad154822019-12-27 15:45:13 -08001752// Tests that a raw watcher and raw fetcher can receive messages from a raw
1753// sender with remote times filled out.
1754TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1755 auto loop1 = Make();
1756 auto loop2 = MakePrimary();
1757 auto loop3 = Make();
1758
1759 const std::string kData("971 is the best");
1760
1761 const aos::monotonic_clock::time_point monotonic_remote_time =
1762 aos::monotonic_clock::time_point(chrono::seconds(1501));
1763 const aos::realtime_clock::time_point realtime_remote_time =
1764 aos::realtime_clock::time_point(chrono::seconds(3132));
1765
1766 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001767 loop1->MakeRawSender(configuration::GetChannel(
1768 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001769
1770 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001771 loop3->MakeRawFetcher(configuration::GetChannel(
1772 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001773
1774 loop2->OnRun([&]() {
1775 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1776 realtime_remote_time));
1777 });
1778
1779 bool happened = false;
1780 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001781 configuration::GetChannel(loop2->configuration(), "/test",
1782 "aos.TestMessage", "", nullptr),
Austin Schuhad154822019-12-27 15:45:13 -08001783 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1784 const Context &context, const void * /*message*/) {
1785 happened = true;
1786 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1787 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1788
1789 ASSERT_TRUE(fetcher->Fetch());
1790 EXPECT_EQ(monotonic_remote_time,
1791 fetcher->context().monotonic_remote_time);
1792 EXPECT_EQ(realtime_remote_time,
1793 fetcher->context().realtime_remote_time);
1794
1795 this->Exit();
1796 });
1797
1798 EXPECT_FALSE(happened);
1799 Run();
1800 EXPECT_TRUE(happened);
1801}
1802
1803// Tests that a raw sender fills out sent data.
1804TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1805 auto loop1 = MakePrimary();
1806
1807 const std::string kData("971 is the best");
1808
1809 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001810 loop1->MakeRawSender(configuration::GetChannel(
1811 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001812
Tyler Chatow67ddb032020-01-12 14:30:04 -08001813 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
1814 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001815
1816 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1817
1818 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1819 EXPECT_LE(sender->monotonic_sent_time(),
1820 monotonic_now + chrono::milliseconds(100));
1821 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1822 EXPECT_LE(sender->realtime_sent_time(),
1823 realtime_now + chrono::milliseconds(100));
1824 EXPECT_EQ(sender->sent_queue_index(), 0u);
1825
1826 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1827
1828 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1829 EXPECT_LE(sender->monotonic_sent_time(),
1830 monotonic_now + chrono::milliseconds(100));
1831 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1832 EXPECT_LE(sender->realtime_sent_time(),
1833 realtime_now + chrono::milliseconds(100));
1834 EXPECT_EQ(sender->sent_queue_index(), 1u);
1835}
1836
Austin Schuh217a9782019-12-21 23:02:50 -08001837// Tests that not setting up nodes results in no node.
1838TEST_P(AbstractEventLoopTest, NoNode) {
1839 auto loop1 = Make();
1840 auto loop2 = MakePrimary();
1841
1842 EXPECT_EQ(loop1->node(), nullptr);
1843 EXPECT_EQ(loop2->node(), nullptr);
1844}
1845
1846// Tests that setting up nodes results in node being set.
1847TEST_P(AbstractEventLoopTest, Node) {
1848 EnableNodes("me");
1849
1850 auto loop1 = Make();
1851 auto loop2 = MakePrimary();
1852
1853 EXPECT_NE(loop1->node(), nullptr);
1854 EXPECT_NE(loop2->node(), nullptr);
1855}
1856
1857// Tests that watchers work with a node setup.
1858TEST_P(AbstractEventLoopTest, NodeWatcher) {
1859 EnableNodes("me");
1860
1861 auto loop1 = Make();
1862 auto loop2 = Make();
1863 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08001864 loop2->MakeRawWatcher(
1865 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1866 nullptr),
1867 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001868}
1869
Brian Silverman454bc112020-03-05 14:21:25 -08001870// Tests that no-arg watchers work with a node setup.
1871TEST_P(AbstractEventLoopTest, NodeNoArgWatcher) {
1872 EnableNodes("me");
1873
1874 auto loop1 = Make();
1875 auto loop2 = Make();
1876 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1877 loop2->MakeRawNoArgWatcher(
1878 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1879 nullptr),
1880 [](const Context &) {});
1881}
1882
Austin Schuh217a9782019-12-21 23:02:50 -08001883// Tests that fetcher work with a node setup.
1884TEST_P(AbstractEventLoopTest, NodeFetcher) {
1885 EnableNodes("me");
1886 auto loop1 = Make();
1887
1888 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08001889 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1890 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001891}
1892
1893// Tests that sender work with a node setup.
1894TEST_P(AbstractEventLoopTest, NodeSender) {
1895 EnableNodes("me");
1896 auto loop1 = Make();
1897
1898 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1899}
1900
1901// Tests that watchers fail when created on the wrong node.
1902TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
1903 EnableNodes("them");
1904
1905 auto loop1 = Make();
1906 auto loop2 = Make();
1907 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
1908 "node");
1909 EXPECT_DEATH(
1910 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001911 loop2->MakeRawWatcher(
1912 configuration::GetChannel(configuration(), "/test",
1913 "aos.TestMessage", "", nullptr),
1914 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001915 },
1916 "node");
Brian Silverman454bc112020-03-05 14:21:25 -08001917 EXPECT_DEATH({ loop1->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1918 "node");
1919 EXPECT_DEATH(
1920 {
1921 loop2->MakeRawNoArgWatcher(
1922 configuration::GetChannel(configuration(), "/test",
1923 "aos.TestMessage", "", nullptr),
1924 [](const Context &) {});
1925 },
1926 "node");
Austin Schuh217a9782019-12-21 23:02:50 -08001927}
1928
1929// Tests that fetchers fail when created on the wrong node.
1930TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
1931 EnableNodes("them");
1932 auto loop1 = Make();
1933
1934 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
1935 "node");
1936 EXPECT_DEATH(
1937 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001938 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1939 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001940 },
1941 "node");
1942}
1943
1944// Tests that senders fail when created on the wrong node.
1945TEST_P(AbstractEventLoopDeathTest, NodeSender) {
1946 EnableNodes("them");
1947 auto loop1 = Make();
1948
1949 EXPECT_DEATH(
1950 {
1951 aos::Sender<TestMessage> sender =
1952 loop1->MakeSender<TestMessage>("/test");
1953 },
1954 "node");
1955
1956 // Note: Creating raw senders is always supported. Right now, this lets us
1957 // use them to create message_gateway.
1958}
1959
Brian Silverman341b57e2020-06-23 16:23:18 -07001960// Tests creating multiple Builders from a single Sender at the same time.
1961TEST_P(AbstractEventLoopDeathTest, MultipleBuilders) {
1962 auto loop1 = Make();
1963 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1964
1965 { auto builder = sender.MakeBuilder(); }
1966 {
1967 auto builder = sender.MakeBuilder();
1968 builder.MakeBuilder<TestMessage>().Finish();
1969 }
1970 {
1971 // Creating this after the first one was destroyed should be fine.
1972 auto builder = sender.MakeBuilder();
1973 builder.MakeBuilder<TestMessage>().Finish();
1974 // But not a second one.
1975 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
1976 "May not overwrite in-use allocator");
1977 }
1978
1979 FlatbufferDetachedBuffer<TestMessage> detached =
1980 flatbuffers::DetachedBuffer();
1981 {
1982 auto builder = sender.MakeBuilder();
1983 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
1984 }
1985 {
1986 // This is the second one, after the detached one, so it should fail.
1987 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
1988 "May not overwrite in-use allocator");
1989 }
1990
1991 // Clear the detached one, and then we should be able to create another.
1992 detached = flatbuffers::DetachedBuffer();
1993 {
1994 auto builder = sender.MakeBuilder();
1995 builder.MakeBuilder<TestMessage>().Finish();
1996 }
1997
1998 // And then detach another one.
1999 {
2000 auto builder = sender.MakeBuilder();
2001 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2002 }
2003}
2004
2005// Tests sending a buffer detached from a different builder.
2006TEST_P(AbstractEventLoopDeathTest, WrongDetachedBuffer) {
2007 auto loop1 = Make();
2008 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
2009 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
2010
2011 auto builder = sender1.MakeBuilder();
2012 FlatbufferDetachedBuffer<TestMessage> detached =
2013 builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2014 EXPECT_DEATH(sender2.SendDetached(std::move(detached)),
2015 "May only send the buffer detached from this Sender");
2016}
2017
Parker Schuhe4a70d62017-12-27 20:10:20 -08002018} // namespace testing
2019} // namespace aos