blob: 57d0525b3f327c370e94a739fd513657c670c333 [file] [log] [blame]
Parker Schuhe4a70d62017-12-27 20:10:20 -08001#ifndef _AOS_EVENTS_EVENT_LOOP_PARAM_TEST_H_
2#define _AOS_EVENTS_EVENT_LOOP_PARAM_TEST_H_
3
Brian Silverman4f4e0612020-08-12 19:54:41 -07004#include <initializer_list>
Austin Schuh5f1cc5c2019-12-01 18:01:11 -08005#include <string_view>
Neil Balch229001a2018-01-07 18:22:52 -08006#include <vector>
7
Alex Perrycb7da4b2019-08-28 19:35:56 -07008#include "aos/events/event_loop.h"
Brian Silverman4f4e0612020-08-12 19:54:41 -07009#include "aos/events/test_message_generated.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070010#include "aos/flatbuffers.h"
11#include "aos/json_to_flatbuffer.h"
Parker Schuhe4a70d62017-12-27 20:10:20 -080012#include "gtest/gtest.h"
13
14namespace aos {
15namespace testing {
16
17class EventLoopTestFactory {
18 public:
Alex Perrycb7da4b2019-08-28 19:35:56 -070019 EventLoopTestFactory()
Brian Silverman77162972020-08-12 19:52:40 -070020 : flatbuffer_(JsonToFlatbuffer<Configuration>(R"config({
21 "channels": [
22 {
23 "name": "/aos",
24 "type": "aos.logging.LogMessageFbs"
25 },
26 {
27 "name": "/aos",
28 "type": "aos.timing.Report"
29 },
30 {
31 "name": "/test",
32 "type": "aos.TestMessage"
33 },
34 {
35 "name": "/test1",
36 "type": "aos.TestMessage"
37 },
38 {
39 "name": "/test2",
40 "type": "aos.TestMessage"
41 }
42 ]
43})config")) {}
Alex Perrycb7da4b2019-08-28 19:35:56 -070044
Parker Schuhe4a70d62017-12-27 20:10:20 -080045 virtual ~EventLoopTestFactory() {}
46
Austin Schuh44019f92019-05-19 19:58:27 -070047 // Makes a connected event loop.
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080048 virtual std::unique_ptr<EventLoop> Make(std::string_view name) = 0;
Austin Schuh44019f92019-05-19 19:58:27 -070049 // Makes a primary event loop. This is the one the tests will try to use for
50 // anything blocking.
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080051 virtual std::unique_ptr<EventLoop> MakePrimary(std::string_view name) = 0;
Austin Schuh44019f92019-05-19 19:58:27 -070052
53 // Runs the loops until they quit.
54 virtual void Run() = 0;
Austin Schuh52d325c2019-06-23 18:59:06 -070055
Austin Schuh9fe68f72019-08-10 19:32:03 -070056 // Quits the loops.
57 virtual void Exit() = 0;
58
Austin Schuh52d325c2019-06-23 18:59:06 -070059 // Advances time by sleeping. Can't be called from inside a loop.
60 virtual void SleepFor(::std::chrono::nanoseconds duration) = 0;
Alex Perrycb7da4b2019-08-28 19:35:56 -070061
Brian Silverman77162972020-08-12 19:52:40 -070062 void PinReads() {
63 static const std::string kJson = R"config({
64 "channels": [
65 {
66 "name": "/aos",
67 "type": "aos.logging.LogMessageFbs",
68 "read_method": "PIN",
69 "num_readers": 10
70 },
71 {
72 "name": "/aos",
73 "type": "aos.timing.Report",
74 "read_method": "PIN",
75 "num_readers": 10
76 },
77 {
78 "name": "/test",
79 "type": "aos.TestMessage",
80 "read_method": "PIN",
81 "num_readers": 10
82 },
83 {
84 "name": "/test1",
85 "type": "aos.TestMessage",
86 "read_method": "PIN",
87 "num_readers": 10
88 },
89 {
90 "name": "/test2",
91 "type": "aos.TestMessage",
92 "read_method": "PIN",
93 "num_readers": 10
94 }
95 ]
96})config";
97
98 flatbuffer_ = FlatbufferDetachedBuffer<Configuration>(
99 JsonToFlatbuffer(kJson, Configuration::MiniReflectTypeTable()));
100 }
101
Austin Schuh217a9782019-12-21 23:02:50 -0800102 void EnableNodes(std::string_view my_node) {
Brian Silverman77162972020-08-12 19:52:40 -0700103 static const std::string kJson = R"config({
Austin Schuh217a9782019-12-21 23:02:50 -0800104 "channels": [
105 {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700106 "name": "/me/aos",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800107 "type": "aos.logging.LogMessageFbs",
108 "source_node": "me"
109 },
110 {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700111 "name": "/them/aos",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800112 "type": "aos.logging.LogMessageFbs",
113 "source_node": "them"
114 },
115 {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700116 "name": "/me/aos",
117 "type": "aos.message_bridge.Timestamp",
118 "source_node": "me",
119 "destination_nodes": [
120 {
121 "name": "them"
122 }
123 ]
124 },
125 {
126 "name": "/them/aos",
127 "type": "aos.message_bridge.Timestamp",
128 "source_node": "them",
129 "destination_nodes": [
130 {
131 "name": "me"
132 }
133 ]
134 },
135 {
136 "name": "/me/aos",
137 "type": "aos.message_bridge.ServerStatistics",
138 "source_node": "me",
139 "frequency": 2
140 },
141 {
142 "name": "/them/aos",
143 "type": "aos.message_bridge.ServerStatistics",
144 "source_node": "them",
145 "frequency": 2
146 },
147 {
148 "name": "/me/aos",
149 "type": "aos.message_bridge.ClientStatistics",
150 "source_node": "me",
151 "frequency": 2
152 },
153 {
154 "name": "/them/aos",
155 "type": "aos.message_bridge.ClientStatistics",
156 "source_node": "them",
157 "frequency": 2
158 },
159 {
Austin Schuh217a9782019-12-21 23:02:50 -0800160 "name": "/aos",
161 "type": "aos.timing.Report",
162 "source_node": "me"
163 },
164 {
165 "name": "/test",
166 "type": "aos.TestMessage",
167 "source_node": "me"
168 },
169 {
170 "name": "/test1",
171 "type": "aos.TestMessage",
172 "source_node": "me"
173 },
174 {
175 "name": "/test2",
176 "type": "aos.TestMessage",
177 "source_node": "me"
178 }
179 ],
180 "nodes": [
181 {
Austin Schuh898f4972020-01-11 17:21:25 -0800182 "name": "me",
Austin Schuh217a9782019-12-21 23:02:50 -0800183 "hostname": "myhostname"
Austin Schuh898f4972020-01-11 17:21:25 -0800184 },
185 {
186 "name": "them",
187 "hostname": "themhostname"
Austin Schuh217a9782019-12-21 23:02:50 -0800188 }
Tyler Chatow67ddb032020-01-12 14:30:04 -0800189 ],
190 "maps": [
191 {
192 "match": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700193 "name": "/aos*",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800194 "source_node": "me"
195 },
196 "rename": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700197 "name": "/me/aos"
Tyler Chatow67ddb032020-01-12 14:30:04 -0800198 }
199 },
200 {
201 "match": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700202 "name": "/aos*",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800203 "source_node": "them"
204 },
205 "rename": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700206 "name": "/them/aos"
Tyler Chatow67ddb032020-01-12 14:30:04 -0800207 }
208 }
Austin Schuh217a9782019-12-21 23:02:50 -0800209 ]
210})config";
211
Austin Schuh4c3b9702020-08-30 11:34:55 -0700212 flatbuffer_ = configuration::MergeConfiguration(
213 FlatbufferDetachedBuffer<Configuration>(
214 JsonToFlatbuffer(kJson, Configuration::MiniReflectTypeTable())));
Austin Schuh217a9782019-12-21 23:02:50 -0800215
Austin Schuhac0771c2020-01-07 18:36:30 -0800216 my_node_ = configuration::GetNode(&flatbuffer_.message(), my_node);
Austin Schuh217a9782019-12-21 23:02:50 -0800217 }
218
Austin Schuhac0771c2020-01-07 18:36:30 -0800219 const Node *my_node() const { return my_node_; }
Austin Schuh217a9782019-12-21 23:02:50 -0800220
Alex Perrycb7da4b2019-08-28 19:35:56 -0700221 const Configuration *configuration() { return &flatbuffer_.message(); }
222
223 private:
224 FlatbufferDetachedBuffer<Configuration> flatbuffer_;
Austin Schuh217a9782019-12-21 23:02:50 -0800225
Austin Schuhac0771c2020-01-07 18:36:30 -0800226 const Node *my_node_ = nullptr;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800227};
228
Brian Silverman4f4e0612020-08-12 19:54:41 -0700229class AbstractEventLoopTest
Brian Silverman77162972020-08-12 19:52:40 -0700230 : public ::testing::TestWithParam<
231 std::tuple<std::function<EventLoopTestFactory *()>, ReadMethod>> {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800232 public:
Brian Silverman4f4e0612020-08-12 19:54:41 -0700233 AbstractEventLoopTest() : factory_(std::get<0>(GetParam())()) {
Brian Silverman77162972020-08-12 19:52:40 -0700234 if (read_method() == ReadMethod::PIN) {
235 factory_->PinReads();
236 }
237 }
238
239 ReadMethod read_method() const { return std::get<1>(GetParam()); }
Parker Schuhe4a70d62017-12-27 20:10:20 -0800240
Brian Silverman4f4e0612020-08-12 19:54:41 -0700241 ::std::unique_ptr<EventLoop> Make(std::string_view name = "");
242
Austin Schuh5f1cc5c2019-12-01 18:01:11 -0800243 ::std::unique_ptr<EventLoop> MakePrimary(std::string_view name = "primary") {
244 ++event_loop_count_;
245 return factory_->MakePrimary(name);
246 }
Austin Schuh44019f92019-05-19 19:58:27 -0700247
Austin Schuh217a9782019-12-21 23:02:50 -0800248 void EnableNodes(std::string_view my_node) { factory_->EnableNodes(my_node); }
249
Austin Schuh44019f92019-05-19 19:58:27 -0700250 void Run() { return factory_->Run(); }
Austin Schuh52d325c2019-06-23 18:59:06 -0700251
Austin Schuh9fe68f72019-08-10 19:32:03 -0700252 void Exit() { return factory_->Exit(); }
253
Austin Schuh52d325c2019-06-23 18:59:06 -0700254 void SleepFor(::std::chrono::nanoseconds duration) {
255 return factory_->SleepFor(duration);
256 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700257
Austin Schuh217a9782019-12-21 23:02:50 -0800258 const Configuration *configuration() { return factory_->configuration(); }
259
Austin Schuhac0771c2020-01-07 18:36:30 -0800260 const Node *my_node() const { return factory_->my_node(); }
Austin Schuh217a9782019-12-21 23:02:50 -0800261
Austin Schuh9fe68f72019-08-10 19:32:03 -0700262 // Ends the given event loop at the given time from now.
263 void EndEventLoop(EventLoop *loop, ::std::chrono::milliseconds duration) {
264 auto end_timer = loop->AddTimer([this]() { this->Exit(); });
Austin Schuh7d87b672019-12-01 20:23:49 -0800265 end_timer->Setup(loop->monotonic_now() + duration);
Austin Schuh39788ff2019-12-01 18:22:57 -0800266 end_timer->set_name("end");
Austin Schuh9fe68f72019-08-10 19:32:03 -0700267 }
268
Brian Silverman4f4e0612020-08-12 19:54:41 -0700269 // Verifies that the buffer_index values for all of the given objects are
270 // consistent.
271 void VerifyBuffers(
272 int number_buffers,
273 std::vector<std::reference_wrapper<const Fetcher<TestMessage>>> fetchers,
274 std::vector<std::reference_wrapper<const Sender<TestMessage>>> senders);
275
Parker Schuhe4a70d62017-12-27 20:10:20 -0800276 private:
Brian Silverman77162972020-08-12 19:52:40 -0700277 const ::std::unique_ptr<EventLoopTestFactory> factory_;
Austin Schuh5f1cc5c2019-12-01 18:01:11 -0800278
279 int event_loop_count_ = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800280};
281
Brian Silverman4f4e0612020-08-12 19:54:41 -0700282using AbstractEventLoopDeathTest = AbstractEventLoopTest;
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700283
Parker Schuhe4a70d62017-12-27 20:10:20 -0800284} // namespace testing
285} // namespace aos
286
287#endif // _AOS_EVENTS_EVENT_LOOP_PARAM_TEST_H_