blob: 6f1e5be1104f6fd7debae7e9092377e92b2e3f2c [file] [log] [blame]
Parker Schuhe4a70d62017-12-27 20:10:20 -08001#include "aos/events/event-loop_param_test.h"
2
3namespace aos {
4namespace testing {
5
6struct TestMessage : public ::aos::Message {
7 enum { kQueueLength = 100, kHash = 0x696c0cdc };
8 int msg_value;
9
Austin Schuh7267c532019-05-19 19:55:53 -070010 void Zero() {
11 ::aos::Message::Zero();
12 msg_value = 0;
13 }
Parker Schuhe4a70d62017-12-27 20:10:20 -080014 static size_t Size() { return 1 + ::aos::Message::Size(); }
15 size_t Print(char *buffer, size_t length) const;
16 TestMessage() { Zero(); }
17};
18
Neil Balch229001a2018-01-07 18:22:52 -080019// Ends the given event loop at the given time from now.
20void EndEventLoop(EventLoop *loop, ::std::chrono::milliseconds duration) {
21 auto end_timer = loop->AddTimer([loop]() { loop->Exit(); });
22 end_timer->Setup(loop->monotonic_now() +
23 ::std::chrono::milliseconds(duration));
24}
25
Parker Schuhe4a70d62017-12-27 20:10:20 -080026// Tests that watcher and fetcher can fetch from a sender.
27// Also tests that OnRun() works.
28TEST_P(AbstractEventLoopTest, Basic) {
29 auto loop1 = Make();
30 auto loop2 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -070031 auto loop3 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -080032
33 auto sender = loop1->MakeSender<TestMessage>("/test");
34
35 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
36
37 auto msg = sender.MakeMessage();
38
39 msg->msg_value = 200;
40
41 msg.Send();
42
43 EXPECT_TRUE(fetcher.Fetch());
44 ASSERT_FALSE(fetcher.get() == nullptr);
45 EXPECT_EQ(fetcher->msg_value, 200);
46
47 bool happened = false;
48
49 loop3->OnRun([&]() { happened = true; });
50
51 loop3->MakeWatcher("/test", [&](const TestMessage &message) {
52 EXPECT_EQ(message.msg_value, 200);
53 loop3->Exit();
54 });
55
56 EXPECT_FALSE(happened);
Austin Schuh44019f92019-05-19 19:58:27 -070057 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -080058 EXPECT_TRUE(happened);
59}
60
Austin Schuh81fc9cc2019-02-02 23:25:47 -080061// Verify that making a fetcher and watcher for "/test" succeeds.
62TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -080063 auto loop = Make();
64 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -080065 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -080066}
67
Austin Schuh81fc9cc2019-02-02 23:25:47 -080068// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -080069TEST_P(AbstractEventLoopTest, TwoFetcher) {
70 auto loop = Make();
71 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -080072 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -080073}
74
Austin Schuh81fc9cc2019-02-02 23:25:47 -080075// Verify that registering a watcher twice for "/test" fails.
76TEST_P(AbstractEventLoopTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -080077 auto loop = Make();
78 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -080079 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
80 "/test");
81}
82
83// Verify that registering a watcher and a sender for "/test" fails.
84TEST_P(AbstractEventLoopTest, WatcherAndSender) {
85 auto loop = Make();
86 auto sender = loop->MakeSender<TestMessage>("/test");
87 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
88 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -080089}
90
91// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -080092TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
93 auto loop1 = Make();
Austin Schuh44019f92019-05-19 19:58:27 -070094 auto loop2 = MakePrimary();
Parker Schuhe4a70d62017-12-27 20:10:20 -080095
Austin Schuh81fc9cc2019-02-02 23:25:47 -080096 auto sender = loop1->MakeSender<TestMessage>("/test2");
Parker Schuhe4a70d62017-12-27 20:10:20 -080097 {
98 auto msg = sender.MakeMessage();
99 msg->msg_value = 200;
100 msg.Send();
101 }
102
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800103 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
104 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800105 EXPECT_EQ(message.msg_value, 200);
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800106 loop2->Exit();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800107 });
Austin Schuh44019f92019-05-19 19:58:27 -0700108 Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800109}
110
Neil Balch229001a2018-01-07 18:22:52 -0800111// Verify that timer intervals and duration function properly.
112TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
Austin Schuh44019f92019-05-19 19:58:27 -0700113 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800114 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
115
116 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
117 iteration_list.push_back(loop->monotonic_now());
118 });
119
120 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
121 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
122 // Testing that the timer thread waits for the event loop to start before
123 // running
124 ::std::this_thread::sleep_for(std::chrono::milliseconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700125 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800126
127 EXPECT_EQ(iteration_list.size(), 8);
128}
129
130// Verify that we can change a timer's parameters during execution.
131TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
Austin Schuh44019f92019-05-19 19:58:27 -0700132 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800133 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
134
135 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
136 iteration_list.push_back(loop->monotonic_now());
137 });
138
139 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
140 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
141 });
142
143
144 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
145 modifier_timer->Setup(loop->monotonic_now() +
146 ::std::chrono::milliseconds(45));
147 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700148 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800149
150 EXPECT_EQ(iteration_list.size(), 7);
151}
152
153// Verify that we can disable a timer during execution.
154TEST_P(AbstractEventLoopTest, TimerDisable) {
Austin Schuh44019f92019-05-19 19:58:27 -0700155 auto loop = MakePrimary();
Neil Balch229001a2018-01-07 18:22:52 -0800156 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
157
158 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
159 iteration_list.push_back(loop->monotonic_now());
160 });
161
162 auto ender_timer = loop->AddTimer([&test_timer]() {
163 test_timer->Disable();
164 });
165
166 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
167 ender_timer->Setup(loop->monotonic_now() +
168 ::std::chrono::milliseconds(45));
169 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
Austin Schuh44019f92019-05-19 19:58:27 -0700170 Run();
Neil Balch229001a2018-01-07 18:22:52 -0800171
172 EXPECT_EQ(iteration_list.size(), 3);
173}
Austin Schuh7267c532019-05-19 19:55:53 -0700174
175// Verify that the send time on a message is roughly right.
176TEST_P(AbstractEventLoopTest, MessageSendTime) {
Austin Schuh44019f92019-05-19 19:58:27 -0700177 auto loop1 = MakePrimary();
Austin Schuh7267c532019-05-19 19:55:53 -0700178 auto loop2 = Make();
179 auto sender = loop1->MakeSender<TestMessage>("/test");
180 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
181
182 auto test_timer = loop1->AddTimer([&sender]() {
183 auto msg = sender.MakeMessage();
184 msg->msg_value = 200;
185 msg.Send();
186 });
187
188 test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
189
190 EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Austin Schuh44019f92019-05-19 19:58:27 -0700191 Run();
Austin Schuh7267c532019-05-19 19:55:53 -0700192
193 EXPECT_TRUE(fetcher.Fetch());
194
195 monotonic_clock::duration time_offset =
196 fetcher->sent_time - (loop1->monotonic_now() - ::std::chrono::seconds(1));
197
198 EXPECT_TRUE(time_offset > ::std::chrono::milliseconds(-500))
199 << ": Got " << fetcher->sent_time.time_since_epoch().count() << " expected "
200 << loop1->monotonic_now().time_since_epoch().count();
201 EXPECT_TRUE(time_offset < ::std::chrono::milliseconds(500))
202 << ": Got " << fetcher->sent_time.time_since_epoch().count()
203 << " expected " << loop1->monotonic_now().time_since_epoch().count();
204}
205
Parker Schuhe4a70d62017-12-27 20:10:20 -0800206} // namespace testing
207} // namespace aos