blob: 979de748b3945a473053e83ef6d8ff50c8731dfb [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
Austin Schuhd54780b2020-10-03 16:26:02 -07001161// Verifies that the event loop implementations detect when Channel has an
1162// invalid alignment.
1163TEST_P(AbstractEventLoopDeathTest, InvalidChannelAlignment) {
1164 const char *const kError = "multiple of alignment";
1165 InvalidChannelAlignment();
1166
1167 auto loop = MakePrimary();
1168
1169 const Channel *channel = configuration::GetChannel(
1170 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
1171
1172 EXPECT_DEATH({ loop->MakeRawSender(channel); }, kError);
1173 EXPECT_DEATH({ loop->MakeSender<TestMessage>("/test"); }, kError);
1174
1175 EXPECT_DEATH({ loop->MakeRawFetcher(channel); }, kError);
1176 EXPECT_DEATH({ loop->MakeFetcher<TestMessage>("/test"); }, kError);
1177
1178 EXPECT_DEATH(
1179 { loop->MakeRawWatcher(channel, [](const Context &, const void *) {}); },
1180 kError);
1181 EXPECT_DEATH({ loop->MakeRawNoArgWatcher(channel, [](const Context &) {}); },
1182 kError);
1183
1184 EXPECT_DEATH({ loop->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1185 kError);
1186 EXPECT_DEATH({ loop->MakeWatcher("/test", [](const TestMessage &) {}); },
1187 kError);
1188}
1189
Brian Silverman454bc112020-03-05 14:21:25 -08001190// Verify that the send time on a message is roughly right when using a watcher.
Austin Schuh7267c532019-05-19 19:55:53 -07001191TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -07001192 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -07001193 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -08001194 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -07001195 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
1196
1197 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -07001198 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1199 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1200 builder.add_value(200);
1201 ASSERT_TRUE(msg.Send(builder.Finish()));
1202 });
1203
Austin Schuhad154822019-12-27 15:45:13 -08001204 bool triggered = false;
Brian Silverman454bc112020-03-05 14:21:25 -08001205 loop1->MakeWatcher("/test", [&](const TestMessage &msg) {
Austin Schuhad154822019-12-27 15:45:13 -08001206 // Confirm that the data pointer makes sense from a watcher, and all the
1207 // timestamps look right.
1208 EXPECT_GT(&msg, loop1->context().data);
1209 EXPECT_EQ(loop1->context().monotonic_remote_time,
1210 loop1->context().monotonic_event_time);
1211 EXPECT_EQ(loop1->context().realtime_remote_time,
1212 loop1->context().realtime_event_time);
1213
1214 const aos::monotonic_clock::time_point monotonic_now =
1215 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -08001216 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001217
1218 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1219 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1220 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1221 monotonic_now);
1222 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1223 realtime_now);
1224
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001225 EXPECT_LT(&msg, reinterpret_cast<const void *>(
1226 reinterpret_cast<const char *>(loop1->context().data) +
Austin Schuhad154822019-12-27 15:45:13 -08001227 loop1->context().size));
Brian Silverman4f4e0612020-08-12 19:54:41 -07001228 if (read_method() == ReadMethod::PIN) {
1229 EXPECT_GE(loop1->context().buffer_index, 0);
1230 EXPECT_LT(loop1->context().buffer_index,
1231 loop1->NumberBuffers(
1232 configuration::GetChannel(loop1->configuration(), "/test",
1233 "aos.TestMessage", "", nullptr)));
1234 } else {
1235 EXPECT_EQ(-1, loop1->context().buffer_index);
1236 }
Austin Schuhad154822019-12-27 15:45:13 -08001237 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -07001238 });
1239
1240 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1241
1242 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -07001243 Run();
Austin Schuh7267c532019-05-19 19:55:53 -07001244
Austin Schuhad154822019-12-27 15:45:13 -08001245 EXPECT_TRUE(triggered);
1246
Brian Silverman454bc112020-03-05 14:21:25 -08001247 ASSERT_TRUE(fetcher.Fetch());
1248
1249 monotonic_clock::duration monotonic_time_offset =
1250 fetcher.context().monotonic_event_time -
1251 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1252 realtime_clock::duration realtime_time_offset =
1253 fetcher.context().realtime_event_time -
1254 (loop1->realtime_now() - ::std::chrono::seconds(1));
1255
1256 EXPECT_EQ(fetcher.context().realtime_event_time,
1257 fetcher.context().realtime_remote_time);
1258 EXPECT_EQ(fetcher.context().monotonic_event_time,
1259 fetcher.context().monotonic_remote_time);
1260
1261 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1262 << ": Got "
1263 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1264 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1265 // Confirm that the data pointer makes sense.
1266 EXPECT_GT(fetcher.get(), fetcher.context().data);
1267 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001268 reinterpret_cast<const void *>(
1269 reinterpret_cast<const char *>(fetcher.context().data) +
Brian Silverman454bc112020-03-05 14:21:25 -08001270 fetcher.context().size));
1271 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1272 << ": Got "
1273 << fetcher.context().monotonic_event_time.time_since_epoch().count()
1274 << " expected " << loop1->monotonic_now().time_since_epoch().count();
1275
1276 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1277 << ": Got "
1278 << fetcher.context().realtime_event_time.time_since_epoch().count()
1279 << " expected " << loop1->realtime_now().time_since_epoch().count();
1280 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1281 << ": Got "
1282 << fetcher.context().realtime_event_time.time_since_epoch().count()
1283 << " expected " << loop1->realtime_now().time_since_epoch().count();
1284}
1285
1286// Verify that the send time on a message is roughly right when using a no-arg
1287// watcher. To get a message, we need to use a fetcher to actually access the
1288// message. This is also the main use case for no-arg fetchers.
1289TEST_P(AbstractEventLoopTest, MessageSendTimeNoArg) {
1290 auto loop1 = MakePrimary();
1291 auto loop2 = Make();
1292 auto sender = loop2->MakeSender<TestMessage>("/test");
1293 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1294
1295 auto test_timer = loop1->AddTimer([&sender]() {
1296 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1297 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1298 builder.add_value(200);
1299 ASSERT_TRUE(msg.Send(builder.Finish()));
1300 });
1301
1302 bool triggered = false;
1303 loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {
1304 // Confirm that we can indeed use a fetcher on this channel from this
1305 // context, and it results in a sane data pointer and timestamps.
1306 ASSERT_TRUE(fetcher.Fetch());
1307
1308 EXPECT_EQ(loop1->context().monotonic_remote_time,
1309 loop1->context().monotonic_event_time);
1310 EXPECT_EQ(loop1->context().realtime_remote_time,
1311 loop1->context().realtime_event_time);
1312
1313 const aos::monotonic_clock::time_point monotonic_now =
1314 loop1->monotonic_now();
1315 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
1316
1317 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
1318 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
1319 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
1320 monotonic_now);
1321 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
1322 realtime_now);
1323
1324 triggered = true;
1325 });
1326
1327 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
1328
1329 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
1330 Run();
1331
1332 ASSERT_TRUE(triggered);
Austin Schuh7267c532019-05-19 19:55:53 -07001333
Alex Perrycb7da4b2019-08-28 19:35:56 -07001334 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001335 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001336 (loop1->monotonic_now() - ::std::chrono::seconds(1));
1337 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -08001338 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -07001339 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -07001340
Austin Schuhad154822019-12-27 15:45:13 -08001341 EXPECT_EQ(fetcher.context().realtime_event_time,
1342 fetcher.context().realtime_remote_time);
1343 EXPECT_EQ(fetcher.context().monotonic_event_time,
1344 fetcher.context().monotonic_remote_time);
1345
Alex Perrycb7da4b2019-08-28 19:35:56 -07001346 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
1347 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001348 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -07001349 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001350 // Confirm that the data pointer makes sense.
1351 EXPECT_GT(fetcher.get(), fetcher.context().data);
1352 EXPECT_LT(fetcher.get(),
Brian Silvermaneaa41d62020-07-08 19:47:35 -07001353 reinterpret_cast<const void *>(
1354 reinterpret_cast<const char *>(fetcher.context().data) +
Alex Perrycb7da4b2019-08-28 19:35:56 -07001355 fetcher.context().size));
1356 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
1357 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001358 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -07001359 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -07001360
1361 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
1362 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001363 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001364 << " expected " << loop1->realtime_now().time_since_epoch().count();
1365 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
1366 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -08001367 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -07001368 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -07001369}
1370
Austin Schuh52d325c2019-06-23 18:59:06 -07001371// Tests that a couple phased loops run in a row result in the correct offset
1372// and period.
1373TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -08001374 // Force a slower rate so we are guarenteed to have reports for our phased
1375 // loop.
1376 FLAGS_timing_report_ms = 2000;
1377
Austin Schuh52d325c2019-06-23 18:59:06 -07001378 const chrono::milliseconds kOffset = chrono::milliseconds(400);
1379 const int kCount = 5;
1380
1381 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -08001382 auto loop2 = Make();
1383
1384 Fetcher<timing::Report> report_fetcher =
1385 loop2->MakeFetcher<timing::Report>("/aos");
1386 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001387
1388 // Collect up a couple of samples.
1389 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001390 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -07001391
1392 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -08001393 loop1
1394 ->AddPhasedLoop(
1395 [&times, &expected_times, &loop1, this](int count) {
1396 EXPECT_EQ(count, 1);
1397 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -08001398 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -08001399
Austin Schuhad154822019-12-27 15:45:13 -08001400 EXPECT_EQ(loop1->context().monotonic_remote_time,
1401 monotonic_clock::min_time);
1402 EXPECT_EQ(loop1->context().realtime_event_time,
1403 realtime_clock::min_time);
1404 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -08001405 realtime_clock::min_time);
1406 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
1407 EXPECT_EQ(loop1->context().size, 0u);
1408 EXPECT_EQ(loop1->context().data, nullptr);
Brian Silverman4f4e0612020-08-12 19:54:41 -07001409 EXPECT_EQ(loop1->context().buffer_index, -1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001410
1411 if (times.size() == kCount) {
1412 LOG(INFO) << "Exiting";
1413 this->Exit();
1414 }
1415 },
1416 chrono::seconds(1), kOffset)
1417 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -07001418
1419 // Add a delay to make sure that delay during startup doesn't result in a
1420 // "missed cycle".
1421 SleepFor(chrono::seconds(2));
1422
1423 Run();
1424
1425 // Confirm that we got both the right number of samples, and it's odd.
1426 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001427 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -07001428 EXPECT_EQ((times.size() % 2), 1);
1429
1430 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001431 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -07001432
1433 // Add up all the delays of all the times.
1434 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1435 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001436 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -07001437 }
1438
1439 // Average and add to the middle to find the average time.
1440 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001441 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -07001442
1443 // Compute the offset from the start of the second of the average time. This
1444 // should be pretty close to the offset.
1445 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001446 average_time.time_since_epoch() -
1447 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001448
1449 const chrono::milliseconds kEpsilon(100);
1450 EXPECT_LT(remainder, kOffset + kEpsilon);
1451 EXPECT_GT(remainder, kOffset - kEpsilon);
1452
1453 // Make sure that the average duration is close to 1 second.
1454 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1455 times.front())
1456 .count() /
1457 static_cast<double>(times.size() - 1),
1458 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001459
1460 // Confirm that the ideal wakeup times increment correctly.
1461 for (size_t i = 1; i < expected_times.size(); ++i) {
1462 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1463 }
1464
1465 for (size_t i = 0; i < expected_times.size(); ++i) {
1466 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1467 kOffset);
1468 }
1469
1470 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1471 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001472
1473 // And, since we are here, check that the timing report makes sense.
1474 // Start by looking for our event loop's timing.
1475 FlatbufferDetachedBuffer<timing::Report> report =
1476 FlatbufferDetachedBuffer<timing::Report>::Empty();
1477 while (report_fetcher.FetchNext()) {
1478 if (report_fetcher->name()->string_view() == "primary") {
1479 report = CopyFlatBuffer(report_fetcher.get());
1480 }
1481 }
1482
Ravago Jonescf453ab2020-05-06 21:14:53 -07001483 VLOG(1) << FlatbufferToJson(report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001484
1485 EXPECT_EQ(report.message().name()->string_view(), "primary");
1486
1487 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001488 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001489
1490 ASSERT_NE(report.message().timers(), nullptr);
1491 EXPECT_EQ(report.message().timers()->size(), 1);
1492
1493 // Make sure there is a single phased loop report with our report in it.
1494 ASSERT_NE(report.message().phased_loops(), nullptr);
1495 ASSERT_EQ(report.message().phased_loops()->size(), 1);
1496 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
1497 "Test loop");
1498 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
1499}
1500
1501// Tests that senders count correctly in the timing report.
1502TEST_P(AbstractEventLoopTest, SenderTimingReport) {
1503 FLAGS_timing_report_ms = 1000;
1504 auto loop1 = MakePrimary();
1505
1506 auto loop2 = Make("watcher_loop");
1507 loop2->MakeWatcher("/test", [](const TestMessage &) {});
1508
1509 auto loop3 = Make();
1510
1511 Fetcher<timing::Report> report_fetcher =
1512 loop3->MakeFetcher<timing::Report>("/aos");
1513 EXPECT_FALSE(report_fetcher.Fetch());
1514
1515 auto sender = loop1->MakeSender<TestMessage>("/test");
1516
1517 // Add a timer to actually quit.
1518 auto test_timer = loop1->AddTimer([&sender]() {
1519 for (int i = 0; i < 10; ++i) {
1520 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1521 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1522 builder.add_value(200 + i);
1523 ASSERT_TRUE(msg.Send(builder.Finish()));
1524 }
1525 });
1526
1527 // Quit after 1 timing report, mid way through the next cycle.
1528 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1529
1530 loop1->OnRun([&test_timer, &loop1]() {
1531 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1532 });
1533
1534 Run();
1535
1536 // And, since we are here, check that the timing report makes sense.
1537 // Start by looking for our event loop's timing.
1538 FlatbufferDetachedBuffer<timing::Report> primary_report =
1539 FlatbufferDetachedBuffer<timing::Report>::Empty();
1540 while (report_fetcher.FetchNext()) {
1541 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1542 if (report_fetcher->name()->string_view() == "primary") {
1543 primary_report = CopyFlatBuffer(report_fetcher.get());
1544 }
1545 }
1546
Ravago Jonescf453ab2020-05-06 21:14:53 -07001547 LOG(INFO) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001548
1549 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1550
1551 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001552 EXPECT_EQ(primary_report.message().senders()->size(), 3);
Austin Schuh39788ff2019-12-01 18:22:57 -08001553
1554 // Confirm that the sender looks sane.
1555 EXPECT_EQ(
1556 loop1->configuration()
1557 ->channels()
1558 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1559 ->name()
1560 ->string_view(),
1561 "/test");
1562 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1563
1564 // Confirm that the timing primary_report sender looks sane.
1565 EXPECT_EQ(
1566 loop1->configuration()
1567 ->channels()
1568 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1569 ->name()
1570 ->string_view(),
1571 "/aos");
1572 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1573
1574 ASSERT_NE(primary_report.message().timers(), nullptr);
1575 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1576
1577 // Make sure there are no phased loops or watchers.
1578 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1579 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1580}
1581
1582// Tests that senders count correctly in the timing report.
1583TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1584 FLAGS_timing_report_ms = 1000;
1585 auto loop1 = MakePrimary();
1586 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1587
1588 auto loop2 = Make("sender_loop");
1589
1590 auto loop3 = Make();
1591
1592 Fetcher<timing::Report> report_fetcher =
1593 loop3->MakeFetcher<timing::Report>("/aos");
1594 EXPECT_FALSE(report_fetcher.Fetch());
1595
1596 auto sender = loop2->MakeSender<TestMessage>("/test");
1597
1598 // Add a timer to actually quit.
1599 auto test_timer = loop1->AddTimer([&sender]() {
1600 for (int i = 0; i < 10; ++i) {
1601 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1602 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1603 builder.add_value(200 + i);
1604 ASSERT_TRUE(msg.Send(builder.Finish()));
1605 }
1606 });
1607
1608 // Quit after 1 timing report, mid way through the next cycle.
1609 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1610
1611 loop1->OnRun([&test_timer, &loop1]() {
1612 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1613 });
1614
1615 Run();
1616
1617 // And, since we are here, check that the timing report makes sense.
1618 // Start by looking for our event loop's timing.
1619 FlatbufferDetachedBuffer<timing::Report> primary_report =
1620 FlatbufferDetachedBuffer<timing::Report>::Empty();
1621 while (report_fetcher.FetchNext()) {
1622 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1623 if (report_fetcher->name()->string_view() == "primary") {
1624 primary_report = CopyFlatBuffer(report_fetcher.get());
1625 }
1626 }
1627
1628 // Check the watcher report.
Ravago Jonescf453ab2020-05-06 21:14:53 -07001629 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001630
1631 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1632
1633 // Just the timing report timer.
1634 ASSERT_NE(primary_report.message().timers(), nullptr);
1635 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1636
1637 // No phased loops
1638 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1639
1640 ASSERT_NE(primary_report.message().watchers(), nullptr);
1641 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1642 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1643}
1644
1645// Tests that fetchers count correctly in the timing report.
1646TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1647 FLAGS_timing_report_ms = 1000;
1648 auto loop1 = MakePrimary();
1649 auto loop2 = Make("sender_loop");
1650
1651 auto loop3 = Make();
1652
1653 Fetcher<timing::Report> report_fetcher =
1654 loop3->MakeFetcher<timing::Report>("/aos");
1655 EXPECT_FALSE(report_fetcher.Fetch());
1656
1657 auto sender = loop2->MakeSender<TestMessage>("/test");
1658 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1659 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1660 fetcher1.Fetch();
1661 fetcher2.Fetch();
1662
1663 // Add a timer to actually quit.
1664 auto test_timer = loop1->AddTimer([&sender]() {
1665 for (int i = 0; i < 10; ++i) {
1666 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1667 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1668 builder.add_value(200 + i);
1669 ASSERT_TRUE(msg.Send(builder.Finish()));
1670 }
1671 });
1672
1673 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1674 fetcher1.Fetch();
1675 while (fetcher2.FetchNext()) {
1676 }
1677 });
1678
1679 // Quit after 1 timing report, mid way through the next cycle.
1680 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1681
1682 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1683 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1684 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1685 });
1686
1687 Run();
1688
1689 // And, since we are here, check that the timing report makes sense.
1690 // Start by looking for our event loop's timing.
1691 FlatbufferDetachedBuffer<timing::Report> primary_report =
1692 FlatbufferDetachedBuffer<timing::Report>::Empty();
1693 while (report_fetcher.FetchNext()) {
1694 if (report_fetcher->name()->string_view() == "primary") {
1695 primary_report = CopyFlatBuffer(report_fetcher.get());
1696 }
1697 }
1698
Ravago Jonescf453ab2020-05-06 21:14:53 -07001699 VLOG(1) << FlatbufferToJson(primary_report, {.multi_line = true});
Austin Schuh39788ff2019-12-01 18:22:57 -08001700
1701 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1702
1703 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001704 EXPECT_EQ(primary_report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001705
1706 ASSERT_NE(primary_report.message().timers(), nullptr);
1707 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1708
1709 // Make sure there are no phased loops or watchers.
1710 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1711 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1712
1713 // Now look at the fetchrs.
1714 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1715 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1716
1717 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1718 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1719 0.1);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001720 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(), 0.1);
1721 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(), 0.1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001722 EXPECT_EQ(primary_report.message()
1723 .fetchers()
1724 ->Get(0)
1725 ->latency()
1726 ->standard_deviation(),
1727 0.0);
1728
1729 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001730}
1731
Austin Schuh67420a42019-12-21 21:55:04 -08001732// Tests that a raw watcher and raw fetcher can receive messages from a raw
1733// sender without messing up offsets.
1734TEST_P(AbstractEventLoopTest, RawBasic) {
1735 auto loop1 = Make();
1736 auto loop2 = MakePrimary();
1737 auto loop3 = Make();
1738
1739 const std::string kData("971 is the best");
1740
1741 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001742 loop1->MakeRawSender(configuration::GetChannel(
1743 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001744
1745 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001746 loop3->MakeRawFetcher(configuration::GetChannel(
1747 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001748
1749 loop2->OnRun(
1750 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1751
1752 bool happened = false;
1753 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001754 configuration::GetChannel(loop2->configuration(), "/test",
1755 "aos.TestMessage", "", nullptr),
Austin Schuh67420a42019-12-21 21:55:04 -08001756 [this, &kData, &fetcher, &happened](const Context &context,
1757 const void *message) {
1758 happened = true;
1759 EXPECT_EQ(std::string_view(kData),
1760 std::string_view(reinterpret_cast<const char *>(message),
1761 context.size));
1762 EXPECT_EQ(std::string_view(kData),
1763 std::string_view(reinterpret_cast<const char *>(context.data),
1764 context.size));
1765
1766 ASSERT_TRUE(fetcher->Fetch());
1767
1768 EXPECT_EQ(std::string_view(kData),
1769 std::string_view(
1770 reinterpret_cast<const char *>(fetcher->context().data),
1771 fetcher->context().size));
1772
1773 this->Exit();
1774 });
1775
1776 EXPECT_FALSE(happened);
1777 Run();
1778 EXPECT_TRUE(happened);
1779}
1780
Austin Schuhad154822019-12-27 15:45:13 -08001781// Tests that a raw watcher and raw fetcher can receive messages from a raw
1782// sender with remote times filled out.
1783TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1784 auto loop1 = Make();
1785 auto loop2 = MakePrimary();
1786 auto loop3 = Make();
1787
1788 const std::string kData("971 is the best");
1789
1790 const aos::monotonic_clock::time_point monotonic_remote_time =
1791 aos::monotonic_clock::time_point(chrono::seconds(1501));
1792 const aos::realtime_clock::time_point realtime_remote_time =
1793 aos::realtime_clock::time_point(chrono::seconds(3132));
1794
1795 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001796 loop1->MakeRawSender(configuration::GetChannel(
1797 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001798
1799 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001800 loop3->MakeRawFetcher(configuration::GetChannel(
1801 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001802
1803 loop2->OnRun([&]() {
1804 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1805 realtime_remote_time));
1806 });
1807
1808 bool happened = false;
1809 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001810 configuration::GetChannel(loop2->configuration(), "/test",
1811 "aos.TestMessage", "", nullptr),
Austin Schuhad154822019-12-27 15:45:13 -08001812 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1813 const Context &context, const void * /*message*/) {
1814 happened = true;
1815 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1816 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1817
1818 ASSERT_TRUE(fetcher->Fetch());
1819 EXPECT_EQ(monotonic_remote_time,
1820 fetcher->context().monotonic_remote_time);
1821 EXPECT_EQ(realtime_remote_time,
1822 fetcher->context().realtime_remote_time);
1823
1824 this->Exit();
1825 });
1826
1827 EXPECT_FALSE(happened);
1828 Run();
1829 EXPECT_TRUE(happened);
1830}
1831
1832// Tests that a raw sender fills out sent data.
1833TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1834 auto loop1 = MakePrimary();
1835
1836 const std::string kData("971 is the best");
1837
1838 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001839 loop1->MakeRawSender(configuration::GetChannel(
1840 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001841
Tyler Chatow67ddb032020-01-12 14:30:04 -08001842 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
1843 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001844
1845 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1846
1847 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1848 EXPECT_LE(sender->monotonic_sent_time(),
1849 monotonic_now + chrono::milliseconds(100));
1850 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1851 EXPECT_LE(sender->realtime_sent_time(),
1852 realtime_now + chrono::milliseconds(100));
1853 EXPECT_EQ(sender->sent_queue_index(), 0u);
1854
1855 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1856
1857 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1858 EXPECT_LE(sender->monotonic_sent_time(),
1859 monotonic_now + chrono::milliseconds(100));
1860 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1861 EXPECT_LE(sender->realtime_sent_time(),
1862 realtime_now + chrono::milliseconds(100));
1863 EXPECT_EQ(sender->sent_queue_index(), 1u);
1864}
1865
Austin Schuh217a9782019-12-21 23:02:50 -08001866// Tests that not setting up nodes results in no node.
1867TEST_P(AbstractEventLoopTest, NoNode) {
1868 auto loop1 = Make();
1869 auto loop2 = MakePrimary();
1870
1871 EXPECT_EQ(loop1->node(), nullptr);
1872 EXPECT_EQ(loop2->node(), nullptr);
1873}
1874
1875// Tests that setting up nodes results in node being set.
1876TEST_P(AbstractEventLoopTest, Node) {
1877 EnableNodes("me");
1878
1879 auto loop1 = Make();
1880 auto loop2 = MakePrimary();
1881
1882 EXPECT_NE(loop1->node(), nullptr);
1883 EXPECT_NE(loop2->node(), nullptr);
1884}
1885
1886// Tests that watchers work with a node setup.
1887TEST_P(AbstractEventLoopTest, NodeWatcher) {
1888 EnableNodes("me");
1889
1890 auto loop1 = Make();
1891 auto loop2 = Make();
1892 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08001893 loop2->MakeRawWatcher(
1894 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1895 nullptr),
1896 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001897}
1898
Brian Silverman454bc112020-03-05 14:21:25 -08001899// Tests that no-arg watchers work with a node setup.
1900TEST_P(AbstractEventLoopTest, NodeNoArgWatcher) {
1901 EnableNodes("me");
1902
1903 auto loop1 = Make();
1904 auto loop2 = Make();
1905 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1906 loop2->MakeRawNoArgWatcher(
1907 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1908 nullptr),
1909 [](const Context &) {});
1910}
1911
Austin Schuh217a9782019-12-21 23:02:50 -08001912// Tests that fetcher work with a node setup.
1913TEST_P(AbstractEventLoopTest, NodeFetcher) {
1914 EnableNodes("me");
1915 auto loop1 = Make();
1916
1917 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08001918 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1919 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001920}
1921
1922// Tests that sender work with a node setup.
1923TEST_P(AbstractEventLoopTest, NodeSender) {
1924 EnableNodes("me");
1925 auto loop1 = Make();
1926
1927 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1928}
1929
1930// Tests that watchers fail when created on the wrong node.
1931TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
1932 EnableNodes("them");
1933
1934 auto loop1 = Make();
1935 auto loop2 = Make();
1936 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
1937 "node");
1938 EXPECT_DEATH(
1939 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001940 loop2->MakeRawWatcher(
1941 configuration::GetChannel(configuration(), "/test",
1942 "aos.TestMessage", "", nullptr),
1943 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001944 },
1945 "node");
Brian Silverman454bc112020-03-05 14:21:25 -08001946 EXPECT_DEATH({ loop1->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1947 "node");
1948 EXPECT_DEATH(
1949 {
1950 loop2->MakeRawNoArgWatcher(
1951 configuration::GetChannel(configuration(), "/test",
1952 "aos.TestMessage", "", nullptr),
1953 [](const Context &) {});
1954 },
1955 "node");
Austin Schuh217a9782019-12-21 23:02:50 -08001956}
1957
1958// Tests that fetchers fail when created on the wrong node.
1959TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
1960 EnableNodes("them");
1961 auto loop1 = Make();
1962
1963 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
1964 "node");
1965 EXPECT_DEATH(
1966 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001967 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1968 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001969 },
1970 "node");
1971}
1972
1973// Tests that senders fail when created on the wrong node.
1974TEST_P(AbstractEventLoopDeathTest, NodeSender) {
1975 EnableNodes("them");
1976 auto loop1 = Make();
1977
1978 EXPECT_DEATH(
1979 {
1980 aos::Sender<TestMessage> sender =
1981 loop1->MakeSender<TestMessage>("/test");
1982 },
1983 "node");
1984
1985 // Note: Creating raw senders is always supported. Right now, this lets us
1986 // use them to create message_gateway.
1987}
1988
Brian Silverman341b57e2020-06-23 16:23:18 -07001989// Tests creating multiple Builders from a single Sender at the same time.
1990TEST_P(AbstractEventLoopDeathTest, MultipleBuilders) {
1991 auto loop1 = Make();
1992 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1993
1994 { auto builder = sender.MakeBuilder(); }
1995 {
1996 auto builder = sender.MakeBuilder();
1997 builder.MakeBuilder<TestMessage>().Finish();
1998 }
1999 {
2000 // Creating this after the first one was destroyed should be fine.
2001 auto builder = sender.MakeBuilder();
2002 builder.MakeBuilder<TestMessage>().Finish();
2003 // But not a second one.
2004 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2005 "May not overwrite in-use allocator");
2006 }
2007
2008 FlatbufferDetachedBuffer<TestMessage> detached =
2009 flatbuffers::DetachedBuffer();
2010 {
2011 auto builder = sender.MakeBuilder();
2012 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2013 }
2014 {
2015 // This is the second one, after the detached one, so it should fail.
2016 EXPECT_DEATH(sender.MakeBuilder().MakeBuilder<TestMessage>().Finish(),
2017 "May not overwrite in-use allocator");
2018 }
2019
2020 // Clear the detached one, and then we should be able to create another.
2021 detached = flatbuffers::DetachedBuffer();
2022 {
2023 auto builder = sender.MakeBuilder();
2024 builder.MakeBuilder<TestMessage>().Finish();
2025 }
2026
2027 // And then detach another one.
2028 {
2029 auto builder = sender.MakeBuilder();
2030 detached = builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2031 }
2032}
2033
2034// Tests sending a buffer detached from a different builder.
2035TEST_P(AbstractEventLoopDeathTest, WrongDetachedBuffer) {
2036 auto loop1 = Make();
2037 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
2038 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
2039
2040 auto builder = sender1.MakeBuilder();
2041 FlatbufferDetachedBuffer<TestMessage> detached =
2042 builder.Detach(builder.MakeBuilder<TestMessage>().Finish());
2043 EXPECT_DEATH(sender2.SendDetached(std::move(detached)),
2044 "May only send the buffer detached from this Sender");
2045}
2046
Parker Schuhe4a70d62017-12-27 20:10:20 -08002047} // namespace testing
2048} // namespace aos