blob: 8a0f9b65dbad49ec70db58e11c1816002eae2388 [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
Austin Schuhf257f3c2019-10-27 21:00:43 -07009#include "glog/logging.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070010#include "aos/events/test_message_generated.h"
Austin Schuh9fe68f72019-08-10 19:32:03 -070011
Parker Schuhe4a70d62017-12-27 20:10:20 -080012namespace aos {
13namespace testing {
Austin Schuh52d325c2019-06-23 18:59:06 -070014namespace {
15namespace chrono = ::std::chrono;
16} // namespace
Parker Schuhe4a70d62017-12-27 20:10:20 -080017
Austin Schuh6b6dfa52019-06-12 20:16:20 -070018// Tests that watcher can receive messages from a sender.
Parker Schuhe4a70d62017-12-27 20:10:20 -080019// Also tests that OnRun() works.
20TEST_P(AbstractEventLoopTest, Basic) {
21 auto loop1 = Make();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070022 auto loop2 = MakePrimary();
23
Alex Perrycb7da4b2019-08-28 19:35:56 -070024 aos::Sender<TestMessage> sender = loop1->MakeSender<TestMessage>("/test");
Austin Schuh6b6dfa52019-06-12 20:16:20 -070025
26 bool happened = false;
27
28 loop2->OnRun([&]() {
29 happened = true;
30
Alex Perrycb7da4b2019-08-28 19:35:56 -070031 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
32 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
33 builder.add_value(200);
34 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -070035 });
36
37 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070038 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -070039 this->Exit();
Austin Schuh6b6dfa52019-06-12 20:16:20 -070040 });
41
42 EXPECT_FALSE(happened);
43 Run();
44 EXPECT_TRUE(happened);
45}
46
47// Tests that a fetcher can fetch from a sender.
48// Also tests that OnRun() works.
49TEST_P(AbstractEventLoopTest, FetchWithoutRun) {
50 auto loop1 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -080051 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -070052 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -080053
54 auto sender = loop1->MakeSender<TestMessage>("/test");
55
56 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
57
Austin Schuhbbce72d2019-05-26 15:11:46 -070058 EXPECT_FALSE(fetcher.Fetch());
59
Alex Perrycb7da4b2019-08-28 19:35:56 -070060 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
61 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
62 builder.add_value(200);
63 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -070064
65 EXPECT_TRUE(fetcher.Fetch());
66 ASSERT_FALSE(fetcher.get() == nullptr);
Alex Perrycb7da4b2019-08-28 19:35:56 -070067 EXPECT_EQ(fetcher.get()->value(), 200);
Parker Schuhe4a70d62017-12-27 20:10:20 -080068}
69
Austin Schuh3578a2e2019-05-25 18:17:59 -070070// Tests that watcher will receive all messages sent if they are sent after
71// initialization and before running.
72TEST_P(AbstractEventLoopTest, DoubleSendAtStartup) {
73 auto loop1 = Make();
74 auto loop2 = MakePrimary();
75
76 auto sender = loop1->MakeSender<TestMessage>("/test");
77
78 ::std::vector<int> values;
79
80 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070081 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -070082 if (values.size() == 2) {
Austin Schuh9fe68f72019-08-10 19:32:03 -070083 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -070084 }
85 });
86
Austin Schuh6b6dfa52019-06-12 20:16:20 -070087 // Before Run, should be ignored.
Austin Schuh3578a2e2019-05-25 18:17:59 -070088 {
Alex Perrycb7da4b2019-08-28 19:35:56 -070089 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
90 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
91 builder.add_value(199);
92 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -070093 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -070094
95 loop2->OnRun([&]() {
96 {
Alex Perrycb7da4b2019-08-28 19:35:56 -070097 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
98 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
99 builder.add_value(200);
100 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700101 }
102 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700103 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
104 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
105 builder.add_value(201);
106 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700107 }
108 });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700109
110 Run();
111
112 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
113}
114
115// Tests that watcher will not receive messages sent before the watcher is
116// created.
117TEST_P(AbstractEventLoopTest, DoubleSendAfterStartup) {
118 auto loop1 = Make();
119 auto loop2 = MakePrimary();
120
121 auto sender = loop1->MakeSender<TestMessage>("/test");
122
123 ::std::vector<int> values;
124
125 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700126 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
127 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
128 builder.add_value(200);
129 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700130 }
131 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700132 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
133 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
134 builder.add_value(201);
135 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3578a2e2019-05-25 18:17:59 -0700136 }
137
138 loop2->MakeWatcher("/test", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700139 values.push_back(message.value());
Austin Schuh3578a2e2019-05-25 18:17:59 -0700140 });
141
142 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700143 auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
Austin Schuh3578a2e2019-05-25 18:17:59 -0700144 loop2->OnRun([&test_timer, &loop2]() {
145 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
146 });
147
148 Run();
149 EXPECT_EQ(0, values.size());
150}
151
Austin Schuhbbce72d2019-05-26 15:11:46 -0700152// Tests that FetchNext gets all the messages sent after it is constructed.
153TEST_P(AbstractEventLoopTest, FetchNext) {
154 auto loop1 = Make();
155 auto loop2 = MakePrimary();
156
157 auto sender = loop1->MakeSender<TestMessage>("/test");
158 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
159
160 ::std::vector<int> values;
161
162 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700163 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
164 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
165 builder.add_value(200);
166 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700167 }
168 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700169 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
170 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
171 builder.add_value(201);
172 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700173 }
174
175 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700176 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700177 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700178 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700179 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700180 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700181 });
182
183 loop2->OnRun([&test_timer, &loop2]() {
184 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
185 });
186
187 Run();
188 EXPECT_THAT(values, ::testing::ElementsAreArray({200, 201}));
189}
190
191// Tests that FetchNext gets no messages sent before it is constructed.
192TEST_P(AbstractEventLoopTest, FetchNextAfterSend) {
193 auto loop1 = Make();
194 auto loop2 = MakePrimary();
195
196 auto sender = loop1->MakeSender<TestMessage>("/test");
197
198 ::std::vector<int> values;
199
200 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700201 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
202 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
203 builder.add_value(200);
204 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700205 }
206 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700207 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
208 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
209 builder.add_value(201);
210 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700211 }
212
213 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
214
215 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700216 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700217 while (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700218 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700219 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700220 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700221 });
222
223 loop2->OnRun([&test_timer, &loop2]() {
224 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
225 });
226
227 Run();
228 EXPECT_THAT(0, values.size());
229}
230
231// Tests that Fetch returns the last message created before the loop was
232// started.
233TEST_P(AbstractEventLoopTest, FetchDataFromBeforeCreation) {
234 auto loop1 = Make();
235 auto loop2 = MakePrimary();
236
237 auto sender = loop1->MakeSender<TestMessage>("/test");
238
239 ::std::vector<int> values;
240
241 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700242 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
243 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
244 builder.add_value(200);
245 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700246 }
247 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700248 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
249 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
250 builder.add_value(201);
251 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700252 }
253
254 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
255
256 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700257 auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700258 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700259 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700260 }
261 // Do it again to make sure we don't double fetch.
262 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700263 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700264 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700265 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700266 });
267
268 loop2->OnRun([&test_timer, &loop2]() {
269 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
270 });
271
272 Run();
273 EXPECT_THAT(values, ::testing::ElementsAreArray({201}));
274}
275
276// Tests that Fetch and FetchNext interleave as expected.
277TEST_P(AbstractEventLoopTest, FetchAndFetchNextTogether) {
278 auto loop1 = Make();
279 auto loop2 = MakePrimary();
280
281 auto sender = loop1->MakeSender<TestMessage>("/test");
282
283 ::std::vector<int> values;
284
285 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700286 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
287 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
288 builder.add_value(200);
289 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700290 }
291 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700292 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
293 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
294 builder.add_value(201);
295 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700296 }
297
298 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
299
300 // Add a timer to actually quit.
Austin Schuh9fe68f72019-08-10 19:32:03 -0700301 auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
Austin Schuhbbce72d2019-05-26 15:11:46 -0700302 if (fetcher.Fetch()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700303 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700304 }
305
306 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700307 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
308 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
309 builder.add_value(202);
310 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700311 }
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(203);
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(204);
322 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuhbbce72d2019-05-26 15:11:46 -0700323 }
324
325 if (fetcher.FetchNext()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700326 values.push_back(fetcher.get()->value());
Austin Schuhbbce72d2019-05-26 15:11:46 -0700327 }
328
329 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
Austin Schuh9fe68f72019-08-10 19:32:03 -0700333 this->Exit();
Austin Schuhbbce72d2019-05-26 15:11:46 -0700334 });
335
336 loop2->OnRun([&test_timer, &loop2]() {
337 test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
338 });
339
340 Run();
341 EXPECT_THAT(values, ::testing::ElementsAreArray({201, 202, 204}));
342}
343
Austin Schuh3115a202019-05-27 21:02:14 -0700344
345// Tests that FetchNext behaves correctly when we get two messages in the queue
346// but don't consume the first until after the second has been sent.
347TEST_P(AbstractEventLoopTest, FetchNextTest) {
348
349 auto send_loop = Make();
350 auto fetch_loop = Make();
351 auto sender = send_loop->MakeSender<TestMessage>("/test");
352 Fetcher<TestMessage> fetcher = fetch_loop->MakeFetcher<TestMessage>("/test");
353
354 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700355 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
356 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
357 builder.add_value(100);
358 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700359 }
360
361 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700362 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
363 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
364 builder.add_value(200);
365 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh3115a202019-05-27 21:02:14 -0700366 }
367
368 ASSERT_TRUE(fetcher.FetchNext());
369 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700370 EXPECT_EQ(100, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700371
372 ASSERT_TRUE(fetcher.FetchNext());
373 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700374 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700375
376 // When we run off the end of the queue, expect to still have the old message:
377 ASSERT_FALSE(fetcher.FetchNext());
378 ASSERT_NE(nullptr, fetcher.get());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700379 EXPECT_EQ(200, fetcher.get()->value());
Austin Schuh3115a202019-05-27 21:02:14 -0700380}
381
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800382// Verify that making a fetcher and watcher for "/test" succeeds.
383TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800384 auto loop = Make();
385 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800386 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -0800387}
388
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800389// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -0800390TEST_P(AbstractEventLoopTest, TwoFetcher) {
391 auto loop = Make();
392 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800393 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800394}
395
Alex Perrycb7da4b2019-08-28 19:35:56 -0700396// Verify that registering a watcher for an invalid channel name dies.
397TEST_P(AbstractEventLoopDeathTest, InvalidChannelName) {
398 auto loop = Make();
399 EXPECT_DEATH(
400 { loop->MakeWatcher("/test/invalid", [&](const TestMessage &) {}); },
401 "/test/invalid");
402}
403
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800404// Verify that registering a watcher twice for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700405TEST_P(AbstractEventLoopDeathTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800406 auto loop = Make();
407 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800408 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
409 "/test");
410}
411
Austin Schuh3115a202019-05-27 21:02:14 -0700412// Verify that SetRuntimeRealtimePriority fails while running.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700413TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
Austin Schuh3115a202019-05-27 21:02:14 -0700414 auto loop = MakePrimary();
415 // Confirm that runtime priority calls work when not realtime.
416 loop->SetRuntimeRealtimePriority(5);
417
418 loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
419
420 EXPECT_DEATH(Run(), "realtime");
421}
422
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800423// Verify that registering a watcher and a sender for "/test" fails.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700424TEST_P(AbstractEventLoopDeathTest, WatcherAndSender) {
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800425 auto loop = Make();
426 auto sender = loop->MakeSender<TestMessage>("/test");
427 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
428 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -0800429}
430
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700431// Verify that we can't create a sender inside OnRun.
432TEST_P(AbstractEventLoopDeathTest, SenderInOnRun) {
433 auto loop1 = MakePrimary();
434
435 loop1->OnRun(
436 [&]() { auto sender = loop1->MakeSender<TestMessage>("/test2"); });
437
438 EXPECT_DEATH(Run(), "running");
439}
440
441// Verify that we can't create a watcher inside OnRun.
442TEST_P(AbstractEventLoopDeathTest, WatcherInOnRun) {
443 auto loop1 = MakePrimary();
444
445 loop1->OnRun(
446 [&]() { loop1->MakeWatcher("/test", [&](const TestMessage &) {}); });
447
448 EXPECT_DEATH(Run(), "running");
449}
450
Parker Schuhe4a70d62017-12-27 20:10:20 -0800451// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800452TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
453 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -0700454 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800455
Austin Schuh3578a2e2019-05-25 18:17:59 -0700456 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
457 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700458 EXPECT_EQ(message.value(), 200);
Austin Schuh9fe68f72019-08-10 19:32:03 -0700459 this->Exit();
Austin Schuh3578a2e2019-05-25 18:17:59 -0700460 });
461
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800462 auto sender = loop1->MakeSender<TestMessage>("/test2");
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700463
464 loop2->OnRun([&]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700465 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
466 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
467 builder.add_value(200);
468 ASSERT_TRUE(msg.Send(builder.Finish()));
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700469 });
Parker Schuhe4a70d62017-12-27 20:10:20 -0800470
Austin Schuh44019f92019-05-19 19:58:27 -0700471 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800472}
473
Neil Balch229001a2018-01-07 18:22:52 -0800474// Verify that timer intervals and duration function properly.
475TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh44019f92019-05-19 19:58:27 -0700476 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800477 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
478
479 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
480 iteration_list.push_back(loop->monotonic_now());
481 });
482
Austin Schuh52d325c2019-06-23 18:59:06 -0700483 // TODO(austin): This should be an error... Should be done in OnRun only.
Neil Balch229001a2018-01-07 18:22:52 -0800484 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
485 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
486 // Testing that the timer thread waits for the event loop to start before
487 // running
488 ::std::this_thread::sleep_for(std::chrono::milliseconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700489 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800490
491 EXPECT_EQ(iteration_list.size(), 8);
492}
493
494// Verify that we can change a timer's parameters during execution.
495TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700496 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800497 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
498
499 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
500 iteration_list.push_back(loop->monotonic_now());
501 });
502
503 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
504 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
505 });
506
Neil Balch229001a2018-01-07 18:22:52 -0800507 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
508 modifier_timer->Setup(loop->monotonic_now() +
509 ::std::chrono::milliseconds(45));
510 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700511 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800512
513 EXPECT_EQ(iteration_list.size(), 7);
514}
515
516// Verify that we can disable a timer during execution.
517TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700518 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800519 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
520
521 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
522 iteration_list.push_back(loop->monotonic_now());
523 });
524
525 auto ender_timer = loop->AddTimer([&test_timer]() {
526 test_timer->Disable();
527 });
528
529 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
530 ender_timer->Setup(loop->monotonic_now() +
531 ::std::chrono::milliseconds(45));
532 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700533 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800534
535 EXPECT_EQ(iteration_list.size(), 3);
536}
Austin Schuh7267c532019-05-19 19:55:53 -0700537
538// Verify that the send time on a message is roughly right.
539TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700540 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700541 auto loop2 = Make();
542 auto sender = loop1->MakeSender<TestMessage>("/test");
543 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
544
545 auto test_timer = loop1->AddTimer([&sender]() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700546 aos::Sender<TestMessage>::Builder msg = sender.MakeBuilder();
547 TestMessage::Builder builder = msg.MakeBuilder<TestMessage>();
548 builder.add_value(200);
549 ASSERT_TRUE(msg.Send(builder.Finish()));
550 });
551
552 loop2->MakeWatcher("/test", [&loop2](const TestMessage &msg) {
553 // Confirm that the data pointer makes sense from a watcher.
554 EXPECT_GT(&msg, loop2->context().data);
555 EXPECT_LT(&msg, reinterpret_cast<void *>(
556 reinterpret_cast<char *>(loop2->context().data) +
557 loop2->context().size));
Austin Schuh7267c532019-05-19 19:55:53 -0700558 });
559
560 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
561
562 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700563 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700564
565 EXPECT_TRUE(fetcher.Fetch());
566
Alex Perrycb7da4b2019-08-28 19:35:56 -0700567 monotonic_clock::duration monotonic_time_offset =
568 fetcher.context().monotonic_sent_time -
569 (loop1->monotonic_now() - ::std::chrono::seconds(1));
570 realtime_clock::duration realtime_time_offset =
571 fetcher.context().realtime_sent_time -
572 (loop1->realtime_now() - ::std::chrono::seconds(1));
Austin Schuh7267c532019-05-19 19:55:53 -0700573
Alex Perrycb7da4b2019-08-28 19:35:56 -0700574 EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
575 << ": Got "
576 << fetcher.context().monotonic_sent_time.time_since_epoch().count()
Austin Schuh52d325c2019-06-23 18:59:06 -0700577 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700578 // Confirm that the data pointer makes sense.
579 EXPECT_GT(fetcher.get(), fetcher.context().data);
580 EXPECT_LT(fetcher.get(),
581 reinterpret_cast<void *>(
582 reinterpret_cast<char *>(fetcher.context().data) +
583 fetcher.context().size));
584 EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
585 << ": Got "
586 << fetcher.context().monotonic_sent_time.time_since_epoch().count()
Austin Schuh7267c532019-05-19 19:55:53 -0700587 << " expected " << loop1->monotonic_now().time_since_epoch().count();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700588
589 EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
590 << ": Got "
591 << fetcher.context().realtime_sent_time.time_since_epoch().count()
592 << " expected " << loop1->realtime_now().time_since_epoch().count();
593 EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
594 << ": Got "
595 << fetcher.context().realtime_sent_time.time_since_epoch().count()
596 << " expected " << loop1->realtime_now().time_since_epoch().count();
Austin Schuh7267c532019-05-19 19:55:53 -0700597}
598
Austin Schuh52d325c2019-06-23 18:59:06 -0700599// Tests that a couple phased loops run in a row result in the correct offset
600// and period.
601TEST_P(AbstractEventLoopTest, PhasedLoopTest) {
602 const chrono::milliseconds kOffset = chrono::milliseconds(400);
603 const int kCount = 5;
604
605 auto loop1 = MakePrimary();
606
607 // Collect up a couple of samples.
608 ::std::vector<::aos::monotonic_clock::time_point> times;
609
610 // Run kCount iterations.
611 loop1->AddPhasedLoop(
Austin Schuh9fe68f72019-08-10 19:32:03 -0700612 [&times, &loop1, this](int count) {
Austin Schuh52d325c2019-06-23 18:59:06 -0700613 EXPECT_EQ(count, 1);
614 times.push_back(loop1->monotonic_now());
Austin Schuhf257f3c2019-10-27 21:00:43 -0700615 LOG(INFO) << times.size();
Austin Schuh52d325c2019-06-23 18:59:06 -0700616 if (times.size() == kCount) {
Austin Schuh9fe68f72019-08-10 19:32:03 -0700617 this->Exit();
Austin Schuh52d325c2019-06-23 18:59:06 -0700618 }
619 },
620 chrono::seconds(1), kOffset);
621
622 // Add a delay to make sure that delay during startup doesn't result in a
623 // "missed cycle".
624 SleepFor(chrono::seconds(2));
625
626 Run();
627
628 // Confirm that we got both the right number of samples, and it's odd.
629 EXPECT_EQ(times.size(), static_cast<size_t>(kCount));
630 EXPECT_EQ((times.size() % 2), 1);
631
632 // Grab the middle sample.
633 ::aos::monotonic_clock::time_point middle_time = times[times.size() / 2 + 1];
634
635 // Add up all the delays of all the times.
636 ::aos::monotonic_clock::duration sum = chrono::seconds(0);
637 for (const ::aos::monotonic_clock::time_point time : times) {
638 sum += time - middle_time;
639 }
640
641 // Average and add to the middle to find the average time.
642 sum /= times.size();
643 middle_time += sum;
644
645 // Compute the offset from the start of the second of the average time. This
646 // should be pretty close to the offset.
647 const ::aos::monotonic_clock::duration remainder =
648 middle_time.time_since_epoch() -
649 chrono::duration_cast<chrono::seconds>(middle_time.time_since_epoch());
650
651 const chrono::milliseconds kEpsilon(100);
652 EXPECT_LT(remainder, kOffset + kEpsilon);
653 EXPECT_GT(remainder, kOffset - kEpsilon);
654
655 // Make sure that the average duration is close to 1 second.
656 EXPECT_NEAR(chrono::duration_cast<chrono::duration<double>>(times.back() -
657 times.front())
658 .count() /
659 static_cast<double>(times.size() - 1),
660 1.0, 0.1);
661}
662
Parker Schuhe4a70d62017-12-27 20:10:20 -0800663} // namespace testing
664} // namespace aos