blob: 3cace56122550f992b4b6d1cb2bfe54a9d268f7b [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());
60
Alex Perrycb7da4b2019-08-28 19:35:56 -070061 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
62 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
63 builder.add_value(200);
64 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -070065
66 EXPECT_TRUE(fetcher.Fetch());
67 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -070068 EXPECT_EQ(fetcher.get()->value(), 200);
Parker Schuhe4a70d62017-12-27 20:10:20 -080069}
70
Austin Schuh3578a2e2019-05-25 18:17:59 -070071// Tests that watcher will receive all messages sent if they are sent after
72// initialization and before running.
73TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
74 auto loop1 = Make();
75 auto loop2 = MakePrimary();
76
77 auto sender = loop1->MakeSender<TestMessage>("/test");
78
79 ::std::vector<int> values;
80
81 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070082 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -070083 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -070084 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -070085 }
86 });
87
Austin Schuh6b6dfa52019-06-12 20:16:20 -070088 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -070089 {
Alex Perrycb7da4b2019-08-28 19:35:56 -070090 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
91 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
92 builder.add_value(199);
93 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -070094 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -070095
96 loop2->OnRun([&]() {
97 {
Alex Perrycb7da4b2019-08-28 19:35:56 -070098 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
99 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
100 builder.add_value(200);
101 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700102 }
103 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700104 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
105 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
106 builder.add_value(201);
107 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700108 }
109 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700110
111 Run();
112
113 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
114}
115
116// Tests that watcher will not receive messages sent before the watcher is
117// created.
118TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
119 auto loop1 = Make();
120 auto loop2 = MakePrimary();
121
122 auto sender = loop1->MakeSender<TestMessage>("/test");
123
124 ::std::vector<int> values;
125
126 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700127 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
128 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
129 builder.add_value(200);
130 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700131 }
132 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700133 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
134 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
135 builder.add_value(201);
136 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700137 }
138
139 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700140 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700141 });
142
143 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700144 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700145 loop2->OnRun([&test_timer, &loop2]() {
146 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
147 });
148
149 Run();
150 EXPECT_EQ(0, values.size());
151}
152
Austin Schuhbbce72d2019-05-26 15:11:46 -0700153// Tests that FetchNext gets all the messages sent after it is constructed.
154TEST_P(AbstractEventLoopTest, FetchNext) {
155 auto loop1 = Make();
156 auto loop2 = MakePrimary();
157
158 auto sender = loop1->MakeSender<TestMessage>("/test");
159 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
160
161 ::std::vector<int> values;
162
163 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700164 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
165 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
166 builder.add_value(200);
167 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700168 }
169 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700170 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
171 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
172 builder.add_value(201);
173 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700174 }
175
176 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700177 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700178 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700179 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700180 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700181 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700182 });
183
184 loop2->OnRun([&test_timer, &loop2]() {
185 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
186 });
187
188 Run();
189 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
190}
191
192// Tests that FetchNext gets no messages sent before it is constructed.
193TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
194 auto loop1 = Make();
195 auto loop2 = MakePrimary();
196
197 auto sender = loop1->MakeSender<TestMessage>("/test");
198
199 ::std::vector<int> values;
200
201 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700202 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
203 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
204 builder.add_value(200);
205 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700206 }
207 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700208 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
209 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
210 builder.add_value(201);
211 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700212 }
213
214 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
215
216 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700217 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700218 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700219 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700220 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700221 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700222 });
223
224 loop2->OnRun([&test_timer, &loop2]() {
225 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
226 });
227
228 Run();
229 EXPECT_THAT(0, values.size());
230}
231
232// Tests that Fetch returns the last message created before the loop was
233// started.
234TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
235 auto loop1 = Make();
236 auto loop2 = MakePrimary();
237
238 auto sender = loop1->MakeSender<TestMessage>("/test");
239
240 ::std::vector<int> values;
241
242 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700243 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
244 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
245 builder.add_value(200);
246 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700247 }
248 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700249 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
250 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
251 builder.add_value(201);
252 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700253 }
254
255 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
256
257 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700258 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700259 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700260 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700261 }
262 // Do it again to make sure we don't double fetch.
263 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700264 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700265 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700266 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700267 });
268
269 loop2->OnRun([&test_timer, &loop2]() {
270 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
271 });
272
273 Run();
274 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
275}
276
277// Tests that Fetch and FetchNext interleave as expected.
278TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
279 auto loop1 = Make();
280 auto loop2 = MakePrimary();
281
282 auto sender = loop1->MakeSender<TestMessage>("/test");
283
284 ::std::vector<int> values;
285
286 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700287 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
288 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
289 builder.add_value(200);
290 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700291 }
292 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700293 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
294 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
295 builder.add_value(201);
296 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700297 }
298
299 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
300
301 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700302 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700303 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700304 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700305 }
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(202);
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(203);
317 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700318 }
319 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700320 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
321 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
322 builder.add_value(204);
323 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700324 }
325
326 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700327 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700328 }
329
330 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700331 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700332 }
333
Austin Schuh9fe68f72019-08-10 19:32:03 -0700334 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700335 });
336
337 loop2->OnRun([&test_timer, &loop2]() {
338 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
339 });
340
341 Run();
342 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
343}
344
Austin Schuh3115a202019-05-27 21:02:14 -0700345
346// Tests that FetchNext behaves correctly when we get two messages in the queue
347// but don't consume the first until after the second has been sent.
348TEST_P(AbstractEventLoopTest, FetchNextTest) {
349
350 auto send_loop = Make();
351 auto fetch_loop = Make();
352 auto sender = send_loop->MakeSender<TestMessage>("/test");
353 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
354
355 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700356 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
357 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
358 builder.add_value(100);
359 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700360 }
361
362 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700363 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
364 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
365 builder.add_value(200);
366 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700367 }
368
369 ASSERT_TRUE(fetcher.FetchNext());
370 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700371 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700372
373 ASSERT_TRUE(fetcher.FetchNext());
374 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700375 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700376
377 // When we run off the end of the queue, expect to still have the old message:
378 ASSERT_FALSE(fetcher.FetchNext());
379 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700380 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700381}
382
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800383// Verify that making a fetcher and watcher for "/test" succeeds.
384TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800385 auto loop = Make();
386 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800387 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800388}
389
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800390// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800391TEST_P(AbstractEventLoopTest, TwoFetcher) {
392 auto loop = Make();
393 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800394 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800395}
396
Alex Perrycb7da4b2019-08-28 19:35:56 -0700397// Verify that registering a watcher for an invalid channel name dies.
398TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
399 auto loop = Make();
400 EXPECT_DEATH(
401 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
402 "/test/invalid");
403}
404
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800405// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700406TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800407 auto loop = Make();
408 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800409 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
410 "/test");
411}
412
Austin Schuh3115a202019-05-27 21:02:14 -0700413// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700414TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700415 auto loop = MakePrimary();
416 // Confirm that runtime priority calls work when not realtime.
417 loop->SetRuntimeRealtimePriority(5);
418
419 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
420
421 EXPECT_DEATH(Run(), "realtime");
422}
423
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800424// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700425TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800426 auto loop = Make();
427 auto sender = loop->MakeSender<TestMessage>("/test");
428 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
429 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800430}
431
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700432// Verify that we can't create a sender inside OnRun.
433TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
434 auto loop1 = MakePrimary();
435
436 loop1->OnRun(
437 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
438
439 EXPECT_DEATH(Run(), "running");
440}
441
442// Verify that we can't create a watcher inside OnRun.
443TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
444 auto loop1 = MakePrimary();
445
446 loop1->OnRun(
447 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
448
449 EXPECT_DEATH(Run(), "running");
450}
451
Parker Schuhe4a70d62017-12-27 20:10:20 -0800452// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800453TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
454 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700455 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800456
Austin Schuh3578a2e2019-05-25 18:17:59 -0700457 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
458 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700459 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700460 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700461 });
462
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800463 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700464
465 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700466 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
467 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
468 builder.add_value(200);
469 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700470 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800471
Austin Schuh44019f92019-05-19 19:58:27 -0700472 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800473}
474
Neil Balch229001a2018-01-07 18:22:52 -0800475// Verify that timer intervals and duration function properly.
476TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh44019f92019-05-19 19:58:27 -0700477 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800478 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
479
480 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
481 iteration_list.push_back(loop->monotonic_now());
482 });
483
Austin Schuh52d325c2019-06-23 18:59:06 -0700484 // TODO(austin): This should be an error... Should be done in OnRun only.
Neil Balch229001a2018-01-07 18:22:52 -0800485 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
486 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
487 // Testing that the timer thread waits for the event loop to start before
488 // running
489 ::std::this_thread::sleep_for(std::chrono::milliseconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700490 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800491
492 EXPECT_EQ(iteration_list.size(), 8);
493}
494
495// Verify that we can change a timer's parameters during execution.
496TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700497 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800498 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
499
500 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
501 iteration_list.push_back(loop->monotonic_now());
502 });
503
504 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
505 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
506 });
507
Neil Balch229001a2018-01-07 18:22:52 -0800508 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
509 modifier_timer->Setup(loop->monotonic_now() +
510 ::std::chrono::milliseconds(45));
511 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700512 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800513
514 EXPECT_EQ(iteration_list.size(), 7);
515}
516
517// Verify that we can disable a timer during execution.
518TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700519 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800520 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
521
522 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
523 iteration_list.push_back(loop->monotonic_now());
524 });
525
526 auto ender_timer = loop->AddTimer([&test_timer]() {
527 test_timer->Disable();
528 });
529
530 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
531 ender_timer->Setup(loop->monotonic_now() +
532 ::std::chrono::milliseconds(45));
533 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700534 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800535
536 EXPECT_EQ(iteration_list.size(), 3);
537}
Austin Schuh7267c532019-05-19 19:55:53 -0700538
Austin Schuh54cf95f2019-11-29 13:14:18 -0800539// Verifies that the event loop implementations detect when Channel is not a
540// pointer into confguration()
541TEST_P(AbstractEventLoopDeathTest, InvalidChannel) {
542 auto loop = MakePrimary();
543
544 const Channel *channel = loop->configuration()->channels()->Get(0);
545
546 FlatbufferDetachedBuffer<Channel> channel_copy = CopyFlatBuffer(channel);
547
548 EXPECT_DEATH(
549 { loop->MakeRawSender(&channel_copy.message()); },
550 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
551
552 EXPECT_DEATH(
553 { loop->MakeRawFetcher(&channel_copy.message()); },
554 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
555
556 EXPECT_DEATH(
557 {
558 loop->MakeRawWatcher(&channel_copy.message(),
559 [](const Context, const void *) {});
560 },
561 "Channel pointer not found in configuration\\(\\)->channels\\(\\)");
562}
563
Austin Schuh7267c532019-05-19 19:55:53 -0700564// Verify that the send time on a message is roughly right.
565TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700566 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700567 auto loop2 = Make();
568 auto sender = loop1->MakeSender<TestMessage>("/test");
569 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
570
571 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700572 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
573 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
574 builder.add_value(200);
575 ASSERT_TRUE(msg.Send(builder.Finish()));
576 });
577
578 loop2->MakeWatcher("/test", [&loop2](const TestMessage &msg) {
579 // Confirm that the data pointer makes sense from a watcher.
580 EXPECT_GT(&msg, loop2->context().data);
581 EXPECT_LT(&msg, reinterpret_cast<void *>(
582 reinterpret_cast<char *>(loop2->context().data) +
583 loop2->context().size));
Austin Schuh7267c532019-05-19 19:55:53 -0700584 });
585
586 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
587
588 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700589 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700590
591 EXPECT_TRUE(fetcher.Fetch());
592
Alex Perrycb7da4b2019-08-28 19:35:56 -0700593 monotonic_clock::duration monotonic_time_offset =
594 fetcher.context().monotonic_sent_time -
595 (loop1->monotonic_now() - ::std::chrono::seconds(1));
596 realtime_clock::duration realtime_time_offset =
597 fetcher.context().realtime_sent_time -
598 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -0700599
Alex Perrycb7da4b2019-08-28 19:35:56 -0700600 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
601 << ": Got "
602 << fetcher.context().monotonic_sent_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -0700603 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700604 // Confirm that the data pointer makes sense.
605 EXPECT_GT(fetcher.get(), fetcher.context().data);
606 EXPECT_LT(fetcher.get(),
607 reinterpret_cast<void *>(
608 reinterpret_cast<char *>(fetcher.context().data) +
609 fetcher.context().size));
610 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
611 << ": Got "
612 << fetcher.context().monotonic_sent_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -0700613 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700614
615 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
616 << ": Got "
617 << fetcher.context().realtime_sent_time.time_since_epoch().count()
618 << " expected " << loop1->realtime_now().time_since_epoch().count();
619 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
620 << ": Got "
621 << fetcher.context().realtime_sent_time.time_since_epoch().count()
622 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -0700623}
624
Austin Schuh52d325c2019-06-23 18:59:06 -0700625// Tests that a couple phased loops run in a row result in the correct offset
626// and period.
627TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
628 const chrono::milliseconds kOffset = chrono::milliseconds(400);
629 const int kCount = 5;
630
631 auto loop1 = MakePrimary();
632
633 // Collect up a couple of samples.
634 ::std::vector<::aos::monotonic_clock::time_point> times;
635
636 // Run kCount iterations.
637 loop1->AddPhasedLoop(
Austin Schuh9fe68f72019-08-10 19:32:03 -0700638 [&times, &loop1, this](int count) {
Austin Schuh52d325c2019-06-23 18:59:06 -0700639 EXPECT_EQ(count, 1);
640 times.push_back(loop1->monotonic_now());
Austin Schuhf257f3c2019-10-27 21:00:43 -0700641 LOG(INFO) << times.size();
Austin Schuh52d325c2019-06-23 18:59:06 -0700642 if (times.size() == kCount) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700643 this->Exit();
Austin Schuh52d325c2019-06-23 18:59:06 -0700644 }
645 },
646 chrono::seconds(1), kOffset);
647
648 // Add a delay to make sure that delay during startup doesn't result in a
649 // "missed cycle".
650 SleepFor(chrono::seconds(2));
651
652 Run();
653
654 // Confirm that we got both the right number of samples, and it's odd.
655 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
656 EXPECT_EQ((times.size() % 2), 1);
657
658 // Grab the middle sample.
659 ::aos::monotonic_clock::time_point middle_time = times[times.size() / 2 + 1];
660
661 // Add up all the delays of all the times.
662 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
663 for (const ::aos::monotonic_clock::time_point time : times) {
664 sum += time - middle_time;
665 }
666
667 // Average and add to the middle to find the average time.
668 sum /= times.size();
669 middle_time += sum;
670
671 // Compute the offset from the start of the second of the average time. This
672 // should be pretty close to the offset.
673 const ::aos::monotonic_clock::duration remainder =
674 middle_time.time_since_epoch() -
675 chrono::duration_cast<chrono::seconds>(middle_time.time_since_epoch());
676
677 const chrono::milliseconds kEpsilon(100);
678 EXPECT_LT(remainder, kOffset + kEpsilon);
679 EXPECT_GT(remainder, kOffset - kEpsilon);
680
681 // Make sure that the average duration is close to 1 second.
682 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
683 times.front())
684 .count() /
685 static_cast<double>(times.size() - 1),
686 1.0, 0.1);
687}
688
Parker Schuhe4a70d62017-12-27 20:10:20 -0800689} // namespace testing
690} // namespace aos