blob: b72a8e25f565707f08cdd646f5b7abf3dee036ef [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 "glog/logging.h"
Austin Schuh3578a2e2019-05-25 18:17:59 -07006#include "gmock/gmock.h"
7#include "gtest/gtest.h"
8
Alex Perrycb7da4b2019-08-28 19:35:56 -07009#include "aos/events/test_message_generated.h"
Austin Schuh54cf95f2019-11-29 13:14:18 -080010#include "aos/flatbuffer_merge.h"
11#include "glog/logging.h"
Austin Schuh9fe68f72019-08-10 19:32:03 -070012
Parker Schuhe4a70d62017-12-27 20:10:20 -080013namespace aos {
14namespace testing {
Austin Schuh52d325c2019-06-23 18:59:06 -070015namespace {
16namespace chrono = ::std::chrono;
17} // namespace
Parker Schuhe4a70d62017-12-27 20:10:20 -080018
Austin Schuh6b6dfa52019-06-12 20:16:20 -070019// Tests that watcher can receive messages from a sender.
Parker Schuhe4a70d62017-12-27 20:10:20 -080020// Also tests that OnRun() works.
21TEST_P(AbstractEventLoopTest, Basic) {
22 auto loop1 = Make();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070023 auto loop2 = MakePrimary();
24
Alex Perrycb7da4b2019-08-28 19:35:56 -070025 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
Austin Schuh6b6dfa52019-06-12 20:16:20 -070026
27 bool happened = false;
28
29 loop2->OnRun([&]() {
30 happened = true;
31
Alex Perrycb7da4b2019-08-28 19:35:56 -070032 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
33 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
34 builder.add_value(200);
35 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -070036 });
37
38 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070039 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -070040 this->Exit();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070041 });
42
43 EXPECT_FALSE(happened);
44 Run();
45 EXPECT_TRUE(happened);
46}
47
Brian Silverman0fc69932020-01-24 21:54:02 -080048// Tests that watcher can receive messages from two senders.
49// Also tests that OnRun() works.
50TEST_P(AbstractEventLoopTest, BasicTwoSenders) {
51 auto loop1 = Make();
52 auto loop2 = MakePrimary();
53
54 aos::Sender<TestMessage> sender1 = loop1->MakeSender<TestMessage>("/test");
55 aos::Sender<TestMessage> sender2 = loop1->MakeSender<TestMessage>("/test");
56
57 bool happened = false;
58
59 loop2->OnRun([&]() {
60 happened = true;
61
62 {
63 aos::Sender<TestMessage>::Builder msg = sender1.MakeBuilder();
64 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
65 builder.add_value(200);
66 ASSERT_TRUE(msg.Send(builder.Finish()));
67 }
68 {
69 aos::Sender<TestMessage>::Builder msg = sender2.MakeBuilder();
70 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
71 builder.add_value(200);
72 ASSERT_TRUE(msg.Send(builder.Finish()));
73 }
74 });
75
76 int messages_received = 0;
77 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
78 EXPECT_EQ(message.value(), 200);
79 this->Exit();
80 ++messages_received;
81 });
82
83 EXPECT_FALSE(happened);
84 Run();
85 EXPECT_TRUE(happened);
86 EXPECT_EQ(messages_received, 2);
87}
88
Austin Schuh6b6dfa52019-06-12 20:16:20 -070089// Tests that a fetcher can fetch from a sender.
90// Also tests that OnRun() works.
91TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
92 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -080093 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -070094 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -080095
96 auto sender = loop1->MakeSender<TestMessage>("/test");
97
98 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
99
Austin Schuhbbce72d2019-05-26 15:11:46 -0700100 EXPECT_FALSE(fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -0800101 EXPECT_EQ(fetcher.get(), nullptr);
102
Austin Schuhad154822019-12-27 15:45:13 -0800103 EXPECT_EQ(fetcher.context().monotonic_event_time, monotonic_clock::min_time);
104 EXPECT_EQ(fetcher.context().monotonic_remote_time, monotonic_clock::min_time);
105 EXPECT_EQ(fetcher.context().realtime_event_time, realtime_clock::min_time);
106 EXPECT_EQ(fetcher.context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800107 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
108 EXPECT_EQ(fetcher.context().size, 0u);
109 EXPECT_EQ(fetcher.context().data, nullptr);
Austin Schuhbbce72d2019-05-26 15:11:46 -0700110
Alex Perrycb7da4b2019-08-28 19:35:56 -0700111 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
112 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
113 builder.add_value(200);
114 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700115
116 EXPECT_TRUE(fetcher.Fetch());
117 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700118 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -0800119
120 const chrono::milliseconds kEpsilon(100);
121
Austin Schuhad154822019-12-27 15:45:13 -0800122 const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
123 const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
124 EXPECT_EQ(fetcher.context().monotonic_event_time,
125 fetcher.context().monotonic_remote_time);
126 EXPECT_EQ(fetcher.context().realtime_event_time,
127 fetcher.context().realtime_remote_time);
128
129 EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
130 EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
131 EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
132 EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800133 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
134 EXPECT_EQ(fetcher.context().size, 20u);
135 EXPECT_NE(fetcher.context().data, nullptr);
Parker Schuhe4a70d62017-12-27 20:10:20 -0800136}
137
Austin Schuh3578a2e2019-05-25 18:17:59 -0700138// Tests that watcher will receive all messages sent if they are sent after
139// initialization and before running.
140TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
141 auto loop1 = Make();
142 auto loop2 = MakePrimary();
143
144 auto sender = loop1->MakeSender<TestMessage>("/test");
145
146 ::std::vector<int> values;
147
148 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700149 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700150 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700151 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700152 }
153 });
154
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700155 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -0700156 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700157 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
158 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
159 builder.add_value(199);
160 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700161 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700162
163 loop2->OnRun([&]() {
164 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700165 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
166 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
167 builder.add_value(200);
168 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700169 }
170 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700171 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
172 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
173 builder.add_value(201);
174 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700175 }
176 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700177
178 Run();
179
180 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
181}
182
183// Tests that watcher will not receive messages sent before the watcher is
184// created.
185TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
186 auto loop1 = Make();
187 auto loop2 = MakePrimary();
188
189 auto sender = loop1->MakeSender<TestMessage>("/test");
190
191 ::std::vector<int> values;
192
193 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700194 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
195 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
196 builder.add_value(200);
197 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700198 }
199 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700200 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
201 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
202 builder.add_value(201);
203 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700204 }
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 });
209
210 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700211 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700212 loop2->OnRun([&test_timer, &loop2]() {
213 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
214 });
215
216 Run();
217 EXPECT_EQ(0, values.size());
218}
219
Austin Schuhbbce72d2019-05-26 15:11:46 -0700220// Tests that FetchNext gets all the messages sent after it is constructed.
221TEST_P(AbstractEventLoopTest, FetchNext) {
222 auto loop1 = Make();
223 auto loop2 = MakePrimary();
224
225 auto sender = loop1->MakeSender<TestMessage>("/test");
226 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
227
228 ::std::vector<int> values;
229
230 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700231 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
232 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
233 builder.add_value(200);
234 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700235 }
236 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700237 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
238 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
239 builder.add_value(201);
240 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700241 }
242
243 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700244 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700245 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700246 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700247 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700248 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700249 });
250
251 loop2->OnRun([&test_timer, &loop2]() {
252 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
253 });
254
255 Run();
256 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
257}
258
259// Tests that FetchNext gets no messages sent before it is constructed.
260TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
261 auto loop1 = Make();
262 auto loop2 = MakePrimary();
263
264 auto sender = loop1->MakeSender<TestMessage>("/test");
265
266 ::std::vector<int> values;
267
268 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700269 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
270 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
271 builder.add_value(200);
272 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700273 }
274 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700275 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
276 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
277 builder.add_value(201);
278 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700279 }
280
281 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
282
283 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700284 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700285 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700286 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700287 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700288 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700289 });
290
291 loop2->OnRun([&test_timer, &loop2]() {
292 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
293 });
294
295 Run();
296 EXPECT_THAT(0, values.size());
297}
298
299// Tests that Fetch returns the last message created before the loop was
300// started.
301TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
302 auto loop1 = Make();
303 auto loop2 = MakePrimary();
304
305 auto sender = loop1->MakeSender<TestMessage>("/test");
306
307 ::std::vector<int> values;
308
309 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700310 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
311 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
312 builder.add_value(200);
313 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700314 }
315 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700316 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
317 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
318 builder.add_value(201);
319 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700320 }
321
322 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
323
324 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700325 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700326 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700327 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700328 }
329 // Do it again to make sure we don't double fetch.
330 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700331 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700332 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700333 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700334 });
335
336 loop2->OnRun([&test_timer, &loop2]() {
337 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
338 });
339
340 Run();
341 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
342}
343
344// Tests that Fetch and FetchNext interleave as expected.
345TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
346 auto loop1 = Make();
347 auto loop2 = MakePrimary();
348
349 auto sender = loop1->MakeSender<TestMessage>("/test");
350
351 ::std::vector<int> values;
352
353 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700354 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
355 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
356 builder.add_value(200);
357 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700358 }
359 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700360 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
361 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
362 builder.add_value(201);
363 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700364 }
365
366 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
367
368 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700369 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700370 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700371 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700372 }
373
374 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700375 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
376 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
377 builder.add_value(202);
378 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700379 }
380 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700381 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
382 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
383 builder.add_value(203);
384 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700385 }
386 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700387 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
388 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
389 builder.add_value(204);
390 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700391 }
392
393 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700394 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700395 }
396
397 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700398 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700399 }
400
Austin Schuh9fe68f72019-08-10 19:32:03 -0700401 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700402 });
403
404 loop2->OnRun([&test_timer, &loop2]() {
405 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
406 });
407
408 Run();
409 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
410}
411
Austin Schuh3115a202019-05-27 21:02:14 -0700412
413// Tests that FetchNext behaves correctly when we get two messages in the queue
414// but don't consume the first until after the second has been sent.
415TEST_P(AbstractEventLoopTest, FetchNextTest) {
416
417 auto send_loop = Make();
418 auto fetch_loop = Make();
419 auto sender = send_loop->MakeSender<TestMessage>("/test");
420 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
421
422 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700423 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
424 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
425 builder.add_value(100);
426 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700427 }
428
429 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700430 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
431 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
432 builder.add_value(200);
433 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700434 }
435
436 ASSERT_TRUE(fetcher.FetchNext());
437 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700438 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700439
440 ASSERT_TRUE(fetcher.FetchNext());
441 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700442 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700443
444 // When we run off the end of the queue, expect to still have the old message:
445 ASSERT_FALSE(fetcher.FetchNext());
446 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700447 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700448}
449
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800450// Verify that making a fetcher and watcher for "/test" succeeds.
451TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800452 auto loop = Make();
453 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800454 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800455}
456
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800457// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800458TEST_P(AbstractEventLoopTest, TwoFetcher) {
459 auto loop = Make();
460 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800461 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800462}
463
Alex Perrycb7da4b2019-08-28 19:35:56 -0700464// Verify that registering a watcher for an invalid channel name dies.
465TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
466 auto loop = Make();
467 EXPECT_DEATH(
468 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
469 "/test/invalid");
470}
471
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800472// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700473TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800474 auto loop = Make();
475 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800476 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
477 "/test");
478}
479
Austin Schuh3115a202019-05-27 21:02:14 -0700480// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700481TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700482 auto loop = MakePrimary();
483 // Confirm that runtime priority calls work when not realtime.
484 loop->SetRuntimeRealtimePriority(5);
485
486 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
487
488 EXPECT_DEATH(Run(), "realtime");
489}
490
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800491// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700492TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800493 auto loop = Make();
494 auto sender = loop->MakeSender<TestMessage>("/test");
495 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
496 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800497}
498
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700499// Verify that we can't create a sender inside OnRun.
500TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
501 auto loop1 = MakePrimary();
502
503 loop1->OnRun(
504 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
505
506 EXPECT_DEATH(Run(), "running");
507}
508
509// Verify that we can't create a watcher inside OnRun.
510TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
511 auto loop1 = MakePrimary();
512
513 loop1->OnRun(
514 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
515
516 EXPECT_DEATH(Run(), "running");
517}
518
Parker Schuhe4a70d62017-12-27 20:10:20 -0800519// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800520TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
521 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700522 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800523
Austin Schuh3578a2e2019-05-25 18:17:59 -0700524 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
525 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700526 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700527 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700528 });
529
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800530 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700531
532 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700533 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
534 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
535 builder.add_value(200);
536 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700537 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800538
Austin Schuh44019f92019-05-19 19:58:27 -0700539 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800540}
541
Neil Balch229001a2018-01-07 18:22:52 -0800542// Verify that timer intervals and duration function properly.
543TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800544 // Force a slower rate so we are guarenteed to have reports for our timer.
545 FLAGS_timing_report_ms = 2000;
546
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800547 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800548
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800549 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800550 auto loop2 = Make();
551
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800552 ::std::vector<::aos::monotonic_clock::time_point> times;
553 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
554
Austin Schuh39788ff2019-12-01 18:22:57 -0800555 Fetcher<timing::Report> report_fetcher =
556 loop2->MakeFetcher<timing::Report>("/aos");
557 EXPECT_FALSE(report_fetcher.Fetch());
558
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800559 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
560 times.push_back(loop->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800561 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
562 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
563 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800564 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
565 EXPECT_EQ(loop->context().size, 0u);
566 EXPECT_EQ(loop->context().data, nullptr);
567
Austin Schuhad154822019-12-27 15:45:13 -0800568 expected_times.push_back(loop->context().monotonic_event_time);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800569 if (times.size() == kCount) {
570 this->Exit();
571 }
Neil Balch229001a2018-01-07 18:22:52 -0800572 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800573 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800574
Austin Schuh39788ff2019-12-01 18:22:57 -0800575 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700576 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800577 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
578
Austin Schuh44019f92019-05-19 19:58:27 -0700579 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800580
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800581 // Confirm that we got both the right number of samples, and it's odd.
582 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
583 EXPECT_EQ(times.size(), expected_times.size());
584 EXPECT_EQ((times.size() % 2), 1);
585
586 // Grab the middle sample.
587 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
588
589 // Add up all the delays of all the times.
590 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
591 for (const ::aos::monotonic_clock::time_point time : times) {
592 sum += time - average_time;
593 }
594
595 // Average and add to the middle to find the average time.
596 sum /= times.size();
597 average_time += sum;
598
599 // Compute the offset from the average and the expected average. It
600 // should be pretty close to 0.
601 const ::aos::monotonic_clock::duration remainder =
602 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
603
604 const chrono::milliseconds kEpsilon(100);
605 EXPECT_LT(remainder, +kEpsilon);
606 EXPECT_GT(remainder, -kEpsilon);
607
608 // Make sure that the average duration is close to 1 second.
609 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
610 times.front())
611 .count() /
612 static_cast<double>(times.size() - 1),
613 1.0, 0.1);
614
615 // Confirm that the ideal wakeup times increment correctly.
616 for (size_t i = 1; i < expected_times.size(); ++i) {
617 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
618 }
619
620 for (size_t i = 0; i < expected_times.size(); ++i) {
621 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
622 chrono::seconds(0));
623 }
624
625 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
626 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800627
628 // And, since we are here, check that the timing report makes sense.
629 // Start by looking for our event loop's timing.
630 FlatbufferDetachedBuffer<timing::Report> report =
631 FlatbufferDetachedBuffer<timing::Report>::Empty();
632 while (report_fetcher.FetchNext()) {
633 if (report_fetcher->name()->string_view() == "primary") {
634 report = CopyFlatBuffer(report_fetcher.get());
635 }
636 }
637
638 // Confirm that we have the right number of reports, and the contents are
639 // sane.
640 VLOG(1) << FlatbufferToJson(report, true);
641
642 EXPECT_EQ(report.message().name()->string_view(), "primary");
643
644 ASSERT_NE(report.message().senders(), nullptr);
645 EXPECT_EQ(report.message().senders()->size(), 1);
646
647 ASSERT_NE(report.message().timers(), nullptr);
648 EXPECT_EQ(report.message().timers()->size(), 2);
649
650 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
651 "Test loop");
652 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
653
654 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
655 "timing_reports");
656 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
657
658 // Make sure there is a single phased loop report with our report in it.
659 ASSERT_EQ(report.message().phased_loops(), nullptr);
Neil Balch229001a2018-01-07 18:22:52 -0800660}
661
662// Verify that we can change a timer's parameters during execution.
663TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700664 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800665 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
666
667 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
668 iteration_list.push_back(loop->monotonic_now());
669 });
670
671 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
672 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
673 });
674
Neil Balch229001a2018-01-07 18:22:52 -0800675 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
676 modifier_timer->Setup(loop->monotonic_now() +
677 ::std::chrono::milliseconds(45));
678 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700679 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800680
681 EXPECT_EQ(iteration_list.size(), 7);
682}
683
684// Verify that we can disable a timer during execution.
685TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700686 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800687 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
688
689 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
690 iteration_list.push_back(loop->monotonic_now());
691 });
692
693 auto ender_timer = loop->AddTimer([&test_timer]() {
694 test_timer->Disable();
695 });
696
697 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
698 ender_timer->Setup(loop->monotonic_now() +
699 ::std::chrono::milliseconds(45));
700 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700701 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800702
703 EXPECT_EQ(iteration_list.size(), 3);
704}
Austin Schuh7267c532019-05-19 19:55:53 -0700705
Austin Schuh54cf95f2019-11-29 13:14:18 -0800706// Verifies that the event loop implementations detect when Channel is not a
707// pointer into confguration()
708TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
709 auto loop = MakePrimary();
710
Austin Schuh39788ff2019-12-01 18:22:57 -0800711 const Channel *channel = loop->configuration()->channels()->Get(1);
Austin Schuh54cf95f2019-11-29 13:14:18 -0800712
713 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
714
715 EXPECT_DEATH(
716 { loop->MakeRawSender(&channel_copy.message()); },
717 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
718
719 EXPECT_DEATH(
720 { loop->MakeRawFetcher(&channel_copy.message()); },
721 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
722
723 EXPECT_DEATH(
724 {
725 loop->MakeRawWatcher(&channel_copy.message(),
726 [](const Context, const void *) {});
727 },
728 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
729}
730
Austin Schuh7267c532019-05-19 19:55:53 -0700731// Verify that the send time on a message is roughly right.
732TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700733 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700734 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -0800735 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -0700736 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
737
738 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700739 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
740 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
741 builder.add_value(200);
742 ASSERT_TRUE(msg.Send(builder.Finish()));
743 });
744
Austin Schuhad154822019-12-27 15:45:13 -0800745 bool triggered = false;
746 loop1->MakeWatcher("/test", [&triggered, &loop1](const TestMessage &msg) {
747 // Confirm that the data pointer makes sense from a watcher, and all the
748 // timestamps look right.
749 EXPECT_GT(&msg, loop1->context().data);
750 EXPECT_EQ(loop1->context().monotonic_remote_time,
751 loop1->context().monotonic_event_time);
752 EXPECT_EQ(loop1->context().realtime_remote_time,
753 loop1->context().realtime_event_time);
754
755 const aos::monotonic_clock::time_point monotonic_now =
756 loop1->monotonic_now();
757 const aos::realtime_clock::time_point realtime_now =
758 loop1->realtime_now();
759
760 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
761 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
762 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
763 monotonic_now);
764 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
765 realtime_now);
766
Alex Perrycb7da4b2019-08-28 19:35:56 -0700767 EXPECT_LT(&msg, reinterpret_cast<void *>(
Austin Schuhad154822019-12-27 15:45:13 -0800768 reinterpret_cast<char *>(loop1->context().data) +
769 loop1->context().size));
770 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -0700771 });
772
773 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
774
775 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700776 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700777
Austin Schuhad154822019-12-27 15:45:13 -0800778 EXPECT_TRUE(triggered);
779
Austin Schuh7267c532019-05-19 19:55:53 -0700780 EXPECT_TRUE(fetcher.Fetch());
781
Alex Perrycb7da4b2019-08-28 19:35:56 -0700782 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -0800783 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700784 (loop1->monotonic_now() - ::std::chrono::seconds(1));
785 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -0800786 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700787 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -0700788
Austin Schuhad154822019-12-27 15:45:13 -0800789 EXPECT_EQ(fetcher.context().realtime_event_time,
790 fetcher.context().realtime_remote_time);
791 EXPECT_EQ(fetcher.context().monotonic_event_time,
792 fetcher.context().monotonic_remote_time);
793
Alex Perrycb7da4b2019-08-28 19:35:56 -0700794 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
795 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800796 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -0700797 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700798 // Confirm that the data pointer makes sense.
799 EXPECT_GT(fetcher.get(), fetcher.context().data);
800 EXPECT_LT(fetcher.get(),
801 reinterpret_cast<void *>(
802 reinterpret_cast<char *>(fetcher.context().data) +
803 fetcher.context().size));
804 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
805 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800806 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -0700807 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700808
809 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
810 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800811 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -0700812 << " expected " << loop1->realtime_now().time_since_epoch().count();
813 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
814 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800815 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -0700816 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -0700817}
818
Austin Schuh52d325c2019-06-23 18:59:06 -0700819// Tests that a couple phased loops run in a row result in the correct offset
820// and period.
821TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800822 // Force a slower rate so we are guarenteed to have reports for our phased
823 // loop.
824 FLAGS_timing_report_ms = 2000;
825
Austin Schuh52d325c2019-06-23 18:59:06 -0700826 const chrono::milliseconds kOffset = chrono::milliseconds(400);
827 const int kCount = 5;
828
829 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800830 auto loop2 = Make();
831
832 Fetcher<timing::Report> report_fetcher =
833 loop2->MakeFetcher<timing::Report>("/aos");
834 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -0700835
836 // Collect up a couple of samples.
837 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800838 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -0700839
840 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -0800841 loop1
842 ->AddPhasedLoop(
843 [&times, &expected_times, &loop1, this](int count) {
844 EXPECT_EQ(count, 1);
845 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800846 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800847
Austin Schuhad154822019-12-27 15:45:13 -0800848 EXPECT_EQ(loop1->context().monotonic_remote_time,
849 monotonic_clock::min_time);
850 EXPECT_EQ(loop1->context().realtime_event_time,
851 realtime_clock::min_time);
852 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -0800853 realtime_clock::min_time);
854 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
855 EXPECT_EQ(loop1->context().size, 0u);
856 EXPECT_EQ(loop1->context().data, nullptr);
857
858 if (times.size() == kCount) {
859 LOG(INFO) << "Exiting";
860 this->Exit();
861 }
862 },
863 chrono::seconds(1), kOffset)
864 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -0700865
866 // Add a delay to make sure that delay during startup doesn't result in a
867 // "missed cycle".
868 SleepFor(chrono::seconds(2));
869
870 Run();
871
872 // Confirm that we got both the right number of samples, and it's odd.
873 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800874 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -0700875 EXPECT_EQ((times.size() % 2), 1);
876
877 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800878 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -0700879
880 // Add up all the delays of all the times.
881 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
882 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800883 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -0700884 }
885
886 // Average and add to the middle to find the average time.
887 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800888 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -0700889
890 // Compute the offset from the start of the second of the average time. This
891 // should be pretty close to the offset.
892 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800893 average_time.time_since_epoch() -
894 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -0700895
896 const chrono::milliseconds kEpsilon(100);
897 EXPECT_LT(remainder, kOffset + kEpsilon);
898 EXPECT_GT(remainder, kOffset - kEpsilon);
899
900 // Make sure that the average duration is close to 1 second.
901 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
902 times.front())
903 .count() /
904 static_cast<double>(times.size() - 1),
905 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800906
907 // Confirm that the ideal wakeup times increment correctly.
908 for (size_t i = 1; i < expected_times.size(); ++i) {
909 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
910 }
911
912 for (size_t i = 0; i < expected_times.size(); ++i) {
913 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
914 kOffset);
915 }
916
917 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
918 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800919
920 // And, since we are here, check that the timing report makes sense.
921 // Start by looking for our event loop's timing.
922 FlatbufferDetachedBuffer<timing::Report> report =
923 FlatbufferDetachedBuffer<timing::Report>::Empty();
924 while (report_fetcher.FetchNext()) {
925 if (report_fetcher->name()->string_view() == "primary") {
926 report = CopyFlatBuffer(report_fetcher.get());
927 }
928 }
929
930 VLOG(1) << FlatbufferToJson(report, true);
931
932 EXPECT_EQ(report.message().name()->string_view(), "primary");
933
934 ASSERT_NE(report.message().senders(), nullptr);
935 EXPECT_EQ(report.message().senders()->size(), 1);
936
937 ASSERT_NE(report.message().timers(), nullptr);
938 EXPECT_EQ(report.message().timers()->size(), 1);
939
940 // Make sure there is a single phased loop report with our report in it.
941 ASSERT_NE(report.message().phased_loops(), nullptr);
942 ASSERT_EQ(report.message().phased_loops()->size(), 1);
943 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
944 "Test loop");
945 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
946}
947
948// Tests that senders count correctly in the timing report.
949TEST_P(AbstractEventLoopTest, SenderTimingReport) {
950 FLAGS_timing_report_ms = 1000;
951 auto loop1 = MakePrimary();
952
953 auto loop2 = Make("watcher_loop");
954 loop2->MakeWatcher("/test", [](const TestMessage &) {});
955
956 auto loop3 = Make();
957
958 Fetcher<timing::Report> report_fetcher =
959 loop3->MakeFetcher<timing::Report>("/aos");
960 EXPECT_FALSE(report_fetcher.Fetch());
961
962 auto sender = loop1->MakeSender<TestMessage>("/test");
963
964 // Add a timer to actually quit.
965 auto test_timer = loop1->AddTimer([&sender]() {
966 for (int i = 0; i < 10; ++i) {
967 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
968 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
969 builder.add_value(200 + i);
970 ASSERT_TRUE(msg.Send(builder.Finish()));
971 }
972 });
973
974 // Quit after 1 timing report, mid way through the next cycle.
975 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
976
977 loop1->OnRun([&test_timer, &loop1]() {
978 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
979 });
980
981 Run();
982
983 // And, since we are here, check that the timing report makes sense.
984 // Start by looking for our event loop's timing.
985 FlatbufferDetachedBuffer<timing::Report> primary_report =
986 FlatbufferDetachedBuffer<timing::Report>::Empty();
987 while (report_fetcher.FetchNext()) {
988 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
989 if (report_fetcher->name()->string_view() == "primary") {
990 primary_report = CopyFlatBuffer(report_fetcher.get());
991 }
992 }
993
994 LOG(INFO) << FlatbufferToJson(primary_report, true);
995
996 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
997
998 ASSERT_NE(primary_report.message().senders(), nullptr);
999 EXPECT_EQ(primary_report.message().senders()->size(), 2);
1000
1001 // Confirm that the sender looks sane.
1002 EXPECT_EQ(
1003 loop1->configuration()
1004 ->channels()
1005 ->Get(primary_report.message().senders()->Get(0)->channel_index())
1006 ->name()
1007 ->string_view(),
1008 "/test");
1009 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
1010
1011 // Confirm that the timing primary_report sender looks sane.
1012 EXPECT_EQ(
1013 loop1->configuration()
1014 ->channels()
1015 ->Get(primary_report.message().senders()->Get(1)->channel_index())
1016 ->name()
1017 ->string_view(),
1018 "/aos");
1019 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
1020
1021 ASSERT_NE(primary_report.message().timers(), nullptr);
1022 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1023
1024 // Make sure there are no phased loops or watchers.
1025 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1026 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1027}
1028
1029// Tests that senders count correctly in the timing report.
1030TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
1031 FLAGS_timing_report_ms = 1000;
1032 auto loop1 = MakePrimary();
1033 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1034
1035 auto loop2 = Make("sender_loop");
1036
1037 auto loop3 = Make();
1038
1039 Fetcher<timing::Report> report_fetcher =
1040 loop3->MakeFetcher<timing::Report>("/aos");
1041 EXPECT_FALSE(report_fetcher.Fetch());
1042
1043 auto sender = loop2->MakeSender<TestMessage>("/test");
1044
1045 // Add a timer to actually quit.
1046 auto test_timer = loop1->AddTimer([&sender]() {
1047 for (int i = 0; i < 10; ++i) {
1048 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1049 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1050 builder.add_value(200 + i);
1051 ASSERT_TRUE(msg.Send(builder.Finish()));
1052 }
1053 });
1054
1055 // Quit after 1 timing report, mid way through the next cycle.
1056 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1057
1058 loop1->OnRun([&test_timer, &loop1]() {
1059 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1060 });
1061
1062 Run();
1063
1064 // And, since we are here, check that the timing report makes sense.
1065 // Start by looking for our event loop's timing.
1066 FlatbufferDetachedBuffer<timing::Report> primary_report =
1067 FlatbufferDetachedBuffer<timing::Report>::Empty();
1068 while (report_fetcher.FetchNext()) {
1069 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1070 if (report_fetcher->name()->string_view() == "primary") {
1071 primary_report = CopyFlatBuffer(report_fetcher.get());
1072 }
1073 }
1074
1075 // Check the watcher report.
1076 VLOG(1) << FlatbufferToJson(primary_report, true);
1077
1078 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1079
1080 // Just the timing report timer.
1081 ASSERT_NE(primary_report.message().timers(), nullptr);
1082 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1083
1084 // No phased loops
1085 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1086
1087 ASSERT_NE(primary_report.message().watchers(), nullptr);
1088 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1089 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1090}
1091
1092// Tests that fetchers count correctly in the timing report.
1093TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1094 FLAGS_timing_report_ms = 1000;
1095 auto loop1 = MakePrimary();
1096 auto loop2 = Make("sender_loop");
1097
1098 auto loop3 = Make();
1099
1100 Fetcher<timing::Report> report_fetcher =
1101 loop3->MakeFetcher<timing::Report>("/aos");
1102 EXPECT_FALSE(report_fetcher.Fetch());
1103
1104 auto sender = loop2->MakeSender<TestMessage>("/test");
1105 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1106 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1107 fetcher1.Fetch();
1108 fetcher2.Fetch();
1109
1110 // Add a timer to actually quit.
1111 auto test_timer = loop1->AddTimer([&sender]() {
1112 for (int i = 0; i < 10; ++i) {
1113 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1114 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1115 builder.add_value(200 + i);
1116 ASSERT_TRUE(msg.Send(builder.Finish()));
1117 }
1118 });
1119
1120 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1121 fetcher1.Fetch();
1122 while (fetcher2.FetchNext()) {
1123 }
1124 });
1125
1126 // Quit after 1 timing report, mid way through the next cycle.
1127 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1128
1129 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1130 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1131 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1132 });
1133
1134 Run();
1135
1136 // And, since we are here, check that the timing report makes sense.
1137 // Start by looking for our event loop's timing.
1138 FlatbufferDetachedBuffer<timing::Report> primary_report =
1139 FlatbufferDetachedBuffer<timing::Report>::Empty();
1140 while (report_fetcher.FetchNext()) {
1141 if (report_fetcher->name()->string_view() == "primary") {
1142 primary_report = CopyFlatBuffer(report_fetcher.get());
1143 }
1144 }
1145
1146 VLOG(1) << FlatbufferToJson(primary_report, true);
1147
1148 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1149
1150 ASSERT_NE(primary_report.message().senders(), nullptr);
1151 EXPECT_EQ(primary_report.message().senders()->size(), 1);
1152
1153 ASSERT_NE(primary_report.message().timers(), nullptr);
1154 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1155
1156 // Make sure there are no phased loops or watchers.
1157 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1158 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1159
1160 // Now look at the fetchrs.
1161 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1162 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1163
1164 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1165 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1166 0.1);
1167 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(),
1168 0.1);
1169 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(),
1170 0.1);
1171 EXPECT_EQ(primary_report.message()
1172 .fetchers()
1173 ->Get(0)
1174 ->latency()
1175 ->standard_deviation(),
1176 0.0);
1177
1178 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001179}
1180
Austin Schuh67420a42019-12-21 21:55:04 -08001181// Tests that a raw watcher and raw fetcher can receive messages from a raw
1182// sender without messing up offsets.
1183TEST_P(AbstractEventLoopTest, RawBasic) {
1184 auto loop1 = Make();
1185 auto loop2 = MakePrimary();
1186 auto loop3 = Make();
1187
1188 const std::string kData("971 is the best");
1189
1190 std::unique_ptr<aos::RawSender> sender =
1191 loop1->MakeRawSender(loop1->configuration()->channels()->Get(1));
1192
1193 std::unique_ptr<aos::RawFetcher> fetcher =
1194 loop3->MakeRawFetcher(loop3->configuration()->channels()->Get(1));
1195
1196 loop2->OnRun(
1197 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1198
1199 bool happened = false;
1200 loop2->MakeRawWatcher(
1201 loop2->configuration()->channels()->Get(1),
1202 [this, &kData, &fetcher, &happened](const Context &context,
1203 const void *message) {
1204 happened = true;
1205 EXPECT_EQ(std::string_view(kData),
1206 std::string_view(reinterpret_cast<const char *>(message),
1207 context.size));
1208 EXPECT_EQ(std::string_view(kData),
1209 std::string_view(reinterpret_cast<const char *>(context.data),
1210 context.size));
1211
1212 ASSERT_TRUE(fetcher->Fetch());
1213
1214 EXPECT_EQ(std::string_view(kData),
1215 std::string_view(
1216 reinterpret_cast<const char *>(fetcher->context().data),
1217 fetcher->context().size));
1218
1219 this->Exit();
1220 });
1221
1222 EXPECT_FALSE(happened);
1223 Run();
1224 EXPECT_TRUE(happened);
1225}
1226
Austin Schuhad154822019-12-27 15:45:13 -08001227// Tests that a raw watcher and raw fetcher can receive messages from a raw
1228// sender with remote times filled out.
1229TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1230 auto loop1 = Make();
1231 auto loop2 = MakePrimary();
1232 auto loop3 = Make();
1233
1234 const std::string kData("971 is the best");
1235
1236 const aos::monotonic_clock::time_point monotonic_remote_time =
1237 aos::monotonic_clock::time_point(chrono::seconds(1501));
1238 const aos::realtime_clock::time_point realtime_remote_time =
1239 aos::realtime_clock::time_point(chrono::seconds(3132));
1240
1241 std::unique_ptr<aos::RawSender> sender =
1242 loop1->MakeRawSender(loop1->configuration()->channels()->Get(1));
1243
1244 std::unique_ptr<aos::RawFetcher> fetcher =
1245 loop3->MakeRawFetcher(loop3->configuration()->channels()->Get(1));
1246
1247 loop2->OnRun([&]() {
1248 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1249 realtime_remote_time));
1250 });
1251
1252 bool happened = false;
1253 loop2->MakeRawWatcher(
1254 loop2->configuration()->channels()->Get(1),
1255 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1256 const Context &context, const void * /*message*/) {
1257 happened = true;
1258 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1259 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1260
1261 ASSERT_TRUE(fetcher->Fetch());
1262 EXPECT_EQ(monotonic_remote_time,
1263 fetcher->context().monotonic_remote_time);
1264 EXPECT_EQ(realtime_remote_time,
1265 fetcher->context().realtime_remote_time);
1266
1267 this->Exit();
1268 });
1269
1270 EXPECT_FALSE(happened);
1271 Run();
1272 EXPECT_TRUE(happened);
1273}
1274
1275// Tests that a raw sender fills out sent data.
1276TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1277 auto loop1 = MakePrimary();
1278
1279 const std::string kData("971 is the best");
1280
1281 std::unique_ptr<aos::RawSender> sender =
1282 loop1->MakeRawSender(loop1->configuration()->channels()->Get(1));
1283
1284 const aos::monotonic_clock::time_point monotonic_now =
1285 loop1->monotonic_now();
1286 const aos::realtime_clock::time_point realtime_now =
1287 loop1->realtime_now();
1288
1289 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1290
1291 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1292 EXPECT_LE(sender->monotonic_sent_time(),
1293 monotonic_now + chrono::milliseconds(100));
1294 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1295 EXPECT_LE(sender->realtime_sent_time(),
1296 realtime_now + chrono::milliseconds(100));
1297 EXPECT_EQ(sender->sent_queue_index(), 0u);
1298
1299 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1300
1301 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1302 EXPECT_LE(sender->monotonic_sent_time(),
1303 monotonic_now + chrono::milliseconds(100));
1304 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1305 EXPECT_LE(sender->realtime_sent_time(),
1306 realtime_now + chrono::milliseconds(100));
1307 EXPECT_EQ(sender->sent_queue_index(), 1u);
1308}
1309
Austin Schuh217a9782019-12-21 23:02:50 -08001310// Tests that not setting up nodes results in no node.
1311TEST_P(AbstractEventLoopTest, NoNode) {
1312 auto loop1 = Make();
1313 auto loop2 = MakePrimary();
1314
1315 EXPECT_EQ(loop1->node(), nullptr);
1316 EXPECT_EQ(loop2->node(), nullptr);
1317}
1318
1319// Tests that setting up nodes results in node being set.
1320TEST_P(AbstractEventLoopTest, Node) {
1321 EnableNodes("me");
1322
1323 auto loop1 = Make();
1324 auto loop2 = MakePrimary();
1325
1326 EXPECT_NE(loop1->node(), nullptr);
1327 EXPECT_NE(loop2->node(), nullptr);
1328}
1329
1330// Tests that watchers work with a node setup.
1331TEST_P(AbstractEventLoopTest, NodeWatcher) {
1332 EnableNodes("me");
1333
1334 auto loop1 = Make();
1335 auto loop2 = Make();
1336 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1337 loop2->MakeRawWatcher(configuration()->channels()->Get(1),
1338 [](const Context &, const void *) {});
1339}
1340
1341// Tests that fetcher work with a node setup.
1342TEST_P(AbstractEventLoopTest, NodeFetcher) {
1343 EnableNodes("me");
1344 auto loop1 = Make();
1345
1346 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1347 auto raw_fetcher = loop1->MakeRawFetcher(configuration()->channels()->Get(1));
1348}
1349
1350// Tests that sender work with a node setup.
1351TEST_P(AbstractEventLoopTest, NodeSender) {
1352 EnableNodes("me");
1353 auto loop1 = Make();
1354
1355 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1356}
1357
1358// Tests that watchers fail when created on the wrong node.
1359TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
1360 EnableNodes("them");
1361
1362 auto loop1 = Make();
1363 auto loop2 = Make();
1364 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
1365 "node");
1366 EXPECT_DEATH(
1367 {
1368 loop2->MakeRawWatcher(configuration()->channels()->Get(1),
1369 [](const Context &, const void *) {});
1370 },
1371 "node");
1372}
1373
1374// Tests that fetchers fail when created on the wrong node.
1375TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
1376 EnableNodes("them");
1377 auto loop1 = Make();
1378
1379 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
1380 "node");
1381 EXPECT_DEATH(
1382 {
1383 auto raw_fetcher =
1384 loop1->MakeRawFetcher(configuration()->channels()->Get(1));
1385 },
1386 "node");
1387}
1388
1389// Tests that senders fail when created on the wrong node.
1390TEST_P(AbstractEventLoopDeathTest, NodeSender) {
1391 EnableNodes("them");
1392 auto loop1 = Make();
1393
1394 EXPECT_DEATH(
1395 {
1396 aos::Sender<TestMessage> sender =
1397 loop1->MakeSender<TestMessage>("/test");
1398 },
1399 "node");
1400
1401 // Note: Creating raw senders is always supported. Right now, this lets us
1402 // use them to create message_gateway.
1403}
1404
Parker Schuhe4a70d62017-12-27 20:10:20 -08001405} // namespace testing
1406} // namespace aos