blob: 78e744aff1a2c90fc607b2e51df5567fdd004f35 [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
58// Verify that making a fetcher and handler for "/test" dies.
59TEST_P(AbstractEventLoopTest, FetcherAndHandler) {
60 auto loop = Make();
61 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
62 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}), "/test");
63}
64
65// Verify that making 2 fetchers for "/test" fails.
66TEST_P(AbstractEventLoopTest, TwoFetcher) {
67 auto loop = Make();
68 auto fetcher = loop->MakeFetcher<TestMessage>("/test");
69 EXPECT_DEATH(loop->MakeFetcher<TestMessage>("/test"), "/test");
70}
71
72// Verify that registering a handler twice for "/test" fails.
73TEST_P(AbstractEventLoopTest, TwoHandler) {
74 auto loop = Make();
75 loop->MakeWatcher("/test", [&](const TestMessage &) {});
76 EXPECT_DEATH(loop->MakeWatcher("/test", [&](const TestMessage &) {}), "/test");
77}
78
79// Verify that Quit() works when there are multiple watchers.
80TEST_P(AbstractEventLoopTest, MultipleFetcherQuit) {
81 auto loop = Make();
82
83 auto sender = loop->MakeSender<TestMessage>("/test2");
84 {
85 auto msg = sender.MakeMessage();
86 msg->msg_value = 200;
87 msg.Send();
88 }
89
90 loop->MakeWatcher("/test1", [&](const TestMessage &) {});
91 loop->MakeWatcher("/test2", [&](const TestMessage &message) {
92 EXPECT_EQ(message.msg_value, 200);
93 loop->Exit();
94 });
95 loop->Run();
96}
97
Neil Balch229001a2018-01-07 18:22:52 -080098// Verify that timer intervals and duration function properly.
99TEST_P(AbstractEventLoopTest, TimerIntervalAndDuration) {
100 auto loop = Make();
101 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
102
103 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
104 iteration_list.push_back(loop->monotonic_now());
105 });
106
107 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
108 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
109 // Testing that the timer thread waits for the event loop to start before
110 // running
111 ::std::this_thread::sleep_for(std::chrono::milliseconds(2));
112 loop->Run();
113
114 EXPECT_EQ(iteration_list.size(), 8);
115}
116
117// Verify that we can change a timer's parameters during execution.
118TEST_P(AbstractEventLoopTest, TimerChangeParameters) {
119 auto loop = Make();
120 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
121
122 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
123 iteration_list.push_back(loop->monotonic_now());
124 });
125
126 auto modifier_timer = loop->AddTimer([&loop, &test_timer]() {
127 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(30));
128 });
129
130
131 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
132 modifier_timer->Setup(loop->monotonic_now() +
133 ::std::chrono::milliseconds(45));
134 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
135 loop->Run();
136
137 EXPECT_EQ(iteration_list.size(), 7);
138}
139
140// Verify that we can disable a timer during execution.
141TEST_P(AbstractEventLoopTest, TimerDisable) {
142 auto loop = Make();
143 ::std::vector<::aos::monotonic_clock::time_point> iteration_list;
144
145 auto test_timer = loop->AddTimer([&iteration_list, &loop]() {
146 iteration_list.push_back(loop->monotonic_now());
147 });
148
149 auto ender_timer = loop->AddTimer([&test_timer]() {
150 test_timer->Disable();
151 });
152
153 test_timer->Setup(loop->monotonic_now(), ::std::chrono::milliseconds(20));
154 ender_timer->Setup(loop->monotonic_now() +
155 ::std::chrono::milliseconds(45));
156 EndEventLoop(loop.get(), ::std::chrono::milliseconds(150));
157 loop->Run();
158
159 EXPECT_EQ(iteration_list.size(), 3);
160}
Parker Schuhe4a70d62017-12-27 20:10:20 -0800161} // namespace testing
162} // namespace aos