blob: 096d84a6cbec9232a937481fd811cf71b6150b21 [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 Silverman0fc69932020-01-24 21:54:02 -080046// Tests that watcher can receive messages from two senders.
47// Also tests that OnRun() works.
48TEST_P(AbstractEventLoopTest, BasicTwoSenders) {
49 auto loop1 = Make();
50 auto loop2 = MakePrimary();
51
52 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
53 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
54
55 bool happened = false;
56
57 loop2->OnRun([&]() {
58 happened = true;
59
60 {
61 aos::Sender<TestMessage>::Builder msg = sender1.MakeBuilder();
62 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
63 builder.add_value(200);
64 ASSERT_TRUE(msg.Send(builder.Finish()));
65 }
66 {
67 aos::Sender<TestMessage>::Builder msg = sender2.MakeBuilder();
68 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
69 builder.add_value(200);
70 ASSERT_TRUE(msg.Send(builder.Finish()));
71 }
72 });
73
74 int messages_received = 0;
75 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
76 EXPECT_EQ(message.value(), 200);
77 this->Exit();
78 ++messages_received;
79 });
80
81 EXPECT_FALSE(happened);
82 Run();
83 EXPECT_TRUE(happened);
84 EXPECT_EQ(messages_received, 2);
85}
86
Austin Schuh6b6dfa52019-06-12 20:16:20 -070087// Tests that a fetcher can fetch from a sender.
88// Also tests that OnRun() works.
89TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
90 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -080091 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -070092 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -080093
94 auto sender = loop1->MakeSender<TestMessage>("/test");
95
96 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
97
Austin Schuhbbce72d2019-05-26 15:11:46 -070098 EXPECT_FALSE(fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -080099 EXPECT_EQ(fetcher.get(), nullptr);
100
Austin Schuhad154822019-12-27 15:45:13 -0800101 EXPECT_EQ(fetcher.context().monotonic_event_time, monotonic_clock::min_time);
102 EXPECT_EQ(fetcher.context().monotonic_remote_time, monotonic_clock::min_time);
103 EXPECT_EQ(fetcher.context().realtime_event_time, realtime_clock::min_time);
104 EXPECT_EQ(fetcher.context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800105 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
106 EXPECT_EQ(fetcher.context().size, 0u);
107 EXPECT_EQ(fetcher.context().data, nullptr);
Austin Schuhbbce72d2019-05-26 15:11:46 -0700108
Alex Perrycb7da4b2019-08-28 19:35:56 -0700109 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
110 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
111 builder.add_value(200);
112 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700113
114 EXPECT_TRUE(fetcher.Fetch());
115 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700116 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -0800117
118 const chrono::milliseconds kEpsilon(100);
119
Austin Schuhad154822019-12-27 15:45:13 -0800120 const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
121 const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
122 EXPECT_EQ(fetcher.context().monotonic_event_time,
123 fetcher.context().monotonic_remote_time);
124 EXPECT_EQ(fetcher.context().realtime_event_time,
125 fetcher.context().realtime_remote_time);
126
127 EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
128 EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
129 EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
130 EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800131 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
132 EXPECT_EQ(fetcher.context().size, 20u);
133 EXPECT_NE(fetcher.context().data, nullptr);
Parker Schuhe4a70d62017-12-27 20:10:20 -0800134}
135
Austin Schuh3578a2e2019-05-25 18:17:59 -0700136// Tests that watcher will receive all messages sent if they are sent after
137// initialization and before running.
138TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
139 auto loop1 = Make();
140 auto loop2 = MakePrimary();
141
142 auto sender = loop1->MakeSender<TestMessage>("/test");
143
144 ::std::vector<int> values;
145
146 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700147 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700148 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700149 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700150 }
151 });
152
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700153 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -0700154 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700155 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
156 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
157 builder.add_value(199);
158 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700159 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700160
161 loop2->OnRun([&]() {
162 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700163 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
164 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
165 builder.add_value(200);
166 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700167 }
168 {
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(201);
172 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700173 }
174 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700175
176 Run();
177
178 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
179}
180
181// Tests that watcher will not receive messages sent before the watcher is
182// created.
183TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
184 auto loop1 = Make();
185 auto loop2 = MakePrimary();
186
187 auto sender = loop1->MakeSender<TestMessage>("/test");
188
189 ::std::vector<int> values;
190
191 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700192 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
193 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
194 builder.add_value(200);
195 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700196 }
197 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700198 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
199 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
200 builder.add_value(201);
201 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700202 }
203
204 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700205 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700206 });
207
208 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700209 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700210 loop2->OnRun([&test_timer, &loop2]() {
211 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
212 });
213
214 Run();
215 EXPECT_EQ(0, values.size());
216}
217
Austin Schuhbbce72d2019-05-26 15:11:46 -0700218// Tests that FetchNext gets all the messages sent after it is constructed.
219TEST_P(AbstractEventLoopTest, FetchNext) {
220 auto loop1 = Make();
221 auto loop2 = MakePrimary();
222
223 auto sender = loop1->MakeSender<TestMessage>("/test");
224 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
225
226 ::std::vector<int> values;
227
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(200);
232 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700233 }
234 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700235 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
236 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
237 builder.add_value(201);
238 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700239 }
240
241 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700242 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700243 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700244 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700245 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700246 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700247 });
248
249 loop2->OnRun([&test_timer, &loop2]() {
250 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
251 });
252
253 Run();
254 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
255}
256
257// Tests that FetchNext gets no messages sent before it is constructed.
258TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
259 auto loop1 = Make();
260 auto loop2 = MakePrimary();
261
262 auto sender = loop1->MakeSender<TestMessage>("/test");
263
264 ::std::vector<int> values;
265
266 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700267 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
268 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
269 builder.add_value(200);
270 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700271 }
272 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700273 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
274 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
275 builder.add_value(201);
276 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700277 }
278
279 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
280
281 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700282 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700283 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700284 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700285 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700286 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700287 });
288
289 loop2->OnRun([&test_timer, &loop2]() {
290 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
291 });
292
293 Run();
294 EXPECT_THAT(0, values.size());
295}
296
297// Tests that Fetch returns the last message created before the loop was
298// started.
299TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
300 auto loop1 = Make();
301 auto loop2 = MakePrimary();
302
303 auto sender = loop1->MakeSender<TestMessage>("/test");
304
305 ::std::vector<int> values;
306
307 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700308 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
309 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
310 builder.add_value(200);
311 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700312 }
313 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700314 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
315 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
316 builder.add_value(201);
317 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700318 }
319
320 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
321
322 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700323 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700324 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700325 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700326 }
327 // Do it again to make sure we don't double fetch.
328 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700329 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700330 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700331 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700332 });
333
334 loop2->OnRun([&test_timer, &loop2]() {
335 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
336 });
337
338 Run();
339 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
340}
341
342// Tests that Fetch and FetchNext interleave as expected.
343TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
344 auto loop1 = Make();
345 auto loop2 = MakePrimary();
346
347 auto sender = loop1->MakeSender<TestMessage>("/test");
348
349 ::std::vector<int> values;
350
351 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700352 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
353 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
354 builder.add_value(200);
355 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700356 }
357 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700358 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
359 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
360 builder.add_value(201);
361 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700362 }
363
364 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
365
366 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700367 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700368 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700369 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700370 }
371
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(202);
376 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700377 }
378 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700379 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
380 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
381 builder.add_value(203);
382 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700383 }
384 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700385 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
386 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
387 builder.add_value(204);
388 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700389 }
390
391 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700392 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700393 }
394
395 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700396 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700397 }
398
Austin Schuh9fe68f72019-08-10 19:32:03 -0700399 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700400 });
401
402 loop2->OnRun([&test_timer, &loop2]() {
403 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
404 });
405
406 Run();
407 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
408}
409
Austin Schuh3115a202019-05-27 21:02:14 -0700410// Tests that FetchNext behaves correctly when we get two messages in the queue
411// but don't consume the first until after the second has been sent.
412TEST_P(AbstractEventLoopTest, FetchNextTest) {
Austin Schuh3115a202019-05-27 21:02:14 -0700413 auto send_loop = Make();
414 auto fetch_loop = Make();
415 auto sender = send_loop->MakeSender<TestMessage>("/test");
416 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
417
418 {
Tyler Chatow67ddb032020-01-12 14:30:04 -0800419 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
420 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
421 builder.add_value(100);
422 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700423 }
424
425 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700426 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
427 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
428 builder.add_value(200);
429 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700430 }
431
432 ASSERT_TRUE(fetcher.FetchNext());
433 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700434 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700435
436 ASSERT_TRUE(fetcher.FetchNext());
437 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700438 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700439
440 // When we run off the end of the queue, expect to still have the old message:
441 ASSERT_FALSE(fetcher.FetchNext());
442 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700443 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700444}
445
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800446// Verify that making a fetcher and watcher for "/test" succeeds.
447TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800448 auto loop = Make();
449 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800450 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800451}
452
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800453// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800454TEST_P(AbstractEventLoopTest, TwoFetcher) {
455 auto loop = Make();
456 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800457 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800458}
459
Alex Perrycb7da4b2019-08-28 19:35:56 -0700460// Verify that registering a watcher for an invalid channel name dies.
461TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
462 auto loop = Make();
463 EXPECT_DEATH(
464 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
465 "/test/invalid");
466}
467
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800468// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700469TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800470 auto loop = Make();
471 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800472 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
473 "/test");
474}
475
Austin Schuh3115a202019-05-27 21:02:14 -0700476// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700477TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700478 auto loop = MakePrimary();
479 // Confirm that runtime priority calls work when not realtime.
480 loop->SetRuntimeRealtimePriority(5);
481
482 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
483
484 EXPECT_DEATH(Run(), "realtime");
485}
486
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800487// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700488TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800489 auto loop = Make();
490 auto sender = loop->MakeSender<TestMessage>("/test");
491 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
492 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800493}
494
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700495// Verify that we can't create a sender inside OnRun.
496TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
497 auto loop1 = MakePrimary();
498
499 loop1->OnRun(
500 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
501
502 EXPECT_DEATH(Run(), "running");
503}
504
505// Verify that we can't create a watcher inside OnRun.
506TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
507 auto loop1 = MakePrimary();
508
509 loop1->OnRun(
510 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
511
512 EXPECT_DEATH(Run(), "running");
513}
514
Parker Schuhe4a70d62017-12-27 20:10:20 -0800515// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800516TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
517 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700518 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800519
Austin Schuh3578a2e2019-05-25 18:17:59 -0700520 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
521 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700522 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700523 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700524 });
525
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800526 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700527
528 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700529 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
530 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
531 builder.add_value(200);
532 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700533 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800534
Austin Schuh44019f92019-05-19 19:58:27 -0700535 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800536}
537
Neil Balch229001a2018-01-07 18:22:52 -0800538// Verify that timer intervals and duration function properly.
539TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800540 // Force a slower rate so we are guarenteed to have reports for our timer.
541 FLAGS_timing_report_ms = 2000;
542
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800543 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800544
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800545 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800546 auto loop2 = Make();
547
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800548 ::std::vector<::aos::monotonic_clock::time_point> times;
549 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
550
Austin Schuh39788ff2019-12-01 18:22:57 -0800551 Fetcher<timing::Report> report_fetcher =
552 loop2->MakeFetcher<timing::Report>("/aos");
553 EXPECT_FALSE(report_fetcher.Fetch());
554
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800555 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
556 times.push_back(loop->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800557 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
558 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
559 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800560 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
561 EXPECT_EQ(loop->context().size, 0u);
562 EXPECT_EQ(loop->context().data, nullptr);
563
Austin Schuhad154822019-12-27 15:45:13 -0800564 expected_times.push_back(loop->context().monotonic_event_time);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800565 if (times.size() == kCount) {
566 this->Exit();
567 }
Neil Balch229001a2018-01-07 18:22:52 -0800568 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800569 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800570
Austin Schuh39788ff2019-12-01 18:22:57 -0800571 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700572 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800573 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
574
Austin Schuh44019f92019-05-19 19:58:27 -0700575 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800576
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800577 // Confirm that we got both the right number of samples, and it's odd.
578 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
579 EXPECT_EQ(times.size(), expected_times.size());
580 EXPECT_EQ((times.size() % 2), 1);
581
582 // Grab the middle sample.
583 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
584
585 // Add up all the delays of all the times.
586 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
587 for (const ::aos::monotonic_clock::time_point time : times) {
588 sum += time - average_time;
589 }
590
591 // Average and add to the middle to find the average time.
592 sum /= times.size();
593 average_time += sum;
594
595 // Compute the offset from the average and the expected average. It
596 // should be pretty close to 0.
597 const ::aos::monotonic_clock::duration remainder =
598 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
599
600 const chrono::milliseconds kEpsilon(100);
601 EXPECT_LT(remainder, +kEpsilon);
602 EXPECT_GT(remainder, -kEpsilon);
603
604 // Make sure that the average duration is close to 1 second.
605 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
606 times.front())
607 .count() /
608 static_cast<double>(times.size() - 1),
609 1.0, 0.1);
610
611 // Confirm that the ideal wakeup times increment correctly.
612 for (size_t i = 1; i < expected_times.size(); ++i) {
613 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
614 }
615
616 for (size_t i = 0; i < expected_times.size(); ++i) {
617 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
618 chrono::seconds(0));
619 }
620
621 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
622 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800623
624 // And, since we are here, check that the timing report makes sense.
625 // Start by looking for our event loop's timing.
626 FlatbufferDetachedBuffer<timing::Report> report =
627 FlatbufferDetachedBuffer<timing::Report>::Empty();
628 while (report_fetcher.FetchNext()) {
629 if (report_fetcher->name()->string_view() == "primary") {
630 report = CopyFlatBuffer(report_fetcher.get());
631 }
632 }
633
634 // Confirm that we have the right number of reports, and the contents are
635 // sane.
636 VLOG(1) << FlatbufferToJson(report, true);
637
638 EXPECT_EQ(report.message().name()->string_view(), "primary");
639
640 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -0800641 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -0800642
643 ASSERT_NE(report.message().timers(), nullptr);
644 EXPECT_EQ(report.message().timers()->size(), 2);
645
646 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
647 "Test loop");
648 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
649
650 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
651 "timing_reports");
652 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
653
654 // Make sure there is a single phased loop report with our report in it.
655 ASSERT_EQ(report.message().phased_loops(), nullptr);
Neil Balch229001a2018-01-07 18:22:52 -0800656}
657
658// Verify that we can change a timer's parameters during execution.
659TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700660 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800661 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
662
663 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
664 iteration_list.push_back(loop->monotonic_now());
665 });
666
667 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
668 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
669 });
670
Neil Balch229001a2018-01-07 18:22:52 -0800671 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
672 modifier_timer->Setup(loop->monotonic_now() +
673 ::std::chrono::milliseconds(45));
674 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700675 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800676
677 EXPECT_EQ(iteration_list.size(), 7);
678}
679
680// Verify that we can disable a timer during execution.
681TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700682 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800683 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
684
685 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
686 iteration_list.push_back(loop->monotonic_now());
687 });
688
Tyler Chatow67ddb032020-01-12 14:30:04 -0800689 auto ender_timer = loop->AddTimer([&test_timer]() { test_timer->Disable(); });
Neil Balch229001a2018-01-07 18:22:52 -0800690
691 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
Tyler Chatow67ddb032020-01-12 14:30:04 -0800692 ender_timer->Setup(loop->monotonic_now() + ::std::chrono::milliseconds(45));
Neil Balch229001a2018-01-07 18:22:52 -0800693 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700694 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800695
696 EXPECT_EQ(iteration_list.size(), 3);
697}
Austin Schuh7267c532019-05-19 19:55:53 -0700698
Austin Schuh54cf95f2019-11-29 13:14:18 -0800699// Verifies that the event loop implementations detect when Channel is not a
700// pointer into confguration()
701TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
702 auto loop = MakePrimary();
703
Tyler Chatow67ddb032020-01-12 14:30:04 -0800704 const Channel *channel = configuration::GetChannel(
705 loop->configuration(), "/test", "aos.TestMessage", "", nullptr);
Austin Schuh54cf95f2019-11-29 13:14:18 -0800706
707 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
708
709 EXPECT_DEATH(
710 { loop->MakeRawSender(&channel_copy.message()); },
711 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
712
713 EXPECT_DEATH(
714 { loop->MakeRawFetcher(&channel_copy.message()); },
715 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
716
717 EXPECT_DEATH(
718 {
719 loop->MakeRawWatcher(&channel_copy.message(),
720 [](const Context, const void *) {});
721 },
722 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
723}
724
Austin Schuh7267c532019-05-19 19:55:53 -0700725// Verify that the send time on a message is roughly right.
726TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700727 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700728 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -0800729 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -0700730 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
731
732 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700733 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
734 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
735 builder.add_value(200);
736 ASSERT_TRUE(msg.Send(builder.Finish()));
737 });
738
Austin Schuhad154822019-12-27 15:45:13 -0800739 bool triggered = false;
740 loop1->MakeWatcher("/test", [&triggered, &loop1](const TestMessage &msg) {
741 // Confirm that the data pointer makes sense from a watcher, and all the
742 // timestamps look right.
743 EXPECT_GT(&msg, loop1->context().data);
744 EXPECT_EQ(loop1->context().monotonic_remote_time,
745 loop1->context().monotonic_event_time);
746 EXPECT_EQ(loop1->context().realtime_remote_time,
747 loop1->context().realtime_event_time);
748
749 const aos::monotonic_clock::time_point monotonic_now =
750 loop1->monotonic_now();
Tyler Chatow67ddb032020-01-12 14:30:04 -0800751 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -0800752
753 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
754 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
755 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
756 monotonic_now);
757 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
758 realtime_now);
759
Alex Perrycb7da4b2019-08-28 19:35:56 -0700760 EXPECT_LT(&msg, reinterpret_cast<void *>(
Austin Schuhad154822019-12-27 15:45:13 -0800761 reinterpret_cast<char *>(loop1->context().data) +
762 loop1->context().size));
763 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -0700764 });
765
766 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
767
768 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700769 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700770
Austin Schuhad154822019-12-27 15:45:13 -0800771 EXPECT_TRUE(triggered);
772
Austin Schuh7267c532019-05-19 19:55:53 -0700773 EXPECT_TRUE(fetcher.Fetch());
774
Alex Perrycb7da4b2019-08-28 19:35:56 -0700775 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -0800776 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700777 (loop1->monotonic_now() - ::std::chrono::seconds(1));
778 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -0800779 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700780 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -0700781
Austin Schuhad154822019-12-27 15:45:13 -0800782 EXPECT_EQ(fetcher.context().realtime_event_time,
783 fetcher.context().realtime_remote_time);
784 EXPECT_EQ(fetcher.context().monotonic_event_time,
785 fetcher.context().monotonic_remote_time);
786
Alex Perrycb7da4b2019-08-28 19:35:56 -0700787 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
788 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800789 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -0700790 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700791 // Confirm that the data pointer makes sense.
792 EXPECT_GT(fetcher.get(), fetcher.context().data);
793 EXPECT_LT(fetcher.get(),
794 reinterpret_cast<void *>(
795 reinterpret_cast<char *>(fetcher.context().data) +
796 fetcher.context().size));
797 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
798 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800799 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -0700800 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700801
802 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
803 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800804 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -0700805 << " expected " << loop1->realtime_now().time_since_epoch().count();
806 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
807 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800808 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -0700809 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -0700810}
811
Austin Schuh52d325c2019-06-23 18:59:06 -0700812// Tests that a couple phased loops run in a row result in the correct offset
813// and period.
814TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800815 // Force a slower rate so we are guarenteed to have reports for our phased
816 // loop.
817 FLAGS_timing_report_ms = 2000;
818
Austin Schuh52d325c2019-06-23 18:59:06 -0700819 const chrono::milliseconds kOffset = chrono::milliseconds(400);
820 const int kCount = 5;
821
822 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800823 auto loop2 = Make();
824
825 Fetcher<timing::Report> report_fetcher =
826 loop2->MakeFetcher<timing::Report>("/aos");
827 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -0700828
829 // Collect up a couple of samples.
830 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800831 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -0700832
833 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -0800834 loop1
835 ->AddPhasedLoop(
836 [&times, &expected_times, &loop1, this](int count) {
837 EXPECT_EQ(count, 1);
838 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800839 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800840
Austin Schuhad154822019-12-27 15:45:13 -0800841 EXPECT_EQ(loop1->context().monotonic_remote_time,
842 monotonic_clock::min_time);
843 EXPECT_EQ(loop1->context().realtime_event_time,
844 realtime_clock::min_time);
845 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -0800846 realtime_clock::min_time);
847 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
848 EXPECT_EQ(loop1->context().size, 0u);
849 EXPECT_EQ(loop1->context().data, nullptr);
850
851 if (times.size() == kCount) {
852 LOG(INFO) << "Exiting";
853 this->Exit();
854 }
855 },
856 chrono::seconds(1), kOffset)
857 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -0700858
859 // Add a delay to make sure that delay during startup doesn't result in a
860 // "missed cycle".
861 SleepFor(chrono::seconds(2));
862
863 Run();
864
865 // Confirm that we got both the right number of samples, and it's odd.
866 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800867 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -0700868 EXPECT_EQ((times.size() % 2), 1);
869
870 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800871 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -0700872
873 // Add up all the delays of all the times.
874 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
875 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800876 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -0700877 }
878
879 // Average and add to the middle to find the average time.
880 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800881 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -0700882
883 // Compute the offset from the start of the second of the average time. This
884 // should be pretty close to the offset.
885 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800886 average_time.time_since_epoch() -
887 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -0700888
889 const chrono::milliseconds kEpsilon(100);
890 EXPECT_LT(remainder, kOffset + kEpsilon);
891 EXPECT_GT(remainder, kOffset - kEpsilon);
892
893 // Make sure that the average duration is close to 1 second.
894 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
895 times.front())
896 .count() /
897 static_cast<double>(times.size() - 1),
898 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800899
900 // Confirm that the ideal wakeup times increment correctly.
901 for (size_t i = 1; i < expected_times.size(); ++i) {
902 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
903 }
904
905 for (size_t i = 0; i < expected_times.size(); ++i) {
906 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
907 kOffset);
908 }
909
910 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
911 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800912
913 // And, since we are here, check that the timing report makes sense.
914 // Start by looking for our event loop's timing.
915 FlatbufferDetachedBuffer<timing::Report> report =
916 FlatbufferDetachedBuffer<timing::Report>::Empty();
917 while (report_fetcher.FetchNext()) {
918 if (report_fetcher->name()->string_view() == "primary") {
919 report = CopyFlatBuffer(report_fetcher.get());
920 }
921 }
922
923 VLOG(1) << FlatbufferToJson(report, true);
924
925 EXPECT_EQ(report.message().name()->string_view(), "primary");
926
927 ASSERT_NE(report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -0800928 EXPECT_EQ(report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -0800929
930 ASSERT_NE(report.message().timers(), nullptr);
931 EXPECT_EQ(report.message().timers()->size(), 1);
932
933 // Make sure there is a single phased loop report with our report in it.
934 ASSERT_NE(report.message().phased_loops(), nullptr);
935 ASSERT_EQ(report.message().phased_loops()->size(), 1);
936 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
937 "Test loop");
938 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
939}
940
941// Tests that senders count correctly in the timing report.
942TEST_P(AbstractEventLoopTest, SenderTimingReport) {
943 FLAGS_timing_report_ms = 1000;
944 auto loop1 = MakePrimary();
945
946 auto loop2 = Make("watcher_loop");
947 loop2->MakeWatcher("/test", [](const TestMessage &) {});
948
949 auto loop3 = Make();
950
951 Fetcher<timing::Report> report_fetcher =
952 loop3->MakeFetcher<timing::Report>("/aos");
953 EXPECT_FALSE(report_fetcher.Fetch());
954
955 auto sender = loop1->MakeSender<TestMessage>("/test");
956
957 // Add a timer to actually quit.
958 auto test_timer = loop1->AddTimer([&sender]() {
959 for (int i = 0; i < 10; ++i) {
960 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
961 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
962 builder.add_value(200 + i);
963 ASSERT_TRUE(msg.Send(builder.Finish()));
964 }
965 });
966
967 // Quit after 1 timing report, mid way through the next cycle.
968 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
969
970 loop1->OnRun([&test_timer, &loop1]() {
971 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
972 });
973
974 Run();
975
976 // And, since we are here, check that the timing report makes sense.
977 // Start by looking for our event loop's timing.
978 FlatbufferDetachedBuffer<timing::Report> primary_report =
979 FlatbufferDetachedBuffer<timing::Report>::Empty();
980 while (report_fetcher.FetchNext()) {
981 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
982 if (report_fetcher->name()->string_view() == "primary") {
983 primary_report = CopyFlatBuffer(report_fetcher.get());
984 }
985 }
986
987 LOG(INFO) << FlatbufferToJson(primary_report, true);
988
989 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
990
991 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -0800992 EXPECT_EQ(primary_report.message().senders()->size(), 3);
Austin Schuh39788ff2019-12-01 18:22:57 -0800993
994 // Confirm that the sender looks sane.
995 EXPECT_EQ(
996 loop1->configuration()
997 ->channels()
998 ->Get(primary_report.message().senders()->Get(0)->channel_index())
999 ->name()
1000 ->string_view(),
1001 "/test");
1002 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1003
1004 // Confirm that the timing primary_report sender looks sane.
1005 EXPECT_EQ(
1006 loop1->configuration()
1007 ->channels()
1008 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1009 ->name()
1010 ->string_view(),
1011 "/aos");
1012 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1013
1014 ASSERT_NE(primary_report.message().timers(), nullptr);
1015 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1016
1017 // Make sure there are no phased loops or watchers.
1018 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1019 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1020}
1021
1022// Tests that senders count correctly in the timing report.
1023TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1024 FLAGS_timing_report_ms = 1000;
1025 auto loop1 = MakePrimary();
1026 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1027
1028 auto loop2 = Make("sender_loop");
1029
1030 auto loop3 = Make();
1031
1032 Fetcher<timing::Report> report_fetcher =
1033 loop3->MakeFetcher<timing::Report>("/aos");
1034 EXPECT_FALSE(report_fetcher.Fetch());
1035
1036 auto sender = loop2->MakeSender<TestMessage>("/test");
1037
1038 // Add a timer to actually quit.
1039 auto test_timer = loop1->AddTimer([&sender]() {
1040 for (int i = 0; i < 10; ++i) {
1041 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1042 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1043 builder.add_value(200 + i);
1044 ASSERT_TRUE(msg.Send(builder.Finish()));
1045 }
1046 });
1047
1048 // Quit after 1 timing report, mid way through the next cycle.
1049 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1050
1051 loop1->OnRun([&test_timer, &loop1]() {
1052 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1053 });
1054
1055 Run();
1056
1057 // And, since we are here, check that the timing report makes sense.
1058 // Start by looking for our event loop's timing.
1059 FlatbufferDetachedBuffer<timing::Report> primary_report =
1060 FlatbufferDetachedBuffer<timing::Report>::Empty();
1061 while (report_fetcher.FetchNext()) {
1062 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1063 if (report_fetcher->name()->string_view() == "primary") {
1064 primary_report = CopyFlatBuffer(report_fetcher.get());
1065 }
1066 }
1067
1068 // Check the watcher report.
1069 VLOG(1) << FlatbufferToJson(primary_report, true);
1070
1071 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1072
1073 // Just the timing report timer.
1074 ASSERT_NE(primary_report.message().timers(), nullptr);
1075 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1076
1077 // No phased loops
1078 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1079
1080 ASSERT_NE(primary_report.message().watchers(), nullptr);
1081 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1082 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1083}
1084
1085// Tests that fetchers count correctly in the timing report.
1086TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1087 FLAGS_timing_report_ms = 1000;
1088 auto loop1 = MakePrimary();
1089 auto loop2 = Make("sender_loop");
1090
1091 auto loop3 = Make();
1092
1093 Fetcher<timing::Report> report_fetcher =
1094 loop3->MakeFetcher<timing::Report>("/aos");
1095 EXPECT_FALSE(report_fetcher.Fetch());
1096
1097 auto sender = loop2->MakeSender<TestMessage>("/test");
1098 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1099 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1100 fetcher1.Fetch();
1101 fetcher2.Fetch();
1102
1103 // Add a timer to actually quit.
1104 auto test_timer = loop1->AddTimer([&sender]() {
1105 for (int i = 0; i < 10; ++i) {
1106 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1107 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1108 builder.add_value(200 + i);
1109 ASSERT_TRUE(msg.Send(builder.Finish()));
1110 }
1111 });
1112
1113 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1114 fetcher1.Fetch();
1115 while (fetcher2.FetchNext()) {
1116 }
1117 });
1118
1119 // Quit after 1 timing report, mid way through the next cycle.
1120 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1121
1122 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1123 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1124 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1125 });
1126
1127 Run();
1128
1129 // And, since we are here, check that the timing report makes sense.
1130 // Start by looking for our event loop's timing.
1131 FlatbufferDetachedBuffer<timing::Report> primary_report =
1132 FlatbufferDetachedBuffer<timing::Report>::Empty();
1133 while (report_fetcher.FetchNext()) {
1134 if (report_fetcher->name()->string_view() == "primary") {
1135 primary_report = CopyFlatBuffer(report_fetcher.get());
1136 }
1137 }
1138
1139 VLOG(1) << FlatbufferToJson(primary_report, true);
1140
1141 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1142
1143 ASSERT_NE(primary_report.message().senders(), nullptr);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001144 EXPECT_EQ(primary_report.message().senders()->size(), 2);
Austin Schuh39788ff2019-12-01 18:22:57 -08001145
1146 ASSERT_NE(primary_report.message().timers(), nullptr);
1147 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1148
1149 // Make sure there are no phased loops or watchers.
1150 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1151 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1152
1153 // Now look at the fetchrs.
1154 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1155 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1156
1157 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1158 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1159 0.1);
Tyler Chatow67ddb032020-01-12 14:30:04 -08001160 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(), 0.1);
1161 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(), 0.1);
Austin Schuh39788ff2019-12-01 18:22:57 -08001162 EXPECT_EQ(primary_report.message()
1163 .fetchers()
1164 ->Get(0)
1165 ->latency()
1166 ->standard_deviation(),
1167 0.0);
1168
1169 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001170}
1171
Austin Schuh67420a42019-12-21 21:55:04 -08001172// Tests that a raw watcher and raw fetcher can receive messages from a raw
1173// sender without messing up offsets.
1174TEST_P(AbstractEventLoopTest, RawBasic) {
1175 auto loop1 = Make();
1176 auto loop2 = MakePrimary();
1177 auto loop3 = Make();
1178
1179 const std::string kData("971 is the best");
1180
1181 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001182 loop1->MakeRawSender(configuration::GetChannel(
1183 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001184
1185 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001186 loop3->MakeRawFetcher(configuration::GetChannel(
1187 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh67420a42019-12-21 21:55:04 -08001188
1189 loop2->OnRun(
1190 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1191
1192 bool happened = false;
1193 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001194 configuration::GetChannel(loop2->configuration(), "/test",
1195 "aos.TestMessage", "", nullptr),
Austin Schuh67420a42019-12-21 21:55:04 -08001196 [this, &kData, &fetcher, &happened](const Context &context,
1197 const void *message) {
1198 happened = true;
1199 EXPECT_EQ(std::string_view(kData),
1200 std::string_view(reinterpret_cast<const char *>(message),
1201 context.size));
1202 EXPECT_EQ(std::string_view(kData),
1203 std::string_view(reinterpret_cast<const char *>(context.data),
1204 context.size));
1205
1206 ASSERT_TRUE(fetcher->Fetch());
1207
1208 EXPECT_EQ(std::string_view(kData),
1209 std::string_view(
1210 reinterpret_cast<const char *>(fetcher->context().data),
1211 fetcher->context().size));
1212
1213 this->Exit();
1214 });
1215
1216 EXPECT_FALSE(happened);
1217 Run();
1218 EXPECT_TRUE(happened);
1219}
1220
Austin Schuhad154822019-12-27 15:45:13 -08001221// Tests that a raw watcher and raw fetcher can receive messages from a raw
1222// sender with remote times filled out.
1223TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1224 auto loop1 = Make();
1225 auto loop2 = MakePrimary();
1226 auto loop3 = Make();
1227
1228 const std::string kData("971 is the best");
1229
1230 const aos::monotonic_clock::time_point monotonic_remote_time =
1231 aos::monotonic_clock::time_point(chrono::seconds(1501));
1232 const aos::realtime_clock::time_point realtime_remote_time =
1233 aos::realtime_clock::time_point(chrono::seconds(3132));
1234
1235 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001236 loop1->MakeRawSender(configuration::GetChannel(
1237 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001238
1239 std::unique_ptr<aos::RawFetcher> fetcher =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001240 loop3->MakeRawFetcher(configuration::GetChannel(
1241 loop3->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001242
1243 loop2->OnRun([&]() {
1244 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1245 realtime_remote_time));
1246 });
1247
1248 bool happened = false;
1249 loop2->MakeRawWatcher(
Tyler Chatow67ddb032020-01-12 14:30:04 -08001250 configuration::GetChannel(loop2->configuration(), "/test",
1251 "aos.TestMessage", "", nullptr),
Austin Schuhad154822019-12-27 15:45:13 -08001252 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1253 const Context &context, const void * /*message*/) {
1254 happened = true;
1255 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1256 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1257
1258 ASSERT_TRUE(fetcher->Fetch());
1259 EXPECT_EQ(monotonic_remote_time,
1260 fetcher->context().monotonic_remote_time);
1261 EXPECT_EQ(realtime_remote_time,
1262 fetcher->context().realtime_remote_time);
1263
1264 this->Exit();
1265 });
1266
1267 EXPECT_FALSE(happened);
1268 Run();
1269 EXPECT_TRUE(happened);
1270}
1271
1272// Tests that a raw sender fills out sent data.
1273TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1274 auto loop1 = MakePrimary();
1275
1276 const std::string kData("971 is the best");
1277
1278 std::unique_ptr<aos::RawSender> sender =
Tyler Chatow67ddb032020-01-12 14:30:04 -08001279 loop1->MakeRawSender(configuration::GetChannel(
1280 loop1->configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuhad154822019-12-27 15:45:13 -08001281
Tyler Chatow67ddb032020-01-12 14:30:04 -08001282 const aos::monotonic_clock::time_point monotonic_now = loop1->monotonic_now();
1283 const aos::realtime_clock::time_point realtime_now = loop1->realtime_now();
Austin Schuhad154822019-12-27 15:45:13 -08001284
1285 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1286
1287 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1288 EXPECT_LE(sender->monotonic_sent_time(),
1289 monotonic_now + chrono::milliseconds(100));
1290 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1291 EXPECT_LE(sender->realtime_sent_time(),
1292 realtime_now + chrono::milliseconds(100));
1293 EXPECT_EQ(sender->sent_queue_index(), 0u);
1294
1295 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1296
1297 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1298 EXPECT_LE(sender->monotonic_sent_time(),
1299 monotonic_now + chrono::milliseconds(100));
1300 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1301 EXPECT_LE(sender->realtime_sent_time(),
1302 realtime_now + chrono::milliseconds(100));
1303 EXPECT_EQ(sender->sent_queue_index(), 1u);
1304}
1305
Austin Schuh217a9782019-12-21 23:02:50 -08001306// Tests that not setting up nodes results in no node.
1307TEST_P(AbstractEventLoopTest, NoNode) {
1308 auto loop1 = Make();
1309 auto loop2 = MakePrimary();
1310
1311 EXPECT_EQ(loop1->node(), nullptr);
1312 EXPECT_EQ(loop2->node(), nullptr);
1313}
1314
1315// Tests that setting up nodes results in node being set.
1316TEST_P(AbstractEventLoopTest, Node) {
1317 EnableNodes("me");
1318
1319 auto loop1 = Make();
1320 auto loop2 = MakePrimary();
1321
1322 EXPECT_NE(loop1->node(), nullptr);
1323 EXPECT_NE(loop2->node(), nullptr);
1324}
1325
1326// Tests that watchers work with a node setup.
1327TEST_P(AbstractEventLoopTest, NodeWatcher) {
1328 EnableNodes("me");
1329
1330 auto loop1 = Make();
1331 auto loop2 = Make();
1332 loop1->MakeWatcher("/test", [](const TestMessage &) {});
Tyler Chatow67ddb032020-01-12 14:30:04 -08001333 loop2->MakeRawWatcher(
1334 configuration::GetChannel(configuration(), "/test", "aos.TestMessage", "",
1335 nullptr),
1336 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001337}
1338
1339// Tests that fetcher work with a node setup.
1340TEST_P(AbstractEventLoopTest, NodeFetcher) {
1341 EnableNodes("me");
1342 auto loop1 = Make();
1343
1344 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
Tyler Chatow67ddb032020-01-12 14:30:04 -08001345 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1346 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001347}
1348
1349// Tests that sender work with a node setup.
1350TEST_P(AbstractEventLoopTest, NodeSender) {
1351 EnableNodes("me");
1352 auto loop1 = Make();
1353
1354 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1355}
1356
1357// Tests that watchers fail when created on the wrong node.
1358TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
1359 EnableNodes("them");
1360
1361 auto loop1 = Make();
1362 auto loop2 = Make();
1363 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
1364 "node");
1365 EXPECT_DEATH(
1366 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001367 loop2->MakeRawWatcher(
1368 configuration::GetChannel(configuration(), "/test",
1369 "aos.TestMessage", "", nullptr),
1370 [](const Context &, const void *) {});
Austin Schuh217a9782019-12-21 23:02:50 -08001371 },
1372 "node");
1373}
1374
1375// Tests that fetchers fail when created on the wrong node.
1376TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
1377 EnableNodes("them");
1378 auto loop1 = Make();
1379
1380 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
1381 "node");
1382 EXPECT_DEATH(
1383 {
Tyler Chatow67ddb032020-01-12 14:30:04 -08001384 auto raw_fetcher = loop1->MakeRawFetcher(configuration::GetChannel(
1385 configuration(), "/test", "aos.TestMessage", "", nullptr));
Austin Schuh217a9782019-12-21 23:02:50 -08001386 },
1387 "node");
1388}
1389
1390// Tests that senders fail when created on the wrong node.
1391TEST_P(AbstractEventLoopDeathTest, NodeSender) {
1392 EnableNodes("them");
1393 auto loop1 = Make();
1394
1395 EXPECT_DEATH(
1396 {
1397 aos::Sender<TestMessage> sender =
1398 loop1->MakeSender<TestMessage>("/test");
1399 },
1400 "node");
1401
1402 // Note: Creating raw senders is always supported. Right now, this lets us
1403 // use them to create message_gateway.
1404}
1405
Parker Schuhe4a70d62017-12-27 20:10:20 -08001406} // namespace testing
1407} // namespace aos