blob: c1256f3095e567e21d2488b50779f401eb636824 [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
48// Tests that a fetcher can fetch from a sender.
49// Also tests that OnRun() works.
50TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
51 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -080052 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -070053 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -080054
55 auto sender = loop1->MakeSender<TestMessage>("/test");
56
57 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
58
Austin Schuhbbce72d2019-05-26 15:11:46 -070059 EXPECT_FALSE(fetcher.Fetch());
Austin Schuh39788ff2019-12-01 18:22:57 -080060 EXPECT_EQ(fetcher.get(), nullptr);
61
62 EXPECT_EQ(fetcher.context().monotonic_sent_time, monotonic_clock::min_time);
63 EXPECT_EQ(fetcher.context().realtime_sent_time, realtime_clock::min_time);
64 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
65 EXPECT_EQ(fetcher.context().size, 0u);
66 EXPECT_EQ(fetcher.context().data, nullptr);
Austin Schuhbbce72d2019-05-26 15:11:46 -070067
Alex Perrycb7da4b2019-08-28 19:35:56 -070068 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
69 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
70 builder.add_value(200);
71 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -070072
73 EXPECT_TRUE(fetcher.Fetch());
74 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -070075 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -080076
77 const chrono::milliseconds kEpsilon(100);
78
79 EXPECT_GE(fetcher.context().monotonic_sent_time,
80 loop2->monotonic_now() - kEpsilon);
81 EXPECT_LE(fetcher.context().monotonic_sent_time,
82 loop2->monotonic_now() + kEpsilon);
83 EXPECT_GE(fetcher.context().realtime_sent_time,
84 loop2->realtime_now() - kEpsilon);
85 EXPECT_LE(fetcher.context().realtime_sent_time,
86 loop2->realtime_now() + kEpsilon);
87 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
88 EXPECT_EQ(fetcher.context().size, 20u);
89 EXPECT_NE(fetcher.context().data, nullptr);
Parker Schuhe4a70d62017-12-27 20:10:20 -080090}
91
Austin Schuh3578a2e2019-05-25 18:17:59 -070092// Tests that watcher will receive all messages sent if they are sent after
93// initialization and before running.
94TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
95 auto loop1 = Make();
96 auto loop2 = MakePrimary();
97
98 auto sender = loop1->MakeSender<TestMessage>("/test");
99
100 ::std::vector<int> values;
101
102 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700103 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700104 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700105 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700106 }
107 });
108
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700109 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -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(199);
114 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700115 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700116
117 loop2->OnRun([&]() {
118 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700119 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
120 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
121 builder.add_value(200);
122 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700123 }
124 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700125 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
126 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
127 builder.add_value(201);
128 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700129 }
130 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700131
132 Run();
133
134 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
135}
136
137// Tests that watcher will not receive messages sent before the watcher is
138// created.
139TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
140 auto loop1 = Make();
141 auto loop2 = MakePrimary();
142
143 auto sender = loop1->MakeSender<TestMessage>("/test");
144
145 ::std::vector<int> values;
146
147 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700148 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
149 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
150 builder.add_value(200);
151 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700152 }
153 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700154 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
155 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
156 builder.add_value(201);
157 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700158 }
159
160 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700161 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700162 });
163
164 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700165 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700166 loop2->OnRun([&test_timer, &loop2]() {
167 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
168 });
169
170 Run();
171 EXPECT_EQ(0, values.size());
172}
173
Austin Schuhbbce72d2019-05-26 15:11:46 -0700174// Tests that FetchNext gets all the messages sent after it is constructed.
175TEST_P(AbstractEventLoopTest, FetchNext) {
176 auto loop1 = Make();
177 auto loop2 = MakePrimary();
178
179 auto sender = loop1->MakeSender<TestMessage>("/test");
180 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
181
182 ::std::vector<int> values;
183
184 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700185 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
186 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
187 builder.add_value(200);
188 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700189 }
190 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700191 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
192 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
193 builder.add_value(201);
194 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700195 }
196
197 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700198 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700199 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700200 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700201 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700202 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700203 });
204
205 loop2->OnRun([&test_timer, &loop2]() {
206 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
207 });
208
209 Run();
210 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
211}
212
213// Tests that FetchNext gets no messages sent before it is constructed.
214TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
215 auto loop1 = Make();
216 auto loop2 = MakePrimary();
217
218 auto sender = loop1->MakeSender<TestMessage>("/test");
219
220 ::std::vector<int> values;
221
222 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700223 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
224 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
225 builder.add_value(200);
226 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700227 }
228 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700229 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
230 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
231 builder.add_value(201);
232 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700233 }
234
235 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
236
237 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700238 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700239 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700240 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700241 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700242 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700243 });
244
245 loop2->OnRun([&test_timer, &loop2]() {
246 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
247 });
248
249 Run();
250 EXPECT_THAT(0, values.size());
251}
252
253// Tests that Fetch returns the last message created before the loop was
254// started.
255TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
256 auto loop1 = Make();
257 auto loop2 = MakePrimary();
258
259 auto sender = loop1->MakeSender<TestMessage>("/test");
260
261 ::std::vector<int> values;
262
263 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700264 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
265 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
266 builder.add_value(200);
267 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700268 }
269 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700270 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
271 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
272 builder.add_value(201);
273 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700274 }
275
276 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
277
278 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700279 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700280 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700281 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700282 }
283 // Do it again to make sure we don't double fetch.
284 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700285 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700286 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700287 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700288 });
289
290 loop2->OnRun([&test_timer, &loop2]() {
291 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
292 });
293
294 Run();
295 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
296}
297
298// Tests that Fetch and FetchNext interleave as expected.
299TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
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, &sender, 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
328 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700329 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
330 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
331 builder.add_value(202);
332 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700333 }
334 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700335 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
336 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
337 builder.add_value(203);
338 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700339 }
340 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700341 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
342 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
343 builder.add_value(204);
344 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700345 }
346
347 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700348 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700349 }
350
351 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700352 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700353 }
354
Austin Schuh9fe68f72019-08-10 19:32:03 -0700355 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700356 });
357
358 loop2->OnRun([&test_timer, &loop2]() {
359 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
360 });
361
362 Run();
363 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
364}
365
Austin Schuh3115a202019-05-27 21:02:14 -0700366
367// Tests that FetchNext behaves correctly when we get two messages in the queue
368// but don't consume the first until after the second has been sent.
369TEST_P(AbstractEventLoopTest, FetchNextTest) {
370
371 auto send_loop = Make();
372 auto fetch_loop = Make();
373 auto sender = send_loop->MakeSender<TestMessage>("/test");
374 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
375
376 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700377 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
378 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
379 builder.add_value(100);
380 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700381 }
382
383 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700384 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
385 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
386 builder.add_value(200);
387 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700388 }
389
390 ASSERT_TRUE(fetcher.FetchNext());
391 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700392 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700393
394 ASSERT_TRUE(fetcher.FetchNext());
395 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700396 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700397
398 // When we run off the end of the queue, expect to still have the old message:
399 ASSERT_FALSE(fetcher.FetchNext());
400 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700401 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700402}
403
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800404// Verify that making a fetcher and watcher for "/test" succeeds.
405TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800406 auto loop = Make();
407 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800408 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800409}
410
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800411// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800412TEST_P(AbstractEventLoopTest, TwoFetcher) {
413 auto loop = Make();
414 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800415 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800416}
417
Alex Perrycb7da4b2019-08-28 19:35:56 -0700418// Verify that registering a watcher for an invalid channel name dies.
419TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
420 auto loop = Make();
421 EXPECT_DEATH(
422 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
423 "/test/invalid");
424}
425
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800426// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700427TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800428 auto loop = Make();
429 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800430 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
431 "/test");
432}
433
Austin Schuh3115a202019-05-27 21:02:14 -0700434// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700435TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700436 auto loop = MakePrimary();
437 // Confirm that runtime priority calls work when not realtime.
438 loop->SetRuntimeRealtimePriority(5);
439
440 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
441
442 EXPECT_DEATH(Run(), "realtime");
443}
444
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800445// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700446TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800447 auto loop = Make();
448 auto sender = loop->MakeSender<TestMessage>("/test");
449 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
450 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800451}
452
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700453// Verify that we can't create a sender inside OnRun.
454TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
455 auto loop1 = MakePrimary();
456
457 loop1->OnRun(
458 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
459
460 EXPECT_DEATH(Run(), "running");
461}
462
463// Verify that we can't create a watcher inside OnRun.
464TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
465 auto loop1 = MakePrimary();
466
467 loop1->OnRun(
468 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
469
470 EXPECT_DEATH(Run(), "running");
471}
472
Parker Schuhe4a70d62017-12-27 20:10:20 -0800473// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800474TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
475 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700476 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800477
Austin Schuh3578a2e2019-05-25 18:17:59 -0700478 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
479 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700480 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700481 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700482 });
483
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800484 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700485
486 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700487 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
488 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
489 builder.add_value(200);
490 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700491 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800492
Austin Schuh44019f92019-05-19 19:58:27 -0700493 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800494}
495
Neil Balch229001a2018-01-07 18:22:52 -0800496// Verify that timer intervals and duration function properly.
497TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800498 // Force a slower rate so we are guarenteed to have reports for our timer.
499 FLAGS_timing_report_ms = 2000;
500
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800501 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800502
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800503 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800504 auto loop2 = Make();
505
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800506 ::std::vector<::aos::monotonic_clock::time_point> times;
507 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
508
Austin Schuh39788ff2019-12-01 18:22:57 -0800509 Fetcher<timing::Report> report_fetcher =
510 loop2->MakeFetcher<timing::Report>("/aos");
511 EXPECT_FALSE(report_fetcher.Fetch());
512
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800513 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
514 times.push_back(loop->monotonic_now());
Austin Schuh39788ff2019-12-01 18:22:57 -0800515 EXPECT_EQ(loop->context().realtime_sent_time, realtime_clock::min_time);
516 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
517 EXPECT_EQ(loop->context().size, 0u);
518 EXPECT_EQ(loop->context().data, nullptr);
519
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800520 expected_times.push_back(loop->context().monotonic_sent_time);
521 if (times.size() == kCount) {
522 this->Exit();
523 }
Neil Balch229001a2018-01-07 18:22:52 -0800524 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800525 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800526
Austin Schuh39788ff2019-12-01 18:22:57 -0800527 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700528 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800529 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
530
Austin Schuh44019f92019-05-19 19:58:27 -0700531 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800532
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800533 // Confirm that we got both the right number of samples, and it's odd.
534 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
535 EXPECT_EQ(times.size(), expected_times.size());
536 EXPECT_EQ((times.size() % 2), 1);
537
538 // Grab the middle sample.
539 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
540
541 // Add up all the delays of all the times.
542 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
543 for (const ::aos::monotonic_clock::time_point time : times) {
544 sum += time - average_time;
545 }
546
547 // Average and add to the middle to find the average time.
548 sum /= times.size();
549 average_time += sum;
550
551 // Compute the offset from the average and the expected average. It
552 // should be pretty close to 0.
553 const ::aos::monotonic_clock::duration remainder =
554 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
555
556 const chrono::milliseconds kEpsilon(100);
557 EXPECT_LT(remainder, +kEpsilon);
558 EXPECT_GT(remainder, -kEpsilon);
559
560 // Make sure that the average duration is close to 1 second.
561 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
562 times.front())
563 .count() /
564 static_cast<double>(times.size() - 1),
565 1.0, 0.1);
566
567 // Confirm that the ideal wakeup times increment correctly.
568 for (size_t i = 1; i < expected_times.size(); ++i) {
569 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
570 }
571
572 for (size_t i = 0; i < expected_times.size(); ++i) {
573 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
574 chrono::seconds(0));
575 }
576
577 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
578 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800579
580 // And, since we are here, check that the timing report makes sense.
581 // Start by looking for our event loop's timing.
582 FlatbufferDetachedBuffer<timing::Report> report =
583 FlatbufferDetachedBuffer<timing::Report>::Empty();
584 while (report_fetcher.FetchNext()) {
585 if (report_fetcher->name()->string_view() == "primary") {
586 report = CopyFlatBuffer(report_fetcher.get());
587 }
588 }
589
590 // Confirm that we have the right number of reports, and the contents are
591 // sane.
592 VLOG(1) << FlatbufferToJson(report, true);
593
594 EXPECT_EQ(report.message().name()->string_view(), "primary");
595
596 ASSERT_NE(report.message().senders(), nullptr);
597 EXPECT_EQ(report.message().senders()->size(), 1);
598
599 ASSERT_NE(report.message().timers(), nullptr);
600 EXPECT_EQ(report.message().timers()->size(), 2);
601
602 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
603 "Test loop");
604 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
605
606 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
607 "timing_reports");
608 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
609
610 // Make sure there is a single phased loop report with our report in it.
611 ASSERT_EQ(report.message().phased_loops(), nullptr);
Neil Balch229001a2018-01-07 18:22:52 -0800612}
613
614// Verify that we can change a timer's parameters during execution.
615TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700616 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800617 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
618
619 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
620 iteration_list.push_back(loop->monotonic_now());
621 });
622
623 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
624 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
625 });
626
Neil Balch229001a2018-01-07 18:22:52 -0800627 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
628 modifier_timer->Setup(loop->monotonic_now() +
629 ::std::chrono::milliseconds(45));
630 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700631 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800632
633 EXPECT_EQ(iteration_list.size(), 7);
634}
635
636// Verify that we can disable a timer during execution.
637TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700638 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800639 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
640
641 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
642 iteration_list.push_back(loop->monotonic_now());
643 });
644
645 auto ender_timer = loop->AddTimer([&test_timer]() {
646 test_timer->Disable();
647 });
648
649 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
650 ender_timer->Setup(loop->monotonic_now() +
651 ::std::chrono::milliseconds(45));
652 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700653 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800654
655 EXPECT_EQ(iteration_list.size(), 3);
656}
Austin Schuh7267c532019-05-19 19:55:53 -0700657
Austin Schuh54cf95f2019-11-29 13:14:18 -0800658// Verifies that the event loop implementations detect when Channel is not a
659// pointer into confguration()
660TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
661 auto loop = MakePrimary();
662
Austin Schuh39788ff2019-12-01 18:22:57 -0800663 const Channel *channel = loop->configuration()->channels()->Get(1);
Austin Schuh54cf95f2019-11-29 13:14:18 -0800664
665 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
666
667 EXPECT_DEATH(
668 { loop->MakeRawSender(&channel_copy.message()); },
669 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
670
671 EXPECT_DEATH(
672 { loop->MakeRawFetcher(&channel_copy.message()); },
673 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
674
675 EXPECT_DEATH(
676 {
677 loop->MakeRawWatcher(&channel_copy.message(),
678 [](const Context, const void *) {});
679 },
680 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
681}
682
Austin Schuh7267c532019-05-19 19:55:53 -0700683// Verify that the send time on a message is roughly right.
684TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700685 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700686 auto loop2 = Make();
687 auto sender = loop1->MakeSender<TestMessage>("/test");
688 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
689
690 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700691 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
692 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
693 builder.add_value(200);
694 ASSERT_TRUE(msg.Send(builder.Finish()));
695 });
696
697 loop2->MakeWatcher("/test", [&loop2](const TestMessage &msg) {
698 // Confirm that the data pointer makes sense from a watcher.
699 EXPECT_GT(&msg, loop2->context().data);
700 EXPECT_LT(&msg, reinterpret_cast<void *>(
701 reinterpret_cast<char *>(loop2->context().data) +
702 loop2->context().size));
Austin Schuh7267c532019-05-19 19:55:53 -0700703 });
704
705 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
706
707 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700708 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700709
710 EXPECT_TRUE(fetcher.Fetch());
711
Alex Perrycb7da4b2019-08-28 19:35:56 -0700712 monotonic_clock::duration monotonic_time_offset =
713 fetcher.context().monotonic_sent_time -
714 (loop1->monotonic_now() - ::std::chrono::seconds(1));
715 realtime_clock::duration realtime_time_offset =
716 fetcher.context().realtime_sent_time -
717 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -0700718
Alex Perrycb7da4b2019-08-28 19:35:56 -0700719 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
720 << ": Got "
721 << fetcher.context().monotonic_sent_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -0700722 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700723 // Confirm that the data pointer makes sense.
724 EXPECT_GT(fetcher.get(), fetcher.context().data);
725 EXPECT_LT(fetcher.get(),
726 reinterpret_cast<void *>(
727 reinterpret_cast<char *>(fetcher.context().data) +
728 fetcher.context().size));
729 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
730 << ": Got "
731 << fetcher.context().monotonic_sent_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -0700732 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700733
734 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
735 << ": Got "
736 << fetcher.context().realtime_sent_time.time_since_epoch().count()
737 << " expected " << loop1->realtime_now().time_since_epoch().count();
738 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
739 << ": Got "
740 << fetcher.context().realtime_sent_time.time_since_epoch().count()
741 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -0700742}
743
Austin Schuh52d325c2019-06-23 18:59:06 -0700744// Tests that a couple phased loops run in a row result in the correct offset
745// and period.
746TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800747 // Force a slower rate so we are guarenteed to have reports for our phased
748 // loop.
749 FLAGS_timing_report_ms = 2000;
750
Austin Schuh52d325c2019-06-23 18:59:06 -0700751 const chrono::milliseconds kOffset = chrono::milliseconds(400);
752 const int kCount = 5;
753
754 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800755 auto loop2 = Make();
756
757 Fetcher<timing::Report> report_fetcher =
758 loop2->MakeFetcher<timing::Report>("/aos");
759 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -0700760
761 // Collect up a couple of samples.
762 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800763 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -0700764
765 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -0800766 loop1
767 ->AddPhasedLoop(
768 [&times, &expected_times, &loop1, this](int count) {
769 EXPECT_EQ(count, 1);
770 times.push_back(loop1->monotonic_now());
771 expected_times.push_back(loop1->context().monotonic_sent_time);
772
773 EXPECT_EQ(loop1->context().realtime_sent_time,
774 realtime_clock::min_time);
775 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
776 EXPECT_EQ(loop1->context().size, 0u);
777 EXPECT_EQ(loop1->context().data, nullptr);
778
779 if (times.size() == kCount) {
780 LOG(INFO) << "Exiting";
781 this->Exit();
782 }
783 },
784 chrono::seconds(1), kOffset)
785 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -0700786
787 // Add a delay to make sure that delay during startup doesn't result in a
788 // "missed cycle".
789 SleepFor(chrono::seconds(2));
790
791 Run();
792
793 // Confirm that we got both the right number of samples, and it's odd.
794 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800795 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -0700796 EXPECT_EQ((times.size() % 2), 1);
797
798 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800799 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -0700800
801 // Add up all the delays of all the times.
802 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
803 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800804 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -0700805 }
806
807 // Average and add to the middle to find the average time.
808 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800809 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -0700810
811 // Compute the offset from the start of the second of the average time. This
812 // should be pretty close to the offset.
813 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800814 average_time.time_since_epoch() -
815 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -0700816
817 const chrono::milliseconds kEpsilon(100);
818 EXPECT_LT(remainder, kOffset + kEpsilon);
819 EXPECT_GT(remainder, kOffset - kEpsilon);
820
821 // Make sure that the average duration is close to 1 second.
822 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
823 times.front())
824 .count() /
825 static_cast<double>(times.size() - 1),
826 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800827
828 // Confirm that the ideal wakeup times increment correctly.
829 for (size_t i = 1; i < expected_times.size(); ++i) {
830 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
831 }
832
833 for (size_t i = 0; i < expected_times.size(); ++i) {
834 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
835 kOffset);
836 }
837
838 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
839 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800840
841 // And, since we are here, check that the timing report makes sense.
842 // Start by looking for our event loop's timing.
843 FlatbufferDetachedBuffer<timing::Report> report =
844 FlatbufferDetachedBuffer<timing::Report>::Empty();
845 while (report_fetcher.FetchNext()) {
846 if (report_fetcher->name()->string_view() == "primary") {
847 report = CopyFlatBuffer(report_fetcher.get());
848 }
849 }
850
851 VLOG(1) << FlatbufferToJson(report, true);
852
853 EXPECT_EQ(report.message().name()->string_view(), "primary");
854
855 ASSERT_NE(report.message().senders(), nullptr);
856 EXPECT_EQ(report.message().senders()->size(), 1);
857
858 ASSERT_NE(report.message().timers(), nullptr);
859 EXPECT_EQ(report.message().timers()->size(), 1);
860
861 // Make sure there is a single phased loop report with our report in it.
862 ASSERT_NE(report.message().phased_loops(), nullptr);
863 ASSERT_EQ(report.message().phased_loops()->size(), 1);
864 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
865 "Test loop");
866 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
867}
868
869// Tests that senders count correctly in the timing report.
870TEST_P(AbstractEventLoopTest, SenderTimingReport) {
871 FLAGS_timing_report_ms = 1000;
872 auto loop1 = MakePrimary();
873
874 auto loop2 = Make("watcher_loop");
875 loop2->MakeWatcher("/test", [](const TestMessage &) {});
876
877 auto loop3 = Make();
878
879 Fetcher<timing::Report> report_fetcher =
880 loop3->MakeFetcher<timing::Report>("/aos");
881 EXPECT_FALSE(report_fetcher.Fetch());
882
883 auto sender = loop1->MakeSender<TestMessage>("/test");
884
885 // Add a timer to actually quit.
886 auto test_timer = loop1->AddTimer([&sender]() {
887 for (int i = 0; i < 10; ++i) {
888 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
889 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
890 builder.add_value(200 + i);
891 ASSERT_TRUE(msg.Send(builder.Finish()));
892 }
893 });
894
895 // Quit after 1 timing report, mid way through the next cycle.
896 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
897
898 loop1->OnRun([&test_timer, &loop1]() {
899 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
900 });
901
902 Run();
903
904 // And, since we are here, check that the timing report makes sense.
905 // Start by looking for our event loop's timing.
906 FlatbufferDetachedBuffer<timing::Report> primary_report =
907 FlatbufferDetachedBuffer<timing::Report>::Empty();
908 while (report_fetcher.FetchNext()) {
909 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
910 if (report_fetcher->name()->string_view() == "primary") {
911 primary_report = CopyFlatBuffer(report_fetcher.get());
912 }
913 }
914
915 LOG(INFO) << FlatbufferToJson(primary_report, true);
916
917 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
918
919 ASSERT_NE(primary_report.message().senders(), nullptr);
920 EXPECT_EQ(primary_report.message().senders()->size(), 2);
921
922 // Confirm that the sender looks sane.
923 EXPECT_EQ(
924 loop1->configuration()
925 ->channels()
926 ->Get(primary_report.message().senders()->Get(0)->channel_index())
927 ->name()
928 ->string_view(),
929 "/test");
930 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
931
932 // Confirm that the timing primary_report sender looks sane.
933 EXPECT_EQ(
934 loop1->configuration()
935 ->channels()
936 ->Get(primary_report.message().senders()->Get(1)->channel_index())
937 ->name()
938 ->string_view(),
939 "/aos");
940 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
941
942 ASSERT_NE(primary_report.message().timers(), nullptr);
943 EXPECT_EQ(primary_report.message().timers()->size(), 3);
944
945 // Make sure there are no phased loops or watchers.
946 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
947 ASSERT_EQ(primary_report.message().watchers(), nullptr);
948}
949
950// Tests that senders count correctly in the timing report.
951TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
952 FLAGS_timing_report_ms = 1000;
953 auto loop1 = MakePrimary();
954 loop1->MakeWatcher("/test", [](const TestMessage &) {});
955
956 auto loop2 = Make("sender_loop");
957
958 auto loop3 = Make();
959
960 Fetcher<timing::Report> report_fetcher =
961 loop3->MakeFetcher<timing::Report>("/aos");
962 EXPECT_FALSE(report_fetcher.Fetch());
963
964 auto sender = loop2->MakeSender<TestMessage>("/test");
965
966 // Add a timer to actually quit.
967 auto test_timer = loop1->AddTimer([&sender]() {
968 for (int i = 0; i < 10; ++i) {
969 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
970 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
971 builder.add_value(200 + i);
972 ASSERT_TRUE(msg.Send(builder.Finish()));
973 }
974 });
975
976 // Quit after 1 timing report, mid way through the next cycle.
977 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
978
979 loop1->OnRun([&test_timer, &loop1]() {
980 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
981 });
982
983 Run();
984
985 // And, since we are here, check that the timing report makes sense.
986 // Start by looking for our event loop's timing.
987 FlatbufferDetachedBuffer<timing::Report> primary_report =
988 FlatbufferDetachedBuffer<timing::Report>::Empty();
989 while (report_fetcher.FetchNext()) {
990 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
991 if (report_fetcher->name()->string_view() == "primary") {
992 primary_report = CopyFlatBuffer(report_fetcher.get());
993 }
994 }
995
996 // Check the watcher report.
997 VLOG(1) << FlatbufferToJson(primary_report, true);
998
999 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1000
1001 // Just the timing report timer.
1002 ASSERT_NE(primary_report.message().timers(), nullptr);
1003 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1004
1005 // No phased loops
1006 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1007
1008 ASSERT_NE(primary_report.message().watchers(), nullptr);
1009 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1010 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1011}
1012
1013// Tests that fetchers count correctly in the timing report.
1014TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1015 FLAGS_timing_report_ms = 1000;
1016 auto loop1 = MakePrimary();
1017 auto loop2 = Make("sender_loop");
1018
1019 auto loop3 = Make();
1020
1021 Fetcher<timing::Report> report_fetcher =
1022 loop3->MakeFetcher<timing::Report>("/aos");
1023 EXPECT_FALSE(report_fetcher.Fetch());
1024
1025 auto sender = loop2->MakeSender<TestMessage>("/test");
1026 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1027 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1028 fetcher1.Fetch();
1029 fetcher2.Fetch();
1030
1031 // Add a timer to actually quit.
1032 auto test_timer = loop1->AddTimer([&sender]() {
1033 for (int i = 0; i < 10; ++i) {
1034 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1035 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1036 builder.add_value(200 + i);
1037 ASSERT_TRUE(msg.Send(builder.Finish()));
1038 }
1039 });
1040
1041 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1042 fetcher1.Fetch();
1043 while (fetcher2.FetchNext()) {
1044 }
1045 });
1046
1047 // Quit after 1 timing report, mid way through the next cycle.
1048 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1049
1050 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1051 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1052 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
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 if (report_fetcher->name()->string_view() == "primary") {
1063 primary_report = CopyFlatBuffer(report_fetcher.get());
1064 }
1065 }
1066
1067 VLOG(1) << FlatbufferToJson(primary_report, true);
1068
1069 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1070
1071 ASSERT_NE(primary_report.message().senders(), nullptr);
1072 EXPECT_EQ(primary_report.message().senders()->size(), 1);
1073
1074 ASSERT_NE(primary_report.message().timers(), nullptr);
1075 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1076
1077 // Make sure there are no phased loops or watchers.
1078 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1079 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1080
1081 // Now look at the fetchrs.
1082 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1083 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1084
1085 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1086 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1087 0.1);
1088 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(),
1089 0.1);
1090 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(),
1091 0.1);
1092 EXPECT_EQ(primary_report.message()
1093 .fetchers()
1094 ->Get(0)
1095 ->latency()
1096 ->standard_deviation(),
1097 0.0);
1098
1099 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001100}
1101
Austin Schuh67420a42019-12-21 21:55:04 -08001102// Tests that a raw watcher and raw fetcher can receive messages from a raw
1103// sender without messing up offsets.
1104TEST_P(AbstractEventLoopTest, RawBasic) {
1105 auto loop1 = Make();
1106 auto loop2 = MakePrimary();
1107 auto loop3 = Make();
1108
1109 const std::string kData("971 is the best");
1110
1111 std::unique_ptr<aos::RawSender> sender =
1112 loop1->MakeRawSender(loop1->configuration()->channels()->Get(1));
1113
1114 std::unique_ptr<aos::RawFetcher> fetcher =
1115 loop3->MakeRawFetcher(loop3->configuration()->channels()->Get(1));
1116
1117 loop2->OnRun(
1118 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1119
1120 bool happened = false;
1121 loop2->MakeRawWatcher(
1122 loop2->configuration()->channels()->Get(1),
1123 [this, &kData, &fetcher, &happened](const Context &context,
1124 const void *message) {
1125 happened = true;
1126 EXPECT_EQ(std::string_view(kData),
1127 std::string_view(reinterpret_cast<const char *>(message),
1128 context.size));
1129 EXPECT_EQ(std::string_view(kData),
1130 std::string_view(reinterpret_cast<const char *>(context.data),
1131 context.size));
1132
1133 ASSERT_TRUE(fetcher->Fetch());
1134
1135 EXPECT_EQ(std::string_view(kData),
1136 std::string_view(
1137 reinterpret_cast<const char *>(fetcher->context().data),
1138 fetcher->context().size));
1139
1140 this->Exit();
1141 });
1142
1143 EXPECT_FALSE(happened);
1144 Run();
1145 EXPECT_TRUE(happened);
1146}
1147
Austin Schuh217a9782019-12-21 23:02:50 -08001148// Tests that not setting up nodes results in no node.
1149TEST_P(AbstractEventLoopTest, NoNode) {
1150 auto loop1 = Make();
1151 auto loop2 = MakePrimary();
1152
1153 EXPECT_EQ(loop1->node(), nullptr);
1154 EXPECT_EQ(loop2->node(), nullptr);
1155}
1156
1157// Tests that setting up nodes results in node being set.
1158TEST_P(AbstractEventLoopTest, Node) {
1159 EnableNodes("me");
1160
1161 auto loop1 = Make();
1162 auto loop2 = MakePrimary();
1163
1164 EXPECT_NE(loop1->node(), nullptr);
1165 EXPECT_NE(loop2->node(), nullptr);
1166}
1167
1168// Tests that watchers work with a node setup.
1169TEST_P(AbstractEventLoopTest, NodeWatcher) {
1170 EnableNodes("me");
1171
1172 auto loop1 = Make();
1173 auto loop2 = Make();
1174 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1175 loop2->MakeRawWatcher(configuration()->channels()->Get(1),
1176 [](const Context &, const void *) {});
1177}
1178
1179// Tests that fetcher work with a node setup.
1180TEST_P(AbstractEventLoopTest, NodeFetcher) {
1181 EnableNodes("me");
1182 auto loop1 = Make();
1183
1184 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1185 auto raw_fetcher = loop1->MakeRawFetcher(configuration()->channels()->Get(1));
1186}
1187
1188// Tests that sender work with a node setup.
1189TEST_P(AbstractEventLoopTest, NodeSender) {
1190 EnableNodes("me");
1191 auto loop1 = Make();
1192
1193 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1194}
1195
1196// Tests that watchers fail when created on the wrong node.
1197TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
1198 EnableNodes("them");
1199
1200 auto loop1 = Make();
1201 auto loop2 = Make();
1202 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
1203 "node");
1204 EXPECT_DEATH(
1205 {
1206 loop2->MakeRawWatcher(configuration()->channels()->Get(1),
1207 [](const Context &, const void *) {});
1208 },
1209 "node");
1210}
1211
1212// Tests that fetchers fail when created on the wrong node.
1213TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
1214 EnableNodes("them");
1215 auto loop1 = Make();
1216
1217 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
1218 "node");
1219 EXPECT_DEATH(
1220 {
1221 auto raw_fetcher =
1222 loop1->MakeRawFetcher(configuration()->channels()->Get(1));
1223 },
1224 "node");
1225}
1226
1227// Tests that senders fail when created on the wrong node.
1228TEST_P(AbstractEventLoopDeathTest, NodeSender) {
1229 EnableNodes("them");
1230 auto loop1 = Make();
1231
1232 EXPECT_DEATH(
1233 {
1234 aos::Sender<TestMessage> sender =
1235 loop1->MakeSender<TestMessage>("/test");
1236 },
1237 "node");
1238
1239 // Note: Creating raw senders is always supported. Right now, this lets us
1240 // use them to create message_gateway.
1241}
1242
Parker Schuhe4a70d62017-12-27 20:10:20 -08001243} // namespace testing
1244} // namespace aos