blob: e1e05a29804950d3ebd0133353bc552c826776f1 [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
Austin Schuhad154822019-12-27 15:45:13 -080062 EXPECT_EQ(fetcher.context().monotonic_event_time, monotonic_clock::min_time);
63 EXPECT_EQ(fetcher.context().monotonic_remote_time, monotonic_clock::min_time);
64 EXPECT_EQ(fetcher.context().realtime_event_time, realtime_clock::min_time);
65 EXPECT_EQ(fetcher.context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -080066 EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
67 EXPECT_EQ(fetcher.context().size, 0u);
68 EXPECT_EQ(fetcher.context().data, nullptr);
Austin Schuhbbce72d2019-05-26 15:11:46 -070069
Alex Perrycb7da4b2019-08-28 19:35:56 -070070 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
71 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
72 builder.add_value(200);
73 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -070074
75 EXPECT_TRUE(fetcher.Fetch());
76 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -070077 EXPECT_EQ(fetcher.get()->value(), 200);
Austin Schuh39788ff2019-12-01 18:22:57 -080078
79 const chrono::milliseconds kEpsilon(100);
80
Austin Schuhad154822019-12-27 15:45:13 -080081 const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
82 const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
83 EXPECT_EQ(fetcher.context().monotonic_event_time,
84 fetcher.context().monotonic_remote_time);
85 EXPECT_EQ(fetcher.context().realtime_event_time,
86 fetcher.context().realtime_remote_time);
87
88 EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
89 EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
90 EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
91 EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -080092 EXPECT_EQ(fetcher.context().queue_index, 0x0u);
93 EXPECT_EQ(fetcher.context().size, 20u);
94 EXPECT_NE(fetcher.context().data, nullptr);
Parker Schuhe4a70d62017-12-27 20:10:20 -080095}
96
Austin Schuh3578a2e2019-05-25 18:17:59 -070097// Tests that watcher will receive all messages sent if they are sent after
98// initialization and before running.
99TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
100 auto loop1 = Make();
101 auto loop2 = MakePrimary();
102
103 auto sender = loop1->MakeSender<TestMessage>("/test");
104
105 ::std::vector<int> values;
106
107 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700108 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700109 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700110 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700111 }
112 });
113
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700114 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -0700115 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700116 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
117 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
118 builder.add_value(199);
119 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700120 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700121
122 loop2->OnRun([&]() {
123 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700124 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
125 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
126 builder.add_value(200);
127 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700128 }
129 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700130 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
131 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
132 builder.add_value(201);
133 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700134 }
135 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700136
137 Run();
138
139 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
140}
141
142// Tests that watcher will not receive messages sent before the watcher is
143// created.
144TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
145 auto loop1 = Make();
146 auto loop2 = MakePrimary();
147
148 auto sender = loop1->MakeSender<TestMessage>("/test");
149
150 ::std::vector<int> values;
151
152 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700153 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
154 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
155 builder.add_value(200);
156 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700157 }
158 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700159 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
160 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
161 builder.add_value(201);
162 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700163 }
164
165 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700166 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700167 });
168
169 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700170 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700171 loop2->OnRun([&test_timer, &loop2]() {
172 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
173 });
174
175 Run();
176 EXPECT_EQ(0, values.size());
177}
178
Austin Schuhbbce72d2019-05-26 15:11:46 -0700179// Tests that FetchNext gets all the messages sent after it is constructed.
180TEST_P(AbstractEventLoopTest, FetchNext) {
181 auto loop1 = Make();
182 auto loop2 = MakePrimary();
183
184 auto sender = loop1->MakeSender<TestMessage>("/test");
185 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
186
187 ::std::vector<int> values;
188
189 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700190 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
191 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
192 builder.add_value(200);
193 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700194 }
195 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700196 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
197 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
198 builder.add_value(201);
199 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700200 }
201
202 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700203 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700204 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700205 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700206 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700207 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700208 });
209
210 loop2->OnRun([&test_timer, &loop2]() {
211 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
212 });
213
214 Run();
215 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
216}
217
218// Tests that FetchNext gets no messages sent before it is constructed.
219TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
220 auto loop1 = Make();
221 auto loop2 = MakePrimary();
222
223 auto sender = loop1->MakeSender<TestMessage>("/test");
224
225 ::std::vector<int> values;
226
227 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700228 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
229 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
230 builder.add_value(200);
231 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700232 }
233 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700234 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
235 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
236 builder.add_value(201);
237 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700238 }
239
240 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
241
242 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700243 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700244 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700245 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700246 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700247 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700248 });
249
250 loop2->OnRun([&test_timer, &loop2]() {
251 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
252 });
253
254 Run();
255 EXPECT_THAT(0, values.size());
256}
257
258// Tests that Fetch returns the last message created before the loop was
259// started.
260TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
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 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700286 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700287 }
288 // Do it again to make sure we don't double fetch.
289 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700290 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700291 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700292 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700293 });
294
295 loop2->OnRun([&test_timer, &loop2]() {
296 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
297 });
298
299 Run();
300 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
301}
302
303// Tests that Fetch and FetchNext interleave as expected.
304TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
305 auto loop1 = Make();
306 auto loop2 = MakePrimary();
307
308 auto sender = loop1->MakeSender<TestMessage>("/test");
309
310 ::std::vector<int> values;
311
312 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700313 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
314 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
315 builder.add_value(200);
316 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700317 }
318 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700319 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
320 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
321 builder.add_value(201);
322 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700323 }
324
325 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
326
327 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700328 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700329 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700330 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700331 }
332
333 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700334 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
335 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
336 builder.add_value(202);
337 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700338 }
339 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700340 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
341 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
342 builder.add_value(203);
343 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700344 }
345 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700346 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
347 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
348 builder.add_value(204);
349 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700350 }
351
352 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700353 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700354 }
355
356 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700357 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700358 }
359
Austin Schuh9fe68f72019-08-10 19:32:03 -0700360 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700361 });
362
363 loop2->OnRun([&test_timer, &loop2]() {
364 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
365 });
366
367 Run();
368 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
369}
370
Austin Schuh3115a202019-05-27 21:02:14 -0700371
372// Tests that FetchNext behaves correctly when we get two messages in the queue
373// but don't consume the first until after the second has been sent.
374TEST_P(AbstractEventLoopTest, FetchNextTest) {
375
376 auto send_loop = Make();
377 auto fetch_loop = Make();
378 auto sender = send_loop->MakeSender<TestMessage>("/test");
379 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
380
381 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700382 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
383 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
384 builder.add_value(100);
385 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700386 }
387
388 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700389 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
390 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
391 builder.add_value(200);
392 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700393 }
394
395 ASSERT_TRUE(fetcher.FetchNext());
396 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700397 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700398
399 ASSERT_TRUE(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 // When we run off the end of the queue, expect to still have the old message:
404 ASSERT_FALSE(fetcher.FetchNext());
405 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700406 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700407}
408
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800409// Verify that making a fetcher and watcher for "/test" succeeds.
410TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800411 auto loop = Make();
412 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800413 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800414}
415
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800416// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800417TEST_P(AbstractEventLoopTest, TwoFetcher) {
418 auto loop = Make();
419 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800420 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800421}
422
Alex Perrycb7da4b2019-08-28 19:35:56 -0700423// Verify that registering a watcher for an invalid channel name dies.
424TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
425 auto loop = Make();
426 EXPECT_DEATH(
427 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
428 "/test/invalid");
429}
430
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800431// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700432TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800433 auto loop = Make();
434 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800435 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
436 "/test");
437}
438
Austin Schuh3115a202019-05-27 21:02:14 -0700439// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700440TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700441 auto loop = MakePrimary();
442 // Confirm that runtime priority calls work when not realtime.
443 loop->SetRuntimeRealtimePriority(5);
444
445 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
446
447 EXPECT_DEATH(Run(), "realtime");
448}
449
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800450// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700451TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800452 auto loop = Make();
453 auto sender = loop->MakeSender<TestMessage>("/test");
454 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
455 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800456}
457
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700458// Verify that we can't create a sender inside OnRun.
459TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
460 auto loop1 = MakePrimary();
461
462 loop1->OnRun(
463 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
464
465 EXPECT_DEATH(Run(), "running");
466}
467
468// Verify that we can't create a watcher inside OnRun.
469TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
470 auto loop1 = MakePrimary();
471
472 loop1->OnRun(
473 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
474
475 EXPECT_DEATH(Run(), "running");
476}
477
Parker Schuhe4a70d62017-12-27 20:10:20 -0800478// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800479TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
480 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700481 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800482
Austin Schuh3578a2e2019-05-25 18:17:59 -0700483 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
484 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700485 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700486 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700487 });
488
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800489 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700490
491 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700492 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
493 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
494 builder.add_value(200);
495 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700496 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800497
Austin Schuh44019f92019-05-19 19:58:27 -0700498 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800499}
500
Neil Balch229001a2018-01-07 18:22:52 -0800501// Verify that timer intervals and duration function properly.
502TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800503 // Force a slower rate so we are guarenteed to have reports for our timer.
504 FLAGS_timing_report_ms = 2000;
505
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800506 const int kCount = 5;
Neil Balch229001a2018-01-07 18:22:52 -0800507
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800508 auto loop = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800509 auto loop2 = Make();
510
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800511 ::std::vector<::aos::monotonic_clock::time_point> times;
512 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
513
Austin Schuh39788ff2019-12-01 18:22:57 -0800514 Fetcher<timing::Report> report_fetcher =
515 loop2->MakeFetcher<timing::Report>("/aos");
516 EXPECT_FALSE(report_fetcher.Fetch());
517
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800518 auto test_timer = loop->AddTimer([this, &times, &expected_times, &loop]() {
519 times.push_back(loop->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800520 EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
521 EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
522 EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800523 EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
524 EXPECT_EQ(loop->context().size, 0u);
525 EXPECT_EQ(loop->context().data, nullptr);
526
Austin Schuhad154822019-12-27 15:45:13 -0800527 expected_times.push_back(loop->context().monotonic_event_time);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800528 if (times.size() == kCount) {
529 this->Exit();
530 }
Neil Balch229001a2018-01-07 18:22:52 -0800531 });
Austin Schuh39788ff2019-12-01 18:22:57 -0800532 test_timer->set_name("Test loop");
Neil Balch229001a2018-01-07 18:22:52 -0800533
Austin Schuh39788ff2019-12-01 18:22:57 -0800534 const monotonic_clock::time_point start_time = loop->monotonic_now();
Austin Schuh52d325c2019-06-23 18:59:06 -0700535 // TODO(austin): This should be an error... Should be done in OnRun only.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800536 test_timer->Setup(start_time + chrono::seconds(1), chrono::seconds(1));
537
Austin Schuh44019f92019-05-19 19:58:27 -0700538 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800539
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800540 // Confirm that we got both the right number of samples, and it's odd.
541 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
542 EXPECT_EQ(times.size(), expected_times.size());
543 EXPECT_EQ((times.size() % 2), 1);
544
545 // Grab the middle sample.
546 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
547
548 // Add up all the delays of all the times.
549 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
550 for (const ::aos::monotonic_clock::time_point time : times) {
551 sum += time - average_time;
552 }
553
554 // Average and add to the middle to find the average time.
555 sum /= times.size();
556 average_time += sum;
557
558 // Compute the offset from the average and the expected average. It
559 // should be pretty close to 0.
560 const ::aos::monotonic_clock::duration remainder =
561 average_time - start_time - chrono::seconds(times.size() / 2 + 1);
562
563 const chrono::milliseconds kEpsilon(100);
564 EXPECT_LT(remainder, +kEpsilon);
565 EXPECT_GT(remainder, -kEpsilon);
566
567 // Make sure that the average duration is close to 1 second.
568 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
569 times.front())
570 .count() /
571 static_cast<double>(times.size() - 1),
572 1.0, 0.1);
573
574 // Confirm that the ideal wakeup times increment correctly.
575 for (size_t i = 1; i < expected_times.size(); ++i) {
576 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
577 }
578
579 for (size_t i = 0; i < expected_times.size(); ++i) {
580 EXPECT_EQ((expected_times[i] - start_time) % chrono::seconds(1),
581 chrono::seconds(0));
582 }
583
584 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
585 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800586
587 // And, since we are here, check that the timing report makes sense.
588 // Start by looking for our event loop's timing.
589 FlatbufferDetachedBuffer<timing::Report> report =
590 FlatbufferDetachedBuffer<timing::Report>::Empty();
591 while (report_fetcher.FetchNext()) {
592 if (report_fetcher->name()->string_view() == "primary") {
593 report = CopyFlatBuffer(report_fetcher.get());
594 }
595 }
596
597 // Confirm that we have the right number of reports, and the contents are
598 // sane.
599 VLOG(1) << FlatbufferToJson(report, true);
600
601 EXPECT_EQ(report.message().name()->string_view(), "primary");
602
603 ASSERT_NE(report.message().senders(), nullptr);
604 EXPECT_EQ(report.message().senders()->size(), 1);
605
606 ASSERT_NE(report.message().timers(), nullptr);
607 EXPECT_EQ(report.message().timers()->size(), 2);
608
609 EXPECT_EQ(report.message().timers()->Get(0)->name()->string_view(),
610 "Test loop");
611 EXPECT_GE(report.message().timers()->Get(0)->count(), 1);
612
613 EXPECT_EQ(report.message().timers()->Get(1)->name()->string_view(),
614 "timing_reports");
615 EXPECT_EQ(report.message().timers()->Get(1)->count(), 1);
616
617 // Make sure there is a single phased loop report with our report in it.
618 ASSERT_EQ(report.message().phased_loops(), nullptr);
Neil Balch229001a2018-01-07 18:22:52 -0800619}
620
621// Verify that we can change a timer's parameters during execution.
622TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700623 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800624 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
625
626 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
627 iteration_list.push_back(loop->monotonic_now());
628 });
629
630 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
631 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
632 });
633
Neil Balch229001a2018-01-07 18:22:52 -0800634 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
635 modifier_timer->Setup(loop->monotonic_now() +
636 ::std::chrono::milliseconds(45));
637 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700638 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800639
640 EXPECT_EQ(iteration_list.size(), 7);
641}
642
643// Verify that we can disable a timer during execution.
644TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700645 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800646 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
647
648 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
649 iteration_list.push_back(loop->monotonic_now());
650 });
651
652 auto ender_timer = loop->AddTimer([&test_timer]() {
653 test_timer->Disable();
654 });
655
656 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
657 ender_timer->Setup(loop->monotonic_now() +
658 ::std::chrono::milliseconds(45));
659 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700660 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800661
662 EXPECT_EQ(iteration_list.size(), 3);
663}
Austin Schuh7267c532019-05-19 19:55:53 -0700664
Austin Schuh54cf95f2019-11-29 13:14:18 -0800665// Verifies that the event loop implementations detect when Channel is not a
666// pointer into confguration()
667TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
668 auto loop = MakePrimary();
669
Austin Schuh39788ff2019-12-01 18:22:57 -0800670 const Channel *channel = loop->configuration()->channels()->Get(1);
Austin Schuh54cf95f2019-11-29 13:14:18 -0800671
672 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
673
674 EXPECT_DEATH(
675 { loop->MakeRawSender(&channel_copy.message()); },
676 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
677
678 EXPECT_DEATH(
679 { loop->MakeRawFetcher(&channel_copy.message()); },
680 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
681
682 EXPECT_DEATH(
683 {
684 loop->MakeRawWatcher(&channel_copy.message(),
685 [](const Context, const void *) {});
686 },
687 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
688}
689
Austin Schuh7267c532019-05-19 19:55:53 -0700690// Verify that the send time on a message is roughly right.
691TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700692 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700693 auto loop2 = Make();
Austin Schuhad154822019-12-27 15:45:13 -0800694 auto sender = loop2->MakeSender<TestMessage>("/test");
Austin Schuh7267c532019-05-19 19:55:53 -0700695 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
696
697 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700698 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
699 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
700 builder.add_value(200);
701 ASSERT_TRUE(msg.Send(builder.Finish()));
702 });
703
Austin Schuhad154822019-12-27 15:45:13 -0800704 bool triggered = false;
705 loop1->MakeWatcher("/test", [&triggered, &loop1](const TestMessage &msg) {
706 // Confirm that the data pointer makes sense from a watcher, and all the
707 // timestamps look right.
708 EXPECT_GT(&msg, loop1->context().data);
709 EXPECT_EQ(loop1->context().monotonic_remote_time,
710 loop1->context().monotonic_event_time);
711 EXPECT_EQ(loop1->context().realtime_remote_time,
712 loop1->context().realtime_event_time);
713
714 const aos::monotonic_clock::time_point monotonic_now =
715 loop1->monotonic_now();
716 const aos::realtime_clock::time_point realtime_now =
717 loop1->realtime_now();
718
719 EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
720 EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
721 EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
722 monotonic_now);
723 EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
724 realtime_now);
725
Alex Perrycb7da4b2019-08-28 19:35:56 -0700726 EXPECT_LT(&msg, reinterpret_cast<void *>(
Austin Schuhad154822019-12-27 15:45:13 -0800727 reinterpret_cast<char *>(loop1->context().data) +
728 loop1->context().size));
729 triggered = true;
Austin Schuh7267c532019-05-19 19:55:53 -0700730 });
731
732 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
733
734 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700735 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700736
Austin Schuhad154822019-12-27 15:45:13 -0800737 EXPECT_TRUE(triggered);
738
Austin Schuh7267c532019-05-19 19:55:53 -0700739 EXPECT_TRUE(fetcher.Fetch());
740
Alex Perrycb7da4b2019-08-28 19:35:56 -0700741 monotonic_clock::duration monotonic_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -0800742 fetcher.context().monotonic_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700743 (loop1->monotonic_now() - ::std::chrono::seconds(1));
744 realtime_clock::duration realtime_time_offset =
Austin Schuhad154822019-12-27 15:45:13 -0800745 fetcher.context().realtime_event_time -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700746 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -0700747
Austin Schuhad154822019-12-27 15:45:13 -0800748 EXPECT_EQ(fetcher.context().realtime_event_time,
749 fetcher.context().realtime_remote_time);
750 EXPECT_EQ(fetcher.context().monotonic_event_time,
751 fetcher.context().monotonic_remote_time);
752
Alex Perrycb7da4b2019-08-28 19:35:56 -0700753 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
754 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800755 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -0700756 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700757 // Confirm that the data pointer makes sense.
758 EXPECT_GT(fetcher.get(), fetcher.context().data);
759 EXPECT_LT(fetcher.get(),
760 reinterpret_cast<void *>(
761 reinterpret_cast<char *>(fetcher.context().data) +
762 fetcher.context().size));
763 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
764 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800765 << fetcher.context().monotonic_event_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -0700766 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700767
768 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
769 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800770 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -0700771 << " expected " << loop1->realtime_now().time_since_epoch().count();
772 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
773 << ": Got "
Austin Schuhad154822019-12-27 15:45:13 -0800774 << fetcher.context().realtime_event_time.time_since_epoch().count()
Alex Perrycb7da4b2019-08-28 19:35:56 -0700775 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -0700776}
777
Austin Schuh52d325c2019-06-23 18:59:06 -0700778// Tests that a couple phased loops run in a row result in the correct offset
779// and period.
780TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
Austin Schuh39788ff2019-12-01 18:22:57 -0800781 // Force a slower rate so we are guarenteed to have reports for our phased
782 // loop.
783 FLAGS_timing_report_ms = 2000;
784
Austin Schuh52d325c2019-06-23 18:59:06 -0700785 const chrono::milliseconds kOffset = chrono::milliseconds(400);
786 const int kCount = 5;
787
788 auto loop1 = MakePrimary();
Austin Schuh39788ff2019-12-01 18:22:57 -0800789 auto loop2 = Make();
790
791 Fetcher<timing::Report> report_fetcher =
792 loop2->MakeFetcher<timing::Report>("/aos");
793 EXPECT_FALSE(report_fetcher.Fetch());
Austin Schuh52d325c2019-06-23 18:59:06 -0700794
795 // Collect up a couple of samples.
796 ::std::vector<::aos::monotonic_clock::time_point> times;
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800797 ::std::vector<::aos::monotonic_clock::time_point> expected_times;
Austin Schuh52d325c2019-06-23 18:59:06 -0700798
799 // Run kCount iterations.
Austin Schuh39788ff2019-12-01 18:22:57 -0800800 loop1
801 ->AddPhasedLoop(
802 [&times, &expected_times, &loop1, this](int count) {
803 EXPECT_EQ(count, 1);
804 times.push_back(loop1->monotonic_now());
Austin Schuhad154822019-12-27 15:45:13 -0800805 expected_times.push_back(loop1->context().monotonic_event_time);
Austin Schuh39788ff2019-12-01 18:22:57 -0800806
Austin Schuhad154822019-12-27 15:45:13 -0800807 EXPECT_EQ(loop1->context().monotonic_remote_time,
808 monotonic_clock::min_time);
809 EXPECT_EQ(loop1->context().realtime_event_time,
810 realtime_clock::min_time);
811 EXPECT_EQ(loop1->context().realtime_remote_time,
Austin Schuh39788ff2019-12-01 18:22:57 -0800812 realtime_clock::min_time);
813 EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
814 EXPECT_EQ(loop1->context().size, 0u);
815 EXPECT_EQ(loop1->context().data, nullptr);
816
817 if (times.size() == kCount) {
818 LOG(INFO) << "Exiting";
819 this->Exit();
820 }
821 },
822 chrono::seconds(1), kOffset)
823 ->set_name("Test loop");
Austin Schuh52d325c2019-06-23 18:59:06 -0700824
825 // Add a delay to make sure that delay during startup doesn't result in a
826 // "missed cycle".
827 SleepFor(chrono::seconds(2));
828
829 Run();
830
831 // Confirm that we got both the right number of samples, and it's odd.
832 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800833 EXPECT_EQ(times.size(), expected_times.size());
Austin Schuh52d325c2019-06-23 18:59:06 -0700834 EXPECT_EQ((times.size() % 2), 1);
835
836 // Grab the middle sample.
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800837 ::aos::monotonic_clock::time_point average_time = times[times.size() / 2];
Austin Schuh52d325c2019-06-23 18:59:06 -0700838
839 // Add up all the delays of all the times.
840 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
841 for (const ::aos::monotonic_clock::time_point time : times) {
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800842 sum += time - average_time;
Austin Schuh52d325c2019-06-23 18:59:06 -0700843 }
844
845 // Average and add to the middle to find the average time.
846 sum /= times.size();
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800847 average_time += sum;
Austin Schuh52d325c2019-06-23 18:59:06 -0700848
849 // Compute the offset from the start of the second of the average time. This
850 // should be pretty close to the offset.
851 const ::aos::monotonic_clock::duration remainder =
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800852 average_time.time_since_epoch() -
853 chrono::duration_cast<chrono::seconds>(average_time.time_since_epoch());
Austin Schuh52d325c2019-06-23 18:59:06 -0700854
855 const chrono::milliseconds kEpsilon(100);
856 EXPECT_LT(remainder, kOffset + kEpsilon);
857 EXPECT_GT(remainder, kOffset - kEpsilon);
858
859 // Make sure that the average duration is close to 1 second.
860 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
861 times.front())
862 .count() /
863 static_cast<double>(times.size() - 1),
864 1.0, 0.1);
Austin Schuhde8a8ff2019-11-30 15:25:36 -0800865
866 // Confirm that the ideal wakeup times increment correctly.
867 for (size_t i = 1; i < expected_times.size(); ++i) {
868 EXPECT_EQ(expected_times[i], expected_times[i - 1] + chrono::seconds(1));
869 }
870
871 for (size_t i = 0; i < expected_times.size(); ++i) {
872 EXPECT_EQ(expected_times[i].time_since_epoch() % chrono::seconds(1),
873 kOffset);
874 }
875
876 EXPECT_LT(expected_times[expected_times.size() / 2], average_time + kEpsilon);
877 EXPECT_GT(expected_times[expected_times.size() / 2], average_time - kEpsilon);
Austin Schuh39788ff2019-12-01 18:22:57 -0800878
879 // And, since we are here, check that the timing report makes sense.
880 // Start by looking for our event loop's timing.
881 FlatbufferDetachedBuffer<timing::Report> report =
882 FlatbufferDetachedBuffer<timing::Report>::Empty();
883 while (report_fetcher.FetchNext()) {
884 if (report_fetcher->name()->string_view() == "primary") {
885 report = CopyFlatBuffer(report_fetcher.get());
886 }
887 }
888
889 VLOG(1) << FlatbufferToJson(report, true);
890
891 EXPECT_EQ(report.message().name()->string_view(), "primary");
892
893 ASSERT_NE(report.message().senders(), nullptr);
894 EXPECT_EQ(report.message().senders()->size(), 1);
895
896 ASSERT_NE(report.message().timers(), nullptr);
897 EXPECT_EQ(report.message().timers()->size(), 1);
898
899 // Make sure there is a single phased loop report with our report in it.
900 ASSERT_NE(report.message().phased_loops(), nullptr);
901 ASSERT_EQ(report.message().phased_loops()->size(), 1);
902 EXPECT_EQ(report.message().phased_loops()->Get(0)->name()->string_view(),
903 "Test loop");
904 EXPECT_GE(report.message().phased_loops()->Get(0)->count(), 1);
905}
906
907// Tests that senders count correctly in the timing report.
908TEST_P(AbstractEventLoopTest, SenderTimingReport) {
909 FLAGS_timing_report_ms = 1000;
910 auto loop1 = MakePrimary();
911
912 auto loop2 = Make("watcher_loop");
913 loop2->MakeWatcher("/test", [](const TestMessage &) {});
914
915 auto loop3 = Make();
916
917 Fetcher<timing::Report> report_fetcher =
918 loop3->MakeFetcher<timing::Report>("/aos");
919 EXPECT_FALSE(report_fetcher.Fetch());
920
921 auto sender = loop1->MakeSender<TestMessage>("/test");
922
923 // Add a timer to actually quit.
924 auto test_timer = loop1->AddTimer([&sender]() {
925 for (int i = 0; i < 10; ++i) {
926 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
927 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
928 builder.add_value(200 + i);
929 ASSERT_TRUE(msg.Send(builder.Finish()));
930 }
931 });
932
933 // Quit after 1 timing report, mid way through the next cycle.
934 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
935
936 loop1->OnRun([&test_timer, &loop1]() {
937 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
938 });
939
940 Run();
941
942 // And, since we are here, check that the timing report makes sense.
943 // Start by looking for our event loop's timing.
944 FlatbufferDetachedBuffer<timing::Report> primary_report =
945 FlatbufferDetachedBuffer<timing::Report>::Empty();
946 while (report_fetcher.FetchNext()) {
947 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
948 if (report_fetcher->name()->string_view() == "primary") {
949 primary_report = CopyFlatBuffer(report_fetcher.get());
950 }
951 }
952
953 LOG(INFO) << FlatbufferToJson(primary_report, true);
954
955 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
956
957 ASSERT_NE(primary_report.message().senders(), nullptr);
958 EXPECT_EQ(primary_report.message().senders()->size(), 2);
959
960 // Confirm that the sender looks sane.
961 EXPECT_EQ(
962 loop1->configuration()
963 ->channels()
964 ->Get(primary_report.message().senders()->Get(0)->channel_index())
965 ->name()
966 ->string_view(),
967 "/test");
968 EXPECT_EQ(primary_report.message().senders()->Get(0)->count(), 10);
969
970 // Confirm that the timing primary_report sender looks sane.
971 EXPECT_EQ(
972 loop1->configuration()
973 ->channels()
974 ->Get(primary_report.message().senders()->Get(1)->channel_index())
975 ->name()
976 ->string_view(),
977 "/aos");
978 EXPECT_EQ(primary_report.message().senders()->Get(1)->count(), 1);
979
980 ASSERT_NE(primary_report.message().timers(), nullptr);
981 EXPECT_EQ(primary_report.message().timers()->size(), 3);
982
983 // Make sure there are no phased loops or watchers.
984 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
985 ASSERT_EQ(primary_report.message().watchers(), nullptr);
986}
987
988// Tests that senders count correctly in the timing report.
989TEST_P(AbstractEventLoopTest, WatcherTimingReport) {
990 FLAGS_timing_report_ms = 1000;
991 auto loop1 = MakePrimary();
992 loop1->MakeWatcher("/test", [](const TestMessage &) {});
993
994 auto loop2 = Make("sender_loop");
995
996 auto loop3 = Make();
997
998 Fetcher<timing::Report> report_fetcher =
999 loop3->MakeFetcher<timing::Report>("/aos");
1000 EXPECT_FALSE(report_fetcher.Fetch());
1001
1002 auto sender = loop2->MakeSender<TestMessage>("/test");
1003
1004 // Add a timer to actually quit.
1005 auto test_timer = loop1->AddTimer([&sender]() {
1006 for (int i = 0; i < 10; ++i) {
1007 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1008 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1009 builder.add_value(200 + i);
1010 ASSERT_TRUE(msg.Send(builder.Finish()));
1011 }
1012 });
1013
1014 // Quit after 1 timing report, mid way through the next cycle.
1015 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1016
1017 loop1->OnRun([&test_timer, &loop1]() {
1018 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1500));
1019 });
1020
1021 Run();
1022
1023 // And, since we are here, check that the timing report makes sense.
1024 // Start by looking for our event loop's timing.
1025 FlatbufferDetachedBuffer<timing::Report> primary_report =
1026 FlatbufferDetachedBuffer<timing::Report>::Empty();
1027 while (report_fetcher.FetchNext()) {
1028 LOG(INFO) << "Report " << FlatbufferToJson(report_fetcher.get());
1029 if (report_fetcher->name()->string_view() == "primary") {
1030 primary_report = CopyFlatBuffer(report_fetcher.get());
1031 }
1032 }
1033
1034 // Check the watcher report.
1035 VLOG(1) << FlatbufferToJson(primary_report, true);
1036
1037 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1038
1039 // Just the timing report timer.
1040 ASSERT_NE(primary_report.message().timers(), nullptr);
1041 EXPECT_EQ(primary_report.message().timers()->size(), 3);
1042
1043 // No phased loops
1044 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1045
1046 ASSERT_NE(primary_report.message().watchers(), nullptr);
1047 ASSERT_EQ(primary_report.message().watchers()->size(), 1);
1048 EXPECT_EQ(primary_report.message().watchers()->Get(0)->count(), 10);
1049}
1050
1051// Tests that fetchers count correctly in the timing report.
1052TEST_P(AbstractEventLoopTest, FetcherTimingReport) {
1053 FLAGS_timing_report_ms = 1000;
1054 auto loop1 = MakePrimary();
1055 auto loop2 = Make("sender_loop");
1056
1057 auto loop3 = Make();
1058
1059 Fetcher<timing::Report> report_fetcher =
1060 loop3->MakeFetcher<timing::Report>("/aos");
1061 EXPECT_FALSE(report_fetcher.Fetch());
1062
1063 auto sender = loop2->MakeSender<TestMessage>("/test");
1064 auto fetcher1 = loop1->MakeFetcher<TestMessage>("/test");
1065 auto fetcher2 = loop1->MakeFetcher<TestMessage>("/test");
1066 fetcher1.Fetch();
1067 fetcher2.Fetch();
1068
1069 // Add a timer to actually quit.
1070 auto test_timer = loop1->AddTimer([&sender]() {
1071 for (int i = 0; i < 10; ++i) {
1072 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
1073 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
1074 builder.add_value(200 + i);
1075 ASSERT_TRUE(msg.Send(builder.Finish()));
1076 }
1077 });
1078
1079 auto test_timer2 = loop1->AddTimer([&fetcher1, &fetcher2]() {
1080 fetcher1.Fetch();
1081 while (fetcher2.FetchNext()) {
1082 }
1083 });
1084
1085 // Quit after 1 timing report, mid way through the next cycle.
1086 EndEventLoop(loop1.get(), chrono::milliseconds(2500));
1087
1088 loop1->OnRun([test_timer, test_timer2, &loop1]() {
1089 test_timer->Setup(loop1->monotonic_now() + chrono::milliseconds(1400));
1090 test_timer2->Setup(loop1->monotonic_now() + chrono::milliseconds(1600));
1091 });
1092
1093 Run();
1094
1095 // And, since we are here, check that the timing report makes sense.
1096 // Start by looking for our event loop's timing.
1097 FlatbufferDetachedBuffer<timing::Report> primary_report =
1098 FlatbufferDetachedBuffer<timing::Report>::Empty();
1099 while (report_fetcher.FetchNext()) {
1100 if (report_fetcher->name()->string_view() == "primary") {
1101 primary_report = CopyFlatBuffer(report_fetcher.get());
1102 }
1103 }
1104
1105 VLOG(1) << FlatbufferToJson(primary_report, true);
1106
1107 EXPECT_EQ(primary_report.message().name()->string_view(), "primary");
1108
1109 ASSERT_NE(primary_report.message().senders(), nullptr);
1110 EXPECT_EQ(primary_report.message().senders()->size(), 1);
1111
1112 ASSERT_NE(primary_report.message().timers(), nullptr);
1113 EXPECT_EQ(primary_report.message().timers()->size(), 4);
1114
1115 // Make sure there are no phased loops or watchers.
1116 ASSERT_EQ(primary_report.message().phased_loops(), nullptr);
1117 ASSERT_EQ(primary_report.message().watchers(), nullptr);
1118
1119 // Now look at the fetchrs.
1120 ASSERT_NE(primary_report.message().fetchers(), nullptr);
1121 ASSERT_EQ(primary_report.message().fetchers()->size(), 2);
1122
1123 EXPECT_EQ(primary_report.message().fetchers()->Get(0)->count(), 1);
1124 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->average(),
1125 0.1);
1126 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->min(),
1127 0.1);
1128 EXPECT_GE(primary_report.message().fetchers()->Get(0)->latency()->max(),
1129 0.1);
1130 EXPECT_EQ(primary_report.message()
1131 .fetchers()
1132 ->Get(0)
1133 ->latency()
1134 ->standard_deviation(),
1135 0.0);
1136
1137 EXPECT_EQ(primary_report.message().fetchers()->Get(1)->count(), 10);
Austin Schuh52d325c2019-06-23 18:59:06 -07001138}
1139
Austin Schuh67420a42019-12-21 21:55:04 -08001140// Tests that a raw watcher and raw fetcher can receive messages from a raw
1141// sender without messing up offsets.
1142TEST_P(AbstractEventLoopTest, RawBasic) {
1143 auto loop1 = Make();
1144 auto loop2 = MakePrimary();
1145 auto loop3 = Make();
1146
1147 const std::string kData("971 is the best");
1148
1149 std::unique_ptr<aos::RawSender> sender =
1150 loop1->MakeRawSender(loop1->configuration()->channels()->Get(1));
1151
1152 std::unique_ptr<aos::RawFetcher> fetcher =
1153 loop3->MakeRawFetcher(loop3->configuration()->channels()->Get(1));
1154
1155 loop2->OnRun(
1156 [&]() { EXPECT_TRUE(sender->Send(kData.data(), kData.size())); });
1157
1158 bool happened = false;
1159 loop2->MakeRawWatcher(
1160 loop2->configuration()->channels()->Get(1),
1161 [this, &kData, &fetcher, &happened](const Context &context,
1162 const void *message) {
1163 happened = true;
1164 EXPECT_EQ(std::string_view(kData),
1165 std::string_view(reinterpret_cast<const char *>(message),
1166 context.size));
1167 EXPECT_EQ(std::string_view(kData),
1168 std::string_view(reinterpret_cast<const char *>(context.data),
1169 context.size));
1170
1171 ASSERT_TRUE(fetcher->Fetch());
1172
1173 EXPECT_EQ(std::string_view(kData),
1174 std::string_view(
1175 reinterpret_cast<const char *>(fetcher->context().data),
1176 fetcher->context().size));
1177
1178 this->Exit();
1179 });
1180
1181 EXPECT_FALSE(happened);
1182 Run();
1183 EXPECT_TRUE(happened);
1184}
1185
Austin Schuhad154822019-12-27 15:45:13 -08001186// Tests that a raw watcher and raw fetcher can receive messages from a raw
1187// sender with remote times filled out.
1188TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
1189 auto loop1 = Make();
1190 auto loop2 = MakePrimary();
1191 auto loop3 = Make();
1192
1193 const std::string kData("971 is the best");
1194
1195 const aos::monotonic_clock::time_point monotonic_remote_time =
1196 aos::monotonic_clock::time_point(chrono::seconds(1501));
1197 const aos::realtime_clock::time_point realtime_remote_time =
1198 aos::realtime_clock::time_point(chrono::seconds(3132));
1199
1200 std::unique_ptr<aos::RawSender> sender =
1201 loop1->MakeRawSender(loop1->configuration()->channels()->Get(1));
1202
1203 std::unique_ptr<aos::RawFetcher> fetcher =
1204 loop3->MakeRawFetcher(loop3->configuration()->channels()->Get(1));
1205
1206 loop2->OnRun([&]() {
1207 EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
1208 realtime_remote_time));
1209 });
1210
1211 bool happened = false;
1212 loop2->MakeRawWatcher(
1213 loop2->configuration()->channels()->Get(1),
1214 [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
1215 const Context &context, const void * /*message*/) {
1216 happened = true;
1217 EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
1218 EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
1219
1220 ASSERT_TRUE(fetcher->Fetch());
1221 EXPECT_EQ(monotonic_remote_time,
1222 fetcher->context().monotonic_remote_time);
1223 EXPECT_EQ(realtime_remote_time,
1224 fetcher->context().realtime_remote_time);
1225
1226 this->Exit();
1227 });
1228
1229 EXPECT_FALSE(happened);
1230 Run();
1231 EXPECT_TRUE(happened);
1232}
1233
1234// Tests that a raw sender fills out sent data.
1235TEST_P(AbstractEventLoopTest, RawSenderSentData) {
1236 auto loop1 = MakePrimary();
1237
1238 const std::string kData("971 is the best");
1239
1240 std::unique_ptr<aos::RawSender> sender =
1241 loop1->MakeRawSender(loop1->configuration()->channels()->Get(1));
1242
1243 const aos::monotonic_clock::time_point monotonic_now =
1244 loop1->monotonic_now();
1245 const aos::realtime_clock::time_point realtime_now =
1246 loop1->realtime_now();
1247
1248 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1249
1250 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1251 EXPECT_LE(sender->monotonic_sent_time(),
1252 monotonic_now + chrono::milliseconds(100));
1253 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1254 EXPECT_LE(sender->realtime_sent_time(),
1255 realtime_now + chrono::milliseconds(100));
1256 EXPECT_EQ(sender->sent_queue_index(), 0u);
1257
1258 EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
1259
1260 EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
1261 EXPECT_LE(sender->monotonic_sent_time(),
1262 monotonic_now + chrono::milliseconds(100));
1263 EXPECT_GE(sender->realtime_sent_time(), realtime_now);
1264 EXPECT_LE(sender->realtime_sent_time(),
1265 realtime_now + chrono::milliseconds(100));
1266 EXPECT_EQ(sender->sent_queue_index(), 1u);
1267}
1268
Austin Schuh217a9782019-12-21 23:02:50 -08001269// Tests that not setting up nodes results in no node.
1270TEST_P(AbstractEventLoopTest, NoNode) {
1271 auto loop1 = Make();
1272 auto loop2 = MakePrimary();
1273
1274 EXPECT_EQ(loop1->node(), nullptr);
1275 EXPECT_EQ(loop2->node(), nullptr);
1276}
1277
1278// Tests that setting up nodes results in node being set.
1279TEST_P(AbstractEventLoopTest, Node) {
1280 EnableNodes("me");
1281
1282 auto loop1 = Make();
1283 auto loop2 = MakePrimary();
1284
1285 EXPECT_NE(loop1->node(), nullptr);
1286 EXPECT_NE(loop2->node(), nullptr);
1287}
1288
1289// Tests that watchers work with a node setup.
1290TEST_P(AbstractEventLoopTest, NodeWatcher) {
1291 EnableNodes("me");
1292
1293 auto loop1 = Make();
1294 auto loop2 = Make();
1295 loop1->MakeWatcher("/test", [](const TestMessage &) {});
1296 loop2->MakeRawWatcher(configuration()->channels()->Get(1),
1297 [](const Context &, const void *) {});
1298}
1299
1300// Tests that fetcher work with a node setup.
1301TEST_P(AbstractEventLoopTest, NodeFetcher) {
1302 EnableNodes("me");
1303 auto loop1 = Make();
1304
1305 auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
1306 auto raw_fetcher = loop1->MakeRawFetcher(configuration()->channels()->Get(1));
1307}
1308
1309// Tests that sender work with a node setup.
1310TEST_P(AbstractEventLoopTest, NodeSender) {
1311 EnableNodes("me");
1312 auto loop1 = Make();
1313
1314 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
1315}
1316
1317// Tests that watchers fail when created on the wrong node.
1318TEST_P(AbstractEventLoopDeathTest, NodeWatcher) {
1319 EnableNodes("them");
1320
1321 auto loop1 = Make();
1322 auto loop2 = Make();
1323 EXPECT_DEATH({ loop1->MakeWatcher("/test", [](const TestMessage &) {}); },
1324 "node");
1325 EXPECT_DEATH(
1326 {
1327 loop2->MakeRawWatcher(configuration()->channels()->Get(1),
1328 [](const Context &, const void *) {});
1329 },
1330 "node");
1331}
1332
1333// Tests that fetchers fail when created on the wrong node.
1334TEST_P(AbstractEventLoopDeathTest, NodeFetcher) {
1335 EnableNodes("them");
1336 auto loop1 = Make();
1337
1338 EXPECT_DEATH({ auto fetcher = loop1->MakeFetcher<TestMessage>("/test"); },
1339 "node");
1340 EXPECT_DEATH(
1341 {
1342 auto raw_fetcher =
1343 loop1->MakeRawFetcher(configuration()->channels()->Get(1));
1344 },
1345 "node");
1346}
1347
1348// Tests that senders fail when created on the wrong node.
1349TEST_P(AbstractEventLoopDeathTest, NodeSender) {
1350 EnableNodes("them");
1351 auto loop1 = Make();
1352
1353 EXPECT_DEATH(
1354 {
1355 aos::Sender<TestMessage> sender =
1356 loop1->MakeSender<TestMessage>("/test");
1357 },
1358 "node");
1359
1360 // Note: Creating raw senders is always supported. Right now, this lets us
1361 // use them to create message_gateway.
1362}
1363
Parker Schuhe4a70d62017-12-27 20:10:20 -08001364} // namespace testing
1365} // namespace aos