blob: efac8f9393bb7feb40c0d57e1593a4f1da6f9cb8 [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
10 void Zero() { msg_value = 0; }
11 static size_t Size() { return 1 + ::aos::Message::Size(); }
12 size_t Print(char *buffer, size_t length) const;
13 TestMessage() { Zero(); }
14};
15
Neil Balch229001a2018-01-07 18:22:52 -080016// Ends the given event loop at the given time from now.
17void EndEventLoop(EventLoop *loop, ::std::chrono::milliseconds duration) {
18 auto end_timer = loop->AddTimer([loop]() { loop->Exit(); });
19 end_timer->Setup(loop->monotonic_now() +
20 ::std::chrono::milliseconds(duration));
21}
22
Parker Schuhe4a70d62017-12-27 20:10:20 -080023// Tests that watcher and fetcher can fetch from a sender.
24// Also tests that OnRun() works.
25TEST_P(AbstractEventLoopTest, Basic) {
26 auto loop1 = Make();
27 auto loop2 = Make();
28 auto loop3 = Make();
29
30 auto sender = loop1->MakeSender<TestMessage>("/test");
31
32 auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
33
34 auto msg = sender.MakeMessage();
35
36 msg->msg_value = 200;
37
38 msg.Send();
39
40 EXPECT_TRUE(fetcher.Fetch());
41 ASSERT_FALSE(fetcher.get() == nullptr);
42 EXPECT_EQ(fetcher->msg_value, 200);
43
44 bool happened = false;
45
46 loop3->OnRun([&]() { happened = true; });
47
48 loop3->MakeWatcher("/test", [&](const TestMessage &message) {
49 EXPECT_EQ(message.msg_value, 200);
50 loop3->Exit();
51 });
52
53 EXPECT_FALSE(happened);
54 loop3->Run();
55 EXPECT_TRUE(happened);
56}
57
Austin Schuh81fc9cc2019-02-02 23:25:47 -080058// Verify that making a fetcher and watcher for "/test" succeeds.
59TEST_P(AbstractEventLoopTest, FetcherAndWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -080060 auto loop = Make();
61 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -080062 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Parker Schuhe4a70d62017-12-27 20:10:20 -080063}
64
Austin Schuh81fc9cc2019-02-02 23:25:47 -080065// Verify that making 2 fetchers for "/test" succeeds.
Parker Schuhe4a70d62017-12-27 20:10:20 -080066TEST_P(AbstractEventLoopTest, TwoFetcher) {
67 auto loop = Make();
68 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
Austin Schuh81fc9cc2019-02-02 23:25:47 -080069 auto fetcher2 = loop->MakeFetcher<TestMessage>("/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -080070}
71
Austin Schuh81fc9cc2019-02-02 23:25:47 -080072// Verify that registering a watcher twice for "/test" fails.
73TEST_P(AbstractEventLoopTest, TwoWatcher) {
Parker Schuhe4a70d62017-12-27 20:10:20 -080074 auto loop = Make();
75 loop->MakeWatcher("/test", [&](const TestMessage &) {});
Austin Schuh81fc9cc2019-02-02 23:25:47 -080076 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
77 "/test");
78}
79
80// Verify that registering a watcher and a sender for "/test" fails.
81TEST_P(AbstractEventLoopTest, WatcherAndSender) {
82 auto loop = Make();
83 auto sender = loop->MakeSender<TestMessage>("/test");
84 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}),
85 "/test");
Parker Schuhe4a70d62017-12-27 20:10:20 -080086}
87
88// Verify that Quit() works when there are multiple watchers.
Austin Schuh81fc9cc2019-02-02 23:25:47 -080089TEST_P(AbstractEventLoopTest, MultipleWatcherQuit) {
90 auto loop1 = Make();
91 auto loop2 = Make();
Parker Schuhe4a70d62017-12-27 20:10:20 -080092
Austin Schuh81fc9cc2019-02-02 23:25:47 -080093 auto sender = loop1->MakeSender<TestMessage>("/test2");
Parker Schuhe4a70d62017-12-27 20:10:20 -080094 {
95 auto msg = sender.MakeMessage();
96 msg->msg_value = 200;
97 msg.Send();
98 }
99
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800100 loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
101 loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800102 EXPECT_EQ(message.msg_value, 200);
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800103 loop2->Exit();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800104 });
Austin Schuh81fc9cc2019-02-02 23:25:47 -0800105 loop2->Run();
Parker Schuhe4a70d62017-12-27 20:10:20 -0800106}
107
Neil Balch229001a2018-01-07 18:22:52 -0800108// Verify that timer intervals and duration function properly.
109TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
110 auto loop = Make();
111 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
112
113 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
114 iteration_list.push_back(loop->monotonic_now());
115 });
116
117 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
118 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
119 // Testing that the timer thread waits for the event loop to start before
120 // running
121 ::std::this_thread::sleep_for(std::chrono::milliseconds(2));
122 loop->Run();
123
124 EXPECT_EQ(iteration_list.size(), 8);
125}
126
127// Verify that we can change a timer's parameters during execution.
128TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
129 auto loop = Make();
130 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
131
132 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
133 iteration_list.push_back(loop->monotonic_now());
134 });
135
136 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
137 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
138 });
139
140
141 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
142 modifier_timer->Setup(loop->monotonic_now() +
143 ::std::chrono::milliseconds(45));
144 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
145 loop->Run();
146
147 EXPECT_EQ(iteration_list.size(), 7);
148}
149
150// Verify that we can disable a timer during execution.
151TEST_P(AbstractEventLoopTest, TimerDisable) {
152 auto loop = Make();
153 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
154
155 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
156 iteration_list.push_back(loop->monotonic_now());
157 });
158
159 auto ender_timer = loop->AddTimer([&test_timer]() {
160 test_timer->Disable();
161 });
162
163 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
164 ender_timer->Setup(loop->monotonic_now() +
165 ::std::chrono::milliseconds(45));
166 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
167 loop->Run();
168
169 EXPECT_EQ(iteration_list.size(), 3);
170}
Parker Schuhe4a70d62017-12-27 20:10:20 -0800171} // namespace testing
172} // namespace aos