blob: b4cfeb283c4d11a3c78e64ed1fc69dbe09b7c8ab [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>
4
Alex Perrycb7da4b2019-08-28 19:35:56 -07005#include "aos/events/test_message_generated.h"
Austin Schuh54cf95f2019-11-29 13:14:18 -08006#include "aos/flatbuffer_merge.h"
7#include "glog/logging.h"
Tyler Chatow67ddb032020-01-12 14:30:04 -08008#include "gmock/gmock.h"
9#include "gtest/gtest.h"
Austin Schuh9fe68f72019-08-10 19:32:03 -070010
Parker Schuhe4a70d62017-12-27 20:10:20 -080011namespace aos {
12namespace testing {
Austin Schuh52d325c2019-06-23 18:59:06 -070013namespace {
14namespace chrono = ::std::chrono;
15} // namespace
Parker Schuhe4a70d62017-12-27 20:10:20 -080016
Austin Schuh6b6dfa52019-06-12 20:16:20 -070017// Tests that watcher can receive messages from a sender.
Parker Schuhe4a70d62017-12-27 20:10:20 -080018// Also tests that OnRun() works.
19TEST_P(AbstractEventLoopTest, Basic) {
20 auto loop1 = Make();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070021 auto loop2 = MakePrimary();
22
Alex Perrycb7da4b2019-08-28 19:35:56 -070023 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
Austin Schuh6b6dfa52019-06-12 20:16:20 -070024
25 bool happened = false;
26
27 loop2->OnRun([&]() {
28 happened = true;
29
Alex Perrycb7da4b2019-08-28 19:35:56 -070030 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
31 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
32 builder.add_value(200);
33 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -070034 });
35
36 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070037 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -070038 this->Exit();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070039 });
40
41 EXPECT_FALSE(happened);
42 Run();
43 EXPECT_TRUE(happened);
44}
45
Brian Silverman454bc112020-03-05 14:21:25 -080046// Tests that no-arg watcher can receive messages from a sender.
47// Also tests that OnRun() works.
48TEST_P(AbstractEventLoopTest, BasicNoArg) {
49 auto loop1 = Make();
50 auto loop2 = MakePrimary();
51
52 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
53
54 bool happened = false;
55
56 loop2->OnRun([&]() {
57 happened = true;
58
59 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
60 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
61 builder.add_value(200);
62 ASSERT_TRUE(msg.Send(builder.Finish()));
63 });
64
65 aos::Fetcher<TestMessage> fetcher = loop2->MakeFetcher<TestMessage>("/test");
66 loop2->MakeNoArgWatcher<TestMessage>("/test", [&]() {
67 ASSERT_TRUE(fetcher.Fetch());
68 EXPECT_EQ(fetcher->value(), 200);
69 this->Exit();
70 });
71
72 EXPECT_FALSE(happened);
73 Run();
74 EXPECT_TRUE(happened);
75}
76
77// Tests that a watcher can be created with an std::function.
78TEST_P(AbstractEventLoopTest, BasicFunction) {
79 auto loop1 = Make();
80 auto loop2 = MakePrimary();
81
82 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
83
84 bool happened = false;
85
86 loop2->OnRun([&]() {
87 happened = true;
88
89 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
90 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
91 builder.add_value(200);
92 ASSERT_TRUE(msg.Send(builder.Finish()));
93 });
94
95 loop2->MakeWatcher("/test", std::function<void(const TestMessage &)>(
96 [&](const TestMessage &message) {
97 EXPECT_EQ(message.value(), 200);
98 this->Exit();
99 }));
100
101 EXPECT_FALSE(happened);
102 Run();
103 EXPECT_TRUE(happened);
104}
105
Brian Silverman0fc69932020-01-24 21:54:02 -0800106// Tests that watcher can receive messages from two senders.
107// Also tests that OnRun() works.
108TEST_P(AbstractEventLoopTest, BasicTwoSenders) {
109 auto loop1 = Make();
110 auto loop2 = MakePrimary();
111
112 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
113 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
114
115 bool happened = false;
116
117 loop2->OnRun([&]() {
118 happened = true;
119
120 {
121 aos::Sender<TestMessage>::Builder msg = sender1.MakeBuilder();
122 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
123 builder.add_value(200);
124 ASSERT_TRUE(msg.Send(builder.Finish()));
125 }
126 {
127 aos::Sender<TestMessage>::Builder msg = sender2.MakeBuilder();
128 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
129 builder.add_value(200);
130 ASSERT_TRUE(msg.Send(builder.Finish()));
131 }
132 });
133
134 int messages_received = 0;
135 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
136 EXPECT_EQ(message.value(), 200);
137 this->Exit();
138 ++messages_received;
139 });
140
141 EXPECT_FALSE(happened);
142 Run();
143 EXPECT_TRUE(happened);
144 EXPECT_EQ(messages_received, 2);
145}
146
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700147// Tests that a fetcher can fetch from a sender.
148// Also tests that OnRun() works.
149TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
150 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800151 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700152 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800153
154 auto sender = loop1->MakeSender<TestMessage>("/test");
155
156 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
157
Austin Schuhbbce72d2019-05-26 15:11:46 -0700158 EXPECT_FALSE(fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -0800159 EXPECT_EQ(fetcher.get(), nullptr);
160
Austin Schuhad154822019-12-27 15:45:13 -0800161 EXPECT_EQ(fetcher.context().monotonic_event_time, monotonic_clock::min_time);
162 EXPECT_EQ(fetcher.context().monotonic_remote_time, monotonic_clock::min_time);
163 EXPECT_EQ(fetcher.context().realtime_event_time, realtime_clock::min_time);
164 EXPECT_EQ(fetcher.context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800165 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
166 EXPECT_EQ(fetcher.context().size, 0u);
167 EXPECT_EQ(fetcher.context().data, nullptr);
Austin Schuhbbce72d2019-05-26 15:11:46 -0700168
Alex Perrycb7da4b2019-08-28 19:35:56 -0700169 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
170 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
171 builder.add_value(200);
172 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700173
174 EXPECT_TRUE(fetcher.Fetch());
175 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700176 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -0800177
178 const chrono::milliseconds kEpsilon(100);
179
Austin Schuhad154822019-12-27 15:45:13 -0800180 const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
181 const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
182 EXPECT_EQ(fetcher.context().monotonic_event_time,
183 fetcher.context().monotonic_remote_time);
184 EXPECT_EQ(fetcher.context().realtime_event_time,
185 fetcher.context().realtime_remote_time);
186
187 EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
188 EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
189 EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
190 EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800191 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
192 EXPECT_EQ(fetcher.context().size, 20u);
193 EXPECT_NE(fetcher.context().data, nullptr);
Parker Schuhe4a70d62017-12-27 20:10:20 -0800194}
195
Austin Schuh3578a2e2019-05-25 18:17:59 -0700196// Tests that watcher will receive all messages sent if they are sent after
197// initialization and before running.
198TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
199 auto loop1 = Make();
200 auto loop2 = MakePrimary();
201
202 auto sender = loop1->MakeSender<TestMessage>("/test");
203
204 ::std::vector<int> values;
205
206 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700207 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700208 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700209 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700210 }
211 });
212
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700213 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -0700214 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700215 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
216 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
217 builder.add_value(199);
218 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700219 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700220
221 loop2->OnRun([&]() {
222 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700223 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
224 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
225 builder.add_value(200);
226 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700227 }
228 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700229 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
230 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
231 builder.add_value(201);
232 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700233 }
234 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700235
236 Run();
237
238 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
239}
240
241// Tests that watcher will not receive messages sent before the watcher is
242// created.
243TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
244 auto loop1 = Make();
245 auto loop2 = MakePrimary();
246
247 auto sender = loop1->MakeSender<TestMessage>("/test");
248
249 ::std::vector<int> values;
250
251 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700252 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
253 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
254 builder.add_value(200);
255 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700256 }
257 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700258 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
259 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
260 builder.add_value(201);
261 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700262 }
263
264 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700265 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700266 });
267
268 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700269 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700270 loop2->OnRun([&test_timer, &loop2]() {
271 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
272 });
273
274 Run();
275 EXPECT_EQ(0, values.size());
276}
277
Austin Schuhbbce72d2019-05-26 15:11:46 -0700278// Tests that FetchNext gets all the messages sent after it is constructed.
279TEST_P(AbstractEventLoopTest, FetchNext) {
280 auto loop1 = Make();
281 auto loop2 = MakePrimary();
282
283 auto sender = loop1->MakeSender<TestMessage>("/test");
284 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
285
286 ::std::vector<int> values;
287
288 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700289 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
290 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
291 builder.add_value(200);
292 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700293 }
294 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700295 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
296 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
297 builder.add_value(201);
298 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700299 }
300
301 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700302 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700303 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700304 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700305 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700306 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700307 });
308
309 loop2->OnRun([&test_timer, &loop2]() {
310 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
311 });
312
313 Run();
314 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
315}
316
317// Tests that FetchNext gets no messages sent before it is constructed.
318TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
319 auto loop1 = Make();
320 auto loop2 = MakePrimary();
321
322 auto sender = loop1->MakeSender<TestMessage>("/test");
323
324 ::std::vector<int> values;
325
326 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700327 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
328 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
329 builder.add_value(200);
330 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700331 }
332 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700333 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
334 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
335 builder.add_value(201);
336 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700337 }
338
339 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
340
341 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700342 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700343 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700344 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700345 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700346 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700347 });
348
349 loop2->OnRun([&test_timer, &loop2]() {
350 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
351 });
352
353 Run();
354 EXPECT_THAT(0, values.size());
355}
356
357// Tests that Fetch returns the last message created before the loop was
358// started.
359TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
360 auto loop1 = Make();
361 auto loop2 = MakePrimary();
362
363 auto sender = loop1->MakeSender<TestMessage>("/test");
364
365 ::std::vector<int> values;
366
367 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700368 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
369 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
370 builder.add_value(200);
371 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700372 }
373 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700374 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
375 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
376 builder.add_value(201);
377 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700378 }
379
380 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
381
382 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700383 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700384 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700385 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700386 }
387 // Do it again to make sure we don't double fetch.
388 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700389 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700390 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700391 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700392 });
393
394 loop2->OnRun([&test_timer, &loop2]() {
395 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
396 });
397
398 Run();
399 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
400}
401
402// Tests that Fetch and FetchNext interleave as expected.
403TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
404 auto loop1 = Make();
405 auto loop2 = MakePrimary();
406
407 auto sender = loop1->MakeSender<TestMessage>("/test");
408
409 ::std::vector<int> values;
410
411 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700412 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
413 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
414 builder.add_value(200);
415 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700416 }
417 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700418 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
419 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
420 builder.add_value(201);
421 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700422 }
423
424 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
425
426 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700427 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700428 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700429 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700430 }
431
432 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700433 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
434 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
435 builder.add_value(202);
436 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700437 }
438 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700439 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
440 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
441 builder.add_value(203);
442 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700443 }
444 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700445 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
446 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
447 builder.add_value(204);
448 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700449 }
450
451 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700452 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700453 }
454
455 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700456 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700457 }
458
Austin Schuh9fe68f72019-08-10 19:32:03 -0700459 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700460 });
461
462 loop2->OnRun([&test_timer, &loop2]() {
463 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
464 });
465
466 Run();
467 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
468}
469
Austin Schuh3115a202019-05-27 21:02:14 -0700470// Tests that FetchNext behaves correctly when we get two messages in the queue
471// but don't consume the first until after the second has been sent.
472TEST_P(AbstractEventLoopTest, FetchNextTest) {
Austin Schuh3115a202019-05-27 21:02:14 -0700473 auto send_loop = Make();
474 auto fetch_loop = Make();
475 auto sender = send_loop->MakeSender<TestMessage>("/test");
476 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
477
478 {
Tyler Chatow67ddb032020-01-12 14:30:04 -0800479 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
480 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
481 builder.add_value(100);
482 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700483 }
484
485 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700486 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
487 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
488 builder.add_value(200);
489 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700490 }
491
492 ASSERT_TRUE(fetcher.FetchNext());
493 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700494 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700495
496 ASSERT_TRUE(fetcher.FetchNext());
497 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700498 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700499
500 // When we run off the end of the queue, expect to still have the old message:
501 ASSERT_FALSE(fetcher.FetchNext());
502 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700503 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700504}
505
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800506// Verify that making a fetcher and watcher for "/test" succeeds.
507TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800508 auto loop = Make();
509 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800510 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800511}
512
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800513// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800514TEST_P(AbstractEventLoopTest, TwoFetcher) {
515 auto loop = Make();
516 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800517 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800518}
519
Alex Perrycb7da4b2019-08-28 19:35:56 -0700520// Verify that registering a watcher for an invalid channel name dies.
521TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
522 auto loop = Make();
523 EXPECT_DEATH(
524 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
525 "/test/invalid");
Brian Silverman454bc112020-03-05 14:21:25 -0800526 EXPECT_DEATH(
527 { loop->MakeNoArgWatcher<TestMessage>("/test/invalid", [&]() {}); },
528 "/test/invalid");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700529}
530
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800531// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700532TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800533 auto loop = Make();
534 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800535 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
536 "/test");
Brian Silverman454bc112020-03-05 14:21:25 -0800537 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
538}
539
540// Verify that registering a no-arg watcher twice for "/test" fails.
541TEST_P(AbstractEventLoopDeathTest, TwoNoArgWatcher) {
542 auto loop = Make();
543 loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {});
544 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
545 "/test");
546 EXPECT_DEATH(loop->MakeNoArgWatcher<TestMessage>("/test", [&]() {}), "/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800547}
548
Austin Schuh3115a202019-05-27 21:02:14 -0700549// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700550TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700551 auto loop = MakePrimary();
552 // Confirm that runtime priority calls work when not realtime.
553 loop->SetRuntimeRealtimePriority(5);
554
555 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
556
557 EXPECT_DEATH(Run(), "realtime");
558}
559
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800560// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700561TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800562 auto loop = Make();
563 auto sender = loop->MakeSender<TestMessage>("/test");
564 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
565 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800566}
567
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700568// Verify that we can't create a sender inside OnRun.
569TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
570 auto loop1 = MakePrimary();
571
572 loop1->OnRun(
573 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
574
575 EXPECT_DEATH(Run(), "running");
576}
577
578// Verify that we can't create a watcher inside OnRun.
579TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
580 auto loop1 = MakePrimary();
581
582 loop1->OnRun(
583 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
584
585 EXPECT_DEATH(Run(), "running");
586}
587
Brian Silverman454bc112020-03-05 14:21:25 -0800588// Verify that we can't create a no-arg watcher inside OnRun.
589TEST_P(AbstractEventLoopDeathTest, NoArgWatcherInOnRun) {
590 auto loop1 = MakePrimary();
591
592 loop1->OnRun(
593 [&]() { loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {}); });
594
595 EXPECT_DEATH(Run(), "running");
596}
597
Parker Schuhe4a70d62017-12-27 20:10:20 -0800598// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800599TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
600 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700601 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800602
Austin Schuh3578a2e2019-05-25 18:17:59 -0700603 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
604 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700605 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700606 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700607 });
608
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800609 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700610
611 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700612 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
613 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
614 builder.add_value(200);
615 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700616 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800617
Austin Schuh44019f92019-05-19 19:58:27 -0700618 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800619}
620
Neil Balch229001a2018-01-07 18:22:52 -0800621// Verify that timer intervals and duration function properly.
622TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800623 // Force a slower rate so we are guarenteed to have reports for our timer.
624 FLAGS_timing_report_ms = 2000;
625
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800626 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800627
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800628 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800629 auto loop2 = Make();
630
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800631 ::std::vector<::aos::monotonic_clock::time_point> times;
632 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
633
Austin Schuh39788ff2019-12-01 18:22:57 -0800634 Fetcher<timing::Report> report_fetcher =
635 loop2->MakeFetcher<timing::Report>("/aos");
636 EXPECT_FALSE(report_fetcher.Fetch());
637
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800638 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
639 times.push_back(loop->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800640 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
641 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
642 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800643 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
644 EXPECT_EQ(loop->context().size, 0u);
645 EXPECT_EQ(loop->context().data, nullptr);
646
Austin Schuhad154822019-12-27 15:45:13 -0800647 expected_times.push_back(loop->context().monotonic_event_time);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800648 if (times.size() == kCount) {
649 this->Exit();
650 }
Neil Balch229001a2018-01-07 18:22:52 -0800651 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800652 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800653
Austin Schuh39788ff2019-12-01 18:22:57 -0800654 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700655 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800656 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
657
Austin Schuh44019f92019-05-19 19:58:27 -0700658 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800659
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800660 // Confirm that we got both the right number of samples, and it's odd.
661 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
662 EXPECT_EQ(times.size(), expected_times.size());
663 EXPECT_EQ((times.size() % 2), 1);
664
665 // Grab the middle sample.
666 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
667
668 // Add up all the delays of all the times.
669 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
670 for (const ::aos::monotonic_clock::time_point time : times) {
671 sum += time - average_time;
672 }
673
674 // Average and add to the middle to find the average time.
675 sum /= times.size();
676 average_time += sum;
677
678 // Compute the offset from the average and the expected average. It
679 // should be pretty close to 0.
680 const ::aos::monotonic_clock::duration remainder =
681 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
682
683 const chrono::milliseconds kEpsilon(100);
684 EXPECT_LT(remainder, +kEpsilon);
685 EXPECT_GT(remainder, -kEpsilon);
686
687 // Make sure that the average duration is close to 1 second.
688 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
689 times.front())
690 .count() /
691 static_cast<double>(times.size() - 1),
692 1.0, 0.1);
693
694 // Confirm that the ideal wakeup times increment correctly.
695 for (size_t i = 1; i < expected_times.size(); ++i) {
696 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
697 }
698
699 for (size_t i = 0; i < expected_times.size(); ++i) {
700 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
701 chrono::seconds(0));
702 }
703
704 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
705 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800706
707 // And, since we are here, check that the timing report makes sense.
708 // Start by looking for our event loop's timing.
709 FlatbufferDetachedBuffer<timing::Report> report =
710 FlatbufferDetachedBuffer<timing::Report>::Empty();
711 while (report_fetcher.FetchNext()) {
712 if (report_fetcher->name()->string_view() == "primary") {
713 report = CopyFlatBuffer(report_fetcher.get());
714 }
715 }
716
717 // Confirm that we have the right number of reports, and the contents are
718 // sane.
719 VLOG(1) << FlatbufferToJson(report, true);
720
721 EXPECT_EQ(report.message().name()->string_view(), "primary");
722
723 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -0800724 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -0800725
726 ASSERT_NE(report.message().timers(), nullptr);
727 EXPECT_EQ(report.message().timers()->size(), 2);
728
729 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
730 "Test loop");
731 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
732
733 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
734 "timing_reports");
735 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
736
737 // Make sure there is a single phased loop report with our report in it.
738 ASSERT_EQ(report.message().phased_loops(), nullptr);
Neil Balch229001a2018-01-07 18:22:52 -0800739}
740
741// Verify that we can change a timer's parameters during execution.
742TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700743 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800744 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
745
746 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
747 iteration_list.push_back(loop->monotonic_now());
748 });
749
750 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
751 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
752 });
753
Neil Balch229001a2018-01-07 18:22:52 -0800754 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
755 modifier_timer->Setup(loop->monotonic_now() +
756 ::std::chrono::milliseconds(45));
757 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700758 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800759
760 EXPECT_EQ(iteration_list.size(), 7);
761}
762
763// Verify that we can disable a timer during execution.
764TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700765 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800766 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
767
768 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
769 iteration_list.push_back(loop->monotonic_now());
770 });
771
Tyler Chatow67ddb032020-01-12 14:30:04 -0800772 auto ender_timer = loop->AddTimer([&test_timer]() { test_timer->Disable(); });
Neil Balch229001a2018-01-07 18:22:52 -0800773
774 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
Tyler Chatow67ddb032020-01-12 14:30:04 -0800775 ender_timer->Setup(loop->monotonic_now() + ::std::chrono::milliseconds(45));
Neil Balch229001a2018-01-07 18:22:52 -0800776 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700777 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800778
779 EXPECT_EQ(iteration_list.size(), 3);
780}
Austin Schuh7267c532019-05-19 19:55:53 -0700781
Austin Schuh54cf95f2019-11-29 13:14:18 -0800782// Verifies that the event loop implementations detect when Channel is not a
783// pointer into confguration()
784TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
785 auto loop = MakePrimary();
786
Tyler Chatow67ddb032020-01-12 14:30:04 -0800787 const Channel *channel = configuration::GetChannel(
788 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
Austin Schuh54cf95f2019-11-29 13:14:18 -0800789
790 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
791
792 EXPECT_DEATH(
793 { loop->MakeRawSender(&channel_copy.message()); },
794 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
795
796 EXPECT_DEATH(
797 { loop->MakeRawFetcher(&channel_copy.message()); },
798 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
799
800 EXPECT_DEATH(
801 {
802 loop->MakeRawWatcher(&channel_copy.message(),
803 [](const Context, const void *) {});
804 },
805 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
806}
807
Brian Silverman454bc112020-03-05 14:21:25 -0800808// Verify that the send time on a message is roughly right when using a watcher.
Austin Schuh7267c532019-05-19 19:55:53 -0700809TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700810 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700811 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -0800812 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -0700813 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
814
815 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700816 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
817 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
818 builder.add_value(200);
819 ASSERT_TRUE(msg.Send(builder.Finish()));
820 });
821
Austin Schuhad154822019-12-27 15:45:13 -0800822 bool triggered = false;
Brian Silverman454bc112020-03-05 14:21:25 -0800823 loop1->MakeWatcher("/test", [&](const TestMessage &msg) {
Austin Schuhad154822019-12-27 15:45:13 -0800824 // Confirm that the data pointer makes sense from a watcher, and all the
825 // timestamps look right.
826 EXPECT_GT(&msg, loop1->context().data);
827 EXPECT_EQ(loop1->context().monotonic_remote_time,
828 loop1->context().monotonic_event_time);
829 EXPECT_EQ(loop1->context().realtime_remote_time,
830 loop1->context().realtime_event_time);
831
832 const aos::monotonic_clock::time_point monotonic_now =
833 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -0800834 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -0800835
836 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
837 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
838 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
839 monotonic_now);
840 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
841 realtime_now);
842
Alex Perrycb7da4b2019-08-28 19:35:56 -0700843 EXPECT_LT(&msg, reinterpret_cast<void *>(
Austin Schuhad154822019-12-27 15:45:13 -0800844 reinterpret_cast<char *>(loop1->context().data) +
845 loop1->context().size));
846 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -0700847 });
848
849 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
850
851 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700852 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700853
Austin Schuhad154822019-12-27 15:45:13 -0800854 EXPECT_TRUE(triggered);
855
Brian Silverman454bc112020-03-05 14:21:25 -0800856 ASSERT_TRUE(fetcher.Fetch());
857
858 monotonic_clock::duration monotonic_time_offset =
859 fetcher.context().monotonic_event_time -
860 (loop1->monotonic_now() - ::std::chrono::seconds(1));
861 realtime_clock::duration realtime_time_offset =
862 fetcher.context().realtime_event_time -
863 (loop1->realtime_now() - ::std::chrono::seconds(1));
864
865 EXPECT_EQ(fetcher.context().realtime_event_time,
866 fetcher.context().realtime_remote_time);
867 EXPECT_EQ(fetcher.context().monotonic_event_time,
868 fetcher.context().monotonic_remote_time);
869
870 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
871 << ": Got "
872 << fetcher.context().monotonic_event_time.time_since_epoch().count()
873 << " expected " << loop1->monotonic_now().time_since_epoch().count();
874 // Confirm that the data pointer makes sense.
875 EXPECT_GT(fetcher.get(), fetcher.context().data);
876 EXPECT_LT(fetcher.get(),
877 reinterpret_cast<void *>(
878 reinterpret_cast<char *>(fetcher.context().data) +
879 fetcher.context().size));
880 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
881 << ": Got "
882 << fetcher.context().monotonic_event_time.time_since_epoch().count()
883 << " expected " << loop1->monotonic_now().time_since_epoch().count();
884
885 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
886 << ": Got "
887 << fetcher.context().realtime_event_time.time_since_epoch().count()
888 << " expected " << loop1->realtime_now().time_since_epoch().count();
889 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
890 << ": Got "
891 << fetcher.context().realtime_event_time.time_since_epoch().count()
892 << " expected " << loop1->realtime_now().time_since_epoch().count();
893}
894
895// Verify that the send time on a message is roughly right when using a no-arg
896// watcher. To get a message, we need to use a fetcher to actually access the
897// message. This is also the main use case for no-arg fetchers.
898TEST_P(AbstractEventLoopTest, MessageSendTimeNoArg) {
899 auto loop1 = MakePrimary();
900 auto loop2 = Make();
901 auto sender = loop2->MakeSender<TestMessage>("/test");
902 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
903
904 auto test_timer = loop1->AddTimer([&sender]() {
905 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
906 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
907 builder.add_value(200);
908 ASSERT_TRUE(msg.Send(builder.Finish()));
909 });
910
911 bool triggered = false;
912 loop1->MakeNoArgWatcher<TestMessage>("/test", [&]() {
913 // Confirm that we can indeed use a fetcher on this channel from this
914 // context, and it results in a sane data pointer and timestamps.
915 ASSERT_TRUE(fetcher.Fetch());
916
917 EXPECT_EQ(loop1->context().monotonic_remote_time,
918 loop1->context().monotonic_event_time);
919 EXPECT_EQ(loop1->context().realtime_remote_time,
920 loop1->context().realtime_event_time);
921
922 const aos::monotonic_clock::time_point monotonic_now =
923 loop1->monotonic_now();
924 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
925
926 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
927 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
928 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
929 monotonic_now);
930 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
931 realtime_now);
932
933 triggered = true;
934 });
935
936 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
937
938 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
939 Run();
940
941 ASSERT_TRUE(triggered);
Austin Schuh7267c532019-05-19 19:55:53 -0700942
Alex Perrycb7da4b2019-08-28 19:35:56 -0700943 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -0800944 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700945 (loop1->monotonic_now() - ::std::chrono::seconds(1));
946 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -0800947 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700948 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -0700949
Austin Schuhad154822019-12-27 15:45:13 -0800950 EXPECT_EQ(fetcher.context().realtime_event_time,
951 fetcher.context().realtime_remote_time);
952 EXPECT_EQ(fetcher.context().monotonic_event_time,
953 fetcher.context().monotonic_remote_time);
954
Alex Perrycb7da4b2019-08-28 19:35:56 -0700955 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
956 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800957 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -0700958 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700959 // Confirm that the data pointer makes sense.
960 EXPECT_GT(fetcher.get(), fetcher.context().data);
961 EXPECT_LT(fetcher.get(),
962 reinterpret_cast<void *>(
963 reinterpret_cast<char *>(fetcher.context().data) +
964 fetcher.context().size));
965 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
966 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800967 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -0700968 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700969
970 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
971 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800972 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -0700973 << " expected " << loop1->realtime_now().time_since_epoch().count();
974 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
975 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800976 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -0700977 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -0700978}
979
Austin Schuh52d325c2019-06-23 18:59:06 -0700980// Tests that a couple phased loops run in a row result in the correct offset
981// and period.
982TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800983 // Force a slower rate so we are guarenteed to have reports for our phased
984 // loop.
985 FLAGS_timing_report_ms = 2000;
986
Austin Schuh52d325c2019-06-23 18:59:06 -0700987 const chrono::milliseconds kOffset = chrono::milliseconds(400);
988 const int kCount = 5;
989
990 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800991 auto loop2 = Make();
992
993 Fetcher<timing::Report> report_fetcher =
994 loop2->MakeFetcher<timing::Report>("/aos");
995 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -0700996
997 // Collect up a couple of samples.
998 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800999 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -07001000
1001 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -08001002 loop1
1003 ->AddPhasedLoop(
1004 [&times, &expected_times, &loop1, this](int count) {
1005 EXPECT_EQ(count, 1);
1006 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -08001007 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -08001008
Austin Schuhad154822019-12-27 15:45:13 -08001009 EXPECT_EQ(loop1->context().monotonic_remote_time,
1010 monotonic_clock::min_time);
1011 EXPECT_EQ(loop1->context().realtime_event_time,
1012 realtime_clock::min_time);
1013 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -08001014 realtime_clock::min_time);
1015 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
1016 EXPECT_EQ(loop1->context().size, 0u);
1017 EXPECT_EQ(loop1->context().data, nullptr);
1018
1019 if (times.size() == kCount) {
1020 LOG(INFO) << "Exiting";
1021 this->Exit();
1022 }
1023 },
1024 chrono::seconds(1), kOffset)
1025 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -07001026
1027 // Add a delay to make sure that delay during startup doesn't result in a
1028 // "missed cycle".
1029 SleepFor(chrono::seconds(2));
1030
1031 Run();
1032
1033 // Confirm that we got both the right number of samples, and it's odd.
1034 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001035 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -07001036 EXPECT_EQ((times.size() % 2), 1);
1037
1038 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001039 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -07001040
1041 // Add up all the delays of all the times.
1042 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
1043 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001044 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -07001045 }
1046
1047 // Average and add to the middle to find the average time.
1048 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001049 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -07001050
1051 // Compute the offset from the start of the second of the average time. This
1052 // should be pretty close to the offset.
1053 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001054 average_time.time_since_epoch() -
1055 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -07001056
1057 const chrono::milliseconds kEpsilon(100);
1058 EXPECT_LT(remainder, kOffset + kEpsilon);
1059 EXPECT_GT(remainder, kOffset - kEpsilon);
1060
1061 // Make sure that the average duration is close to 1 second.
1062 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
1063 times.front())
1064 .count() /
1065 static_cast<double>(times.size() - 1),
1066 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -08001067
1068 // Confirm that the ideal wakeup times increment correctly.
1069 for (size_t i = 1; i < expected_times.size(); ++i) {
1070 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
1071 }
1072
1073 for (size_t i = 0; i < expected_times.size(); ++i) {
1074 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
1075 kOffset);
1076 }
1077
1078 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
1079 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -08001080
1081 // And, since we are here, check that the timing report makes sense.
1082 // Start by looking for our event loop's timing.
1083 FlatbufferDetachedBuffer<timing::Report> report =
1084 FlatbufferDetachedBuffer<timing::Report>::Empty();
1085 while (report_fetcher.FetchNext()) {
1086 if (report_fetcher->name()->string_view() == "primary") {
1087 report = CopyFlatBuffer(report_fetcher.get());
1088 }
1089 }
1090
1091 VLOG(1) << FlatbufferToJson(report, true);
1092
1093 EXPECT_EQ(report.message().name()->string_view(), "primary");
1094
1095 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001096 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001097
1098 ASSERT_NE(report.message().timers(), nullptr);
1099 EXPECT_EQ(report.message().timers()->size(), 1);
1100
1101 // Make sure there is a single phased loop report with our report in it.
1102 ASSERT_NE(report.message().phased_loops(), nullptr);
1103 ASSERT_EQ(report.message().phased_loops()->size(), 1);
1104 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
1105 "Test loop");
1106 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
1107}
1108
1109// Tests that senders count correctly in the timing report.
1110TEST_P(AbstractEventLoopTest, SenderTimingReport) {
1111 FLAGS_timing_report_ms = 1000;
1112 auto loop1 = MakePrimary();
1113
1114 auto loop2 = Make("watcher_loop");
1115 loop2->MakeWatcher("/test", [](const TestMessage &) {});
1116
1117 auto loop3 = Make();
1118
1119 Fetcher<timing::Report> report_fetcher =
1120 loop3->MakeFetcher<timing::Report>("/aos");
1121 EXPECT_FALSE(report_fetcher.Fetch());
1122
1123 auto sender = loop1->MakeSender<TestMessage>("/test");
1124
1125 // Add a timer to actually quit.
1126 auto test_timer = loop1->AddTimer([&sender]() {
1127 for (int i = 0; i < 10; ++i) {
1128 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1129 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1130 builder.add_value(200 + i);
1131 ASSERT_TRUE(msg.Send(builder.Finish()));
1132 }
1133 });
1134
1135 // Quit after 1 timing report, mid way through the next cycle.
1136 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1137
1138 loop1->OnRun([&test_timer, &loop1]() {
1139 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1140 });
1141
1142 Run();
1143
1144 // And, since we are here, check that the timing report makes sense.
1145 // Start by looking for our event loop's timing.
1146 FlatbufferDetachedBuffer<timing::Report> primary_report =
1147 FlatbufferDetachedBuffer<timing::Report>::Empty();
1148 while (report_fetcher.FetchNext()) {
1149 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1150 if (report_fetcher->name()->string_view() == "primary") {
1151 primary_report = CopyFlatBuffer(report_fetcher.get());
1152 }
1153 }
1154
1155 LOG(INFO) << FlatbufferToJson(primary_report, true);
1156
1157 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1158
1159 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001160 EXPECT_EQ(primary_report.message().senders()->size(), 3);
Austin Schuh39788ff2019-12-01 18:22:57 -08001161
1162 // Confirm that the sender looks sane.
1163 EXPECT_EQ(
1164 loop1->configuration()
1165 ->channels()
1166 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1167 ->name()
1168 ->string_view(),
1169 "/test");
1170 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1171
1172 // Confirm that the timing primary_report sender looks sane.
1173 EXPECT_EQ(
1174 loop1->configuration()
1175 ->channels()
1176 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1177 ->name()
1178 ->string_view(),
1179 "/aos");
1180 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1181
1182 ASSERT_NE(primary_report.message().timers(), nullptr);
1183 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1184
1185 // Make sure there are no phased loops or watchers.
1186 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1187 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1188}
1189
1190// Tests that senders count correctly in the timing report.
1191TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1192 FLAGS_timing_report_ms = 1000;
1193 auto loop1 = MakePrimary();
1194 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1195
1196 auto loop2 = Make("sender_loop");
1197
1198 auto loop3 = Make();
1199
1200 Fetcher<timing::Report> report_fetcher =
1201 loop3->MakeFetcher<timing::Report>("/aos");
1202 EXPECT_FALSE(report_fetcher.Fetch());
1203
1204 auto sender = loop2->MakeSender<TestMessage>("/test");
1205
1206 // Add a timer to actually quit.
1207 auto test_timer = loop1->AddTimer([&sender]() {
1208 for (int i = 0; i < 10; ++i) {
1209 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1210 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1211 builder.add_value(200 + i);
1212 ASSERT_TRUE(msg.Send(builder.Finish()));
1213 }
1214 });
1215
1216 // Quit after 1 timing report, mid way through the next cycle.
1217 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1218
1219 loop1->OnRun([&test_timer, &loop1]() {
1220 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1221 });
1222
1223 Run();
1224
1225 // And, since we are here, check that the timing report makes sense.
1226 // Start by looking for our event loop's timing.
1227 FlatbufferDetachedBuffer<timing::Report> primary_report =
1228 FlatbufferDetachedBuffer<timing::Report>::Empty();
1229 while (report_fetcher.FetchNext()) {
1230 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1231 if (report_fetcher->name()->string_view() == "primary") {
1232 primary_report = CopyFlatBuffer(report_fetcher.get());
1233 }
1234 }
1235
1236 // Check the watcher report.
1237 VLOG(1) << FlatbufferToJson(primary_report, true);
1238
1239 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1240
1241 // Just the timing report timer.
1242 ASSERT_NE(primary_report.message().timers(), nullptr);
1243 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1244
1245 // No phased loops
1246 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1247
1248 ASSERT_NE(primary_report.message().watchers(), nullptr);
1249 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1250 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1251}
1252
1253// Tests that fetchers count correctly in the timing report.
1254TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1255 FLAGS_timing_report_ms = 1000;
1256 auto loop1 = MakePrimary();
1257 auto loop2 = Make("sender_loop");
1258
1259 auto loop3 = Make();
1260
1261 Fetcher<timing::Report> report_fetcher =
1262 loop3->MakeFetcher<timing::Report>("/aos");
1263 EXPECT_FALSE(report_fetcher.Fetch());
1264
1265 auto sender = loop2->MakeSender<TestMessage>("/test");
1266 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1267 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1268 fetcher1.Fetch();
1269 fetcher2.Fetch();
1270
1271 // Add a timer to actually quit.
1272 auto test_timer = loop1->AddTimer([&sender]() {
1273 for (int i = 0; i < 10; ++i) {
1274 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1275 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1276 builder.add_value(200 + i);
1277 ASSERT_TRUE(msg.Send(builder.Finish()));
1278 }
1279 });
1280
1281 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1282 fetcher1.Fetch();
1283 while (fetcher2.FetchNext()) {
1284 }
1285 });
1286
1287 // Quit after 1 timing report, mid way through the next cycle.
1288 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1289
1290 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1291 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1292 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1293 });
1294
1295 Run();
1296
1297 // And, since we are here, check that the timing report makes sense.
1298 // Start by looking for our event loop's timing.
1299 FlatbufferDetachedBuffer<timing::Report> primary_report =
1300 FlatbufferDetachedBuffer<timing::Report>::Empty();
1301 while (report_fetcher.FetchNext()) {
1302 if (report_fetcher->name()->string_view() == "primary") {
1303 primary_report = CopyFlatBuffer(report_fetcher.get());
1304 }
1305 }
1306
1307 VLOG(1) << FlatbufferToJson(primary_report, true);
1308
1309 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1310
1311 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001312 EXPECT_EQ(primary_report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001313
1314 ASSERT_NE(primary_report.message().timers(), nullptr);
1315 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1316
1317 // Make sure there are no phased loops or watchers.
1318 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1319 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1320
1321 // Now look at the fetchrs.
1322 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1323 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1324
1325 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1326 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1327 0.1);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001328 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(), 0.1);
1329 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(), 0.1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001330 EXPECT_EQ(primary_report.message()
1331 .fetchers()
1332 ->Get(0)
1333 ->latency()
1334 ->standard_deviation(),
1335 0.0);
1336
1337 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001338}
1339
Austin Schuh67420a42019-12-21 21:55:04 -08001340// Tests that a raw watcher and raw fetcher can receive messages from a raw
1341// sender without messing up offsets.
1342TEST_P(AbstractEventLoopTest, RawBasic) {
1343 auto loop1 = Make();
1344 auto loop2 = MakePrimary();
1345 auto loop3 = Make();
1346
1347 const std::string kData("971 is the best");
1348
1349 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001350 loop1->MakeRawSender(configuration::GetChannel(
1351 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001352
1353 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001354 loop3->MakeRawFetcher(configuration::GetChannel(
1355 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001356
1357 loop2->OnRun(
1358 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1359
1360 bool happened = false;
1361 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001362 configuration::GetChannel(loop2->configuration(), "/test",
1363 "aos.TestMessage", "", nullptr),
Austin Schuh67420a42019-12-21 21:55:04 -08001364 [this, &kData, &fetcher, &happened](const Context &context,
1365 const void *message) {
1366 happened = true;
1367 EXPECT_EQ(std::string_view(kData),
1368 std::string_view(reinterpret_cast<const char *>(message),
1369 context.size));
1370 EXPECT_EQ(std::string_view(kData),
1371 std::string_view(reinterpret_cast<const char *>(context.data),
1372 context.size));
1373
1374 ASSERT_TRUE(fetcher->Fetch());
1375
1376 EXPECT_EQ(std::string_view(kData),
1377 std::string_view(
1378 reinterpret_cast<const char *>(fetcher->context().data),
1379 fetcher->context().size));
1380
1381 this->Exit();
1382 });
1383
1384 EXPECT_FALSE(happened);
1385 Run();
1386 EXPECT_TRUE(happened);
1387}
1388
Austin Schuhad154822019-12-27 15:45:13 -08001389// Tests that a raw watcher and raw fetcher can receive messages from a raw
1390// sender with remote times filled out.
1391TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1392 auto loop1 = Make();
1393 auto loop2 = MakePrimary();
1394 auto loop3 = Make();
1395
1396 const std::string kData("971 is the best");
1397
1398 const aos::monotonic_clock::time_point monotonic_remote_time =
1399 aos::monotonic_clock::time_point(chrono::seconds(1501));
1400 const aos::realtime_clock::time_point realtime_remote_time =
1401 aos::realtime_clock::time_point(chrono::seconds(3132));
1402
1403 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001404 loop1->MakeRawSender(configuration::GetChannel(
1405 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001406
1407 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001408 loop3->MakeRawFetcher(configuration::GetChannel(
1409 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001410
1411 loop2->OnRun([&]() {
1412 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1413 realtime_remote_time));
1414 });
1415
1416 bool happened = false;
1417 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001418 configuration::GetChannel(loop2->configuration(), "/test",
1419 "aos.TestMessage", "", nullptr),
Austin Schuhad154822019-12-27 15:45:13 -08001420 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1421 const Context &context, const void * /*message*/) {
1422 happened = true;
1423 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1424 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1425
1426 ASSERT_TRUE(fetcher->Fetch());
1427 EXPECT_EQ(monotonic_remote_time,
1428 fetcher->context().monotonic_remote_time);
1429 EXPECT_EQ(realtime_remote_time,
1430 fetcher->context().realtime_remote_time);
1431
1432 this->Exit();
1433 });
1434
1435 EXPECT_FALSE(happened);
1436 Run();
1437 EXPECT_TRUE(happened);
1438}
1439
1440// Tests that a raw sender fills out sent data.
1441TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1442 auto loop1 = MakePrimary();
1443
1444 const std::string kData("971 is the best");
1445
1446 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001447 loop1->MakeRawSender(configuration::GetChannel(
1448 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001449
Tyler Chatow67ddb032020-01-12 14:30:04 -08001450 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
1451 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001452
1453 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1454
1455 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1456 EXPECT_LE(sender->monotonic_sent_time(),
1457 monotonic_now + chrono::milliseconds(100));
1458 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1459 EXPECT_LE(sender->realtime_sent_time(),
1460 realtime_now + chrono::milliseconds(100));
1461 EXPECT_EQ(sender->sent_queue_index(), 0u);
1462
1463 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1464
1465 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1466 EXPECT_LE(sender->monotonic_sent_time(),
1467 monotonic_now + chrono::milliseconds(100));
1468 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1469 EXPECT_LE(sender->realtime_sent_time(),
1470 realtime_now + chrono::milliseconds(100));
1471 EXPECT_EQ(sender->sent_queue_index(), 1u);
1472}
1473
Austin Schuh217a9782019-12-21 23:02:50 -08001474// Tests that not setting up nodes results in no node.
1475TEST_P(AbstractEventLoopTest, NoNode) {
1476 auto loop1 = Make();
1477 auto loop2 = MakePrimary();
1478
1479 EXPECT_EQ(loop1->node(), nullptr);
1480 EXPECT_EQ(loop2->node(), nullptr);
1481}
1482
1483// Tests that setting up nodes results in node being set.
1484TEST_P(AbstractEventLoopTest, Node) {
1485 EnableNodes("me");
1486
1487 auto loop1 = Make();
1488 auto loop2 = MakePrimary();
1489
1490 EXPECT_NE(loop1->node(), nullptr);
1491 EXPECT_NE(loop2->node(), nullptr);
1492}
1493
1494// Tests that watchers work with a node setup.
1495TEST_P(AbstractEventLoopTest, NodeWatcher) {
1496 EnableNodes("me");
1497
1498 auto loop1 = Make();
1499 auto loop2 = Make();
1500 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08001501 loop2->MakeRawWatcher(
1502 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1503 nullptr),
1504 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001505}
1506
Brian Silverman454bc112020-03-05 14:21:25 -08001507// Tests that no-arg watchers work with a node setup.
1508TEST_P(AbstractEventLoopTest, NodeNoArgWatcher) {
1509 EnableNodes("me");
1510
1511 auto loop1 = Make();
1512 auto loop2 = Make();
1513 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1514 loop2->MakeRawNoArgWatcher(
1515 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1516 nullptr),
1517 [](const Context &) {});
1518}
1519
Austin Schuh217a9782019-12-21 23:02:50 -08001520// Tests that fetcher work with a node setup.
1521TEST_P(AbstractEventLoopTest, NodeFetcher) {
1522 EnableNodes("me");
1523 auto loop1 = Make();
1524
1525 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08001526 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1527 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001528}
1529
1530// Tests that sender work with a node setup.
1531TEST_P(AbstractEventLoopTest, NodeSender) {
1532 EnableNodes("me");
1533 auto loop1 = Make();
1534
1535 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1536}
1537
1538// Tests that watchers fail when created on the wrong node.
1539TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
1540 EnableNodes("them");
1541
1542 auto loop1 = Make();
1543 auto loop2 = Make();
1544 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
1545 "node");
1546 EXPECT_DEATH(
1547 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001548 loop2->MakeRawWatcher(
1549 configuration::GetChannel(configuration(), "/test",
1550 "aos.TestMessage", "", nullptr),
1551 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001552 },
1553 "node");
Brian Silverman454bc112020-03-05 14:21:25 -08001554 EXPECT_DEATH({ loop1->MakeNoArgWatcher<TestMessage>("/test", []() {}); },
1555 "node");
1556 EXPECT_DEATH(
1557 {
1558 loop2->MakeRawNoArgWatcher(
1559 configuration::GetChannel(configuration(), "/test",
1560 "aos.TestMessage", "", nullptr),
1561 [](const Context &) {});
1562 },
1563 "node");
Austin Schuh217a9782019-12-21 23:02:50 -08001564}
1565
1566// Tests that fetchers fail when created on the wrong node.
1567TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
1568 EnableNodes("them");
1569 auto loop1 = Make();
1570
1571 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
1572 "node");
1573 EXPECT_DEATH(
1574 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001575 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1576 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001577 },
1578 "node");
1579}
1580
1581// Tests that senders fail when created on the wrong node.
1582TEST_P(AbstractEventLoopDeathTest, NodeSender) {
1583 EnableNodes("them");
1584 auto loop1 = Make();
1585
1586 EXPECT_DEATH(
1587 {
1588 aos::Sender<TestMessage> sender =
1589 loop1->MakeSender<TestMessage>("/test");
1590 },
1591 "node");
1592
1593 // Note: Creating raw senders is always supported. Right now, this lets us
1594 // use them to create message_gateway.
1595}
1596
Parker Schuhe4a70d62017-12-27 20:10:20 -08001597} // namespace testing
1598} // namespace aos