blob: 3138c5106e09053676b61719b35a2b489a355a7f [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"
Austin Schuha9df9ad2021-06-16 14:49:39 -070010#include "aos/events/test_message_schema.h"
11#include "aos/events/timing_report_schema.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070012#include "aos/flatbuffers.h"
13#include "aos/json_to_flatbuffer.h"
Austin Schuha9df9ad2021-06-16 14:49:39 -070014#include "aos/logging/log_message_schema.h"
15#include "aos/network/message_bridge_client_schema.h"
16#include "aos/network/message_bridge_server_schema.h"
17#include "aos/network/timestamp_schema.h"
Parker Schuhe4a70d62017-12-27 20:10:20 -080018#include "gtest/gtest.h"
19
20namespace aos {
21namespace testing {
22
23class EventLoopTestFactory {
24 public:
Alex Perrycb7da4b2019-08-28 19:35:56 -070025 EventLoopTestFactory()
Austin Schuha9df9ad2021-06-16 14:49:39 -070026 : flatbuffer_(configuration::AddSchema(
27 R"config({
Brian Silverman77162972020-08-12 19:52:40 -070028 "channels": [
29 {
30 "name": "/aos",
31 "type": "aos.logging.LogMessageFbs"
32 },
33 {
34 "name": "/aos",
35 "type": "aos.timing.Report"
36 },
37 {
38 "name": "/test",
39 "type": "aos.TestMessage"
40 },
41 {
42 "name": "/test1",
43 "type": "aos.TestMessage"
44 },
45 {
46 "name": "/test2",
47 "type": "aos.TestMessage"
48 }
49 ]
Austin Schuha9df9ad2021-06-16 14:49:39 -070050})config",
51 {aos::FlatbufferSpan<reflection::Schema>(
52 logging::LogMessageFbsSchema()),
53 aos::FlatbufferSpan<reflection::Schema>(timing::ReportSchema()),
54 aos::FlatbufferSpan<reflection::Schema>(TestMessageSchema())})) {}
Alex Perrycb7da4b2019-08-28 19:35:56 -070055
Parker Schuhe4a70d62017-12-27 20:10:20 -080056 virtual ~EventLoopTestFactory() {}
57
Austin Schuh44019f92019-05-19 19:58:27 -070058 // Makes a connected event loop.
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080059 virtual std::unique_ptr<EventLoop> Make(std::string_view name) = 0;
Austin Schuh44019f92019-05-19 19:58:27 -070060 // Makes a primary event loop. This is the one the tests will try to use for
61 // anything blocking.
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080062 virtual std::unique_ptr<EventLoop> MakePrimary(std::string_view name) = 0;
Austin Schuh44019f92019-05-19 19:58:27 -070063
64 // Runs the loops until they quit.
65 virtual void Run() = 0;
Austin Schuh52d325c2019-06-23 18:59:06 -070066
Austin Schuh9fe68f72019-08-10 19:32:03 -070067 // Quits the loops.
68 virtual void Exit() = 0;
69
Austin Schuh52d325c2019-06-23 18:59:06 -070070 // Advances time by sleeping. Can't be called from inside a loop.
71 virtual void SleepFor(::std::chrono::nanoseconds duration) = 0;
Alex Perrycb7da4b2019-08-28 19:35:56 -070072
Austin Schuhd54780b2020-10-03 16:26:02 -070073 // Sets the config to a config with a max size with an invalid alignment.
74 void InvalidChannelAlignment() {
Austin Schuha9df9ad2021-06-16 14:49:39 -070075 flatbuffer_ = configuration::AddSchema(
76 R"config({
Austin Schuhd54780b2020-10-03 16:26:02 -070077 "channels": [
78 {
79 "name": "/aos",
80 "type": "aos.logging.LogMessageFbs"
81 },
82 {
83 "name": "/aos",
84 "type": "aos.timing.Report"
85 },
86 {
87 "name": "/test",
88 "type": "aos.TestMessage",
89 "max_size": 13
90 },
91 {
92 "name": "/test1",
93 "type": "aos.TestMessage"
94 },
95 {
96 "name": "/test2",
97 "type": "aos.TestMessage"
98 }
99 ]
Austin Schuha9df9ad2021-06-16 14:49:39 -0700100})config",
101 {aos::FlatbufferSpan<reflection::Schema>(
102 logging::LogMessageFbsSchema()),
103 aos::FlatbufferSpan<reflection::Schema>(timing::ReportSchema()),
104 aos::FlatbufferSpan<reflection::Schema>(TestMessageSchema())});
Austin Schuhd54780b2020-10-03 16:26:02 -0700105 }
106
Brian Silverman77162972020-08-12 19:52:40 -0700107 void PinReads() {
108 static const std::string kJson = R"config({
109 "channels": [
110 {
111 "name": "/aos",
112 "type": "aos.logging.LogMessageFbs",
113 "read_method": "PIN",
114 "num_readers": 10
115 },
116 {
117 "name": "/aos",
118 "type": "aos.timing.Report",
119 "read_method": "PIN",
120 "num_readers": 10
121 },
122 {
123 "name": "/test",
124 "type": "aos.TestMessage",
125 "read_method": "PIN",
126 "num_readers": 10
127 },
128 {
129 "name": "/test1",
130 "type": "aos.TestMessage",
131 "read_method": "PIN",
132 "num_readers": 10
133 },
134 {
135 "name": "/test2",
136 "type": "aos.TestMessage",
137 "read_method": "PIN",
138 "num_readers": 10
139 }
140 ]
141})config";
142
Austin Schuha9df9ad2021-06-16 14:49:39 -0700143 flatbuffer_ = configuration::AddSchema(
144 kJson, {aos::FlatbufferSpan<reflection::Schema>(
145 logging::LogMessageFbsSchema()),
146 aos::FlatbufferSpan<reflection::Schema>(timing::ReportSchema()),
147 aos::FlatbufferSpan<reflection::Schema>(TestMessageSchema())});
Brian Silverman77162972020-08-12 19:52:40 -0700148 }
149
Austin Schuh217a9782019-12-21 23:02:50 -0800150 void EnableNodes(std::string_view my_node) {
Brian Silverman77162972020-08-12 19:52:40 -0700151 static const std::string kJson = R"config({
Austin Schuh217a9782019-12-21 23:02:50 -0800152 "channels": [
153 {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700154 "name": "/me/aos",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800155 "type": "aos.logging.LogMessageFbs",
156 "source_node": "me"
157 },
158 {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700159 "name": "/them/aos",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800160 "type": "aos.logging.LogMessageFbs",
161 "source_node": "them"
162 },
163 {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700164 "name": "/me/aos",
165 "type": "aos.message_bridge.Timestamp",
166 "source_node": "me",
167 "destination_nodes": [
168 {
169 "name": "them"
170 }
171 ]
172 },
173 {
174 "name": "/them/aos",
175 "type": "aos.message_bridge.Timestamp",
176 "source_node": "them",
177 "destination_nodes": [
178 {
179 "name": "me"
180 }
181 ]
182 },
183 {
184 "name": "/me/aos",
185 "type": "aos.message_bridge.ServerStatistics",
186 "source_node": "me",
187 "frequency": 2
188 },
189 {
190 "name": "/them/aos",
191 "type": "aos.message_bridge.ServerStatistics",
192 "source_node": "them",
193 "frequency": 2
194 },
195 {
196 "name": "/me/aos",
197 "type": "aos.message_bridge.ClientStatistics",
198 "source_node": "me",
199 "frequency": 2
200 },
201 {
202 "name": "/them/aos",
203 "type": "aos.message_bridge.ClientStatistics",
204 "source_node": "them",
205 "frequency": 2
206 },
207 {
Austin Schuh217a9782019-12-21 23:02:50 -0800208 "name": "/aos",
209 "type": "aos.timing.Report",
210 "source_node": "me"
211 },
212 {
213 "name": "/test",
214 "type": "aos.TestMessage",
215 "source_node": "me"
216 },
217 {
218 "name": "/test1",
219 "type": "aos.TestMessage",
220 "source_node": "me"
221 },
222 {
223 "name": "/test2",
224 "type": "aos.TestMessage",
225 "source_node": "me"
226 }
227 ],
228 "nodes": [
229 {
Austin Schuh898f4972020-01-11 17:21:25 -0800230 "name": "me",
Austin Schuh217a9782019-12-21 23:02:50 -0800231 "hostname": "myhostname"
Austin Schuh898f4972020-01-11 17:21:25 -0800232 },
233 {
234 "name": "them",
235 "hostname": "themhostname"
Austin Schuh217a9782019-12-21 23:02:50 -0800236 }
Tyler Chatow67ddb032020-01-12 14:30:04 -0800237 ],
238 "maps": [
239 {
240 "match": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700241 "name": "/aos*",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800242 "source_node": "me"
243 },
244 "rename": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700245 "name": "/me/aos"
Tyler Chatow67ddb032020-01-12 14:30:04 -0800246 }
247 },
248 {
249 "match": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700250 "name": "/aos*",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800251 "source_node": "them"
252 },
253 "rename": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700254 "name": "/them/aos"
Tyler Chatow67ddb032020-01-12 14:30:04 -0800255 }
256 }
Austin Schuh217a9782019-12-21 23:02:50 -0800257 ]
258})config";
259
Austin Schuh4c3b9702020-08-30 11:34:55 -0700260 flatbuffer_ = configuration::MergeConfiguration(
Austin Schuha9df9ad2021-06-16 14:49:39 -0700261 configuration::MergeConfiguration(
262 aos::FlatbufferDetachedBuffer<Configuration>(
263 JsonToFlatbuffer<Configuration>(kJson))),
264 {aos::FlatbufferSpan<reflection::Schema>(
265 logging::LogMessageFbsSchema()),
266 aos::FlatbufferSpan<reflection::Schema>(timing::ReportSchema()),
267 aos::FlatbufferSpan<reflection::Schema>(TestMessageSchema()),
268 aos::FlatbufferSpan<reflection::Schema>(
269 message_bridge::ClientStatisticsSchema()),
270 aos::FlatbufferSpan<reflection::Schema>(
271 message_bridge::ServerStatisticsSchema()),
272 aos::FlatbufferSpan<reflection::Schema>(
273 message_bridge::TimestampSchema())});
Austin Schuh217a9782019-12-21 23:02:50 -0800274
Austin Schuhac0771c2020-01-07 18:36:30 -0800275 my_node_ = configuration::GetNode(&flatbuffer_.message(), my_node);
Austin Schuh217a9782019-12-21 23:02:50 -0800276 }
277
Austin Schuhac0771c2020-01-07 18:36:30 -0800278 const Node *my_node() const { return my_node_; }
Austin Schuh217a9782019-12-21 23:02:50 -0800279
Alex Perrycb7da4b2019-08-28 19:35:56 -0700280 const Configuration *configuration() { return &flatbuffer_.message(); }
281
282 private:
283 FlatbufferDetachedBuffer<Configuration> flatbuffer_;
Austin Schuh217a9782019-12-21 23:02:50 -0800284
Austin Schuhac0771c2020-01-07 18:36:30 -0800285 const Node *my_node_ = nullptr;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800286};
287
Austin Schuh6bae8252021-02-07 22:01:49 -0800288enum class DoTimingReports { kYes, kNo };
289
Brian Silverman4f4e0612020-08-12 19:54:41 -0700290class AbstractEventLoopTest
Brian Silverman77162972020-08-12 19:52:40 -0700291 : public ::testing::TestWithParam<
Austin Schuh6bae8252021-02-07 22:01:49 -0800292 std::tuple<std::function<EventLoopTestFactory *()>, ReadMethod,
293 DoTimingReports>> {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800294 public:
Brian Silverman4f4e0612020-08-12 19:54:41 -0700295 AbstractEventLoopTest() : factory_(std::get<0>(GetParam())()) {
Brian Silverman77162972020-08-12 19:52:40 -0700296 if (read_method() == ReadMethod::PIN) {
297 factory_->PinReads();
298 }
299 }
300
301 ReadMethod read_method() const { return std::get<1>(GetParam()); }
Austin Schuh6bae8252021-02-07 22:01:49 -0800302 DoTimingReports do_timing_reports() const { return std::get<2>(GetParam()); }
Parker Schuhe4a70d62017-12-27 20:10:20 -0800303
Brian Silverman4f4e0612020-08-12 19:54:41 -0700304 ::std::unique_ptr<EventLoop> Make(std::string_view name = "");
305
Austin Schuh5f1cc5c2019-12-01 18:01:11 -0800306 ::std::unique_ptr<EventLoop> MakePrimary(std::string_view name = "primary") {
307 ++event_loop_count_;
Austin Schuh6bae8252021-02-07 22:01:49 -0800308 auto result = factory_->MakePrimary(name);
309 if (do_timing_reports() == DoTimingReports::kNo) {
310 result->SkipTimingReport();
311 }
312 return result;
Austin Schuh5f1cc5c2019-12-01 18:01:11 -0800313 }
Austin Schuh44019f92019-05-19 19:58:27 -0700314
Austin Schuhd54780b2020-10-03 16:26:02 -0700315 void InvalidChannelAlignment() { factory_->InvalidChannelAlignment(); }
316
Austin Schuh217a9782019-12-21 23:02:50 -0800317 void EnableNodes(std::string_view my_node) { factory_->EnableNodes(my_node); }
318
Austin Schuh44019f92019-05-19 19:58:27 -0700319 void Run() { return factory_->Run(); }
Austin Schuh52d325c2019-06-23 18:59:06 -0700320
Austin Schuh9fe68f72019-08-10 19:32:03 -0700321 void Exit() { return factory_->Exit(); }
322
Austin Schuh52d325c2019-06-23 18:59:06 -0700323 void SleepFor(::std::chrono::nanoseconds duration) {
324 return factory_->SleepFor(duration);
325 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700326
Austin Schuh217a9782019-12-21 23:02:50 -0800327 const Configuration *configuration() { return factory_->configuration(); }
328
Austin Schuhac0771c2020-01-07 18:36:30 -0800329 const Node *my_node() const { return factory_->my_node(); }
Austin Schuh217a9782019-12-21 23:02:50 -0800330
Austin Schuh9fe68f72019-08-10 19:32:03 -0700331 // Ends the given event loop at the given time from now.
332 void EndEventLoop(EventLoop *loop, ::std::chrono::milliseconds duration) {
333 auto end_timer = loop->AddTimer([this]() { this->Exit(); });
Austin Schuh7d87b672019-12-01 20:23:49 -0800334 end_timer->Setup(loop->monotonic_now() + duration);
Austin Schuh39788ff2019-12-01 18:22:57 -0800335 end_timer->set_name("end");
Austin Schuh9fe68f72019-08-10 19:32:03 -0700336 }
337
Brian Silverman4f4e0612020-08-12 19:54:41 -0700338 // Verifies that the buffer_index values for all of the given objects are
339 // consistent.
340 void VerifyBuffers(
341 int number_buffers,
342 std::vector<std::reference_wrapper<const Fetcher<TestMessage>>> fetchers,
343 std::vector<std::reference_wrapper<const Sender<TestMessage>>> senders);
344
Parker Schuhe4a70d62017-12-27 20:10:20 -0800345 private:
Brian Silverman77162972020-08-12 19:52:40 -0700346 const ::std::unique_ptr<EventLoopTestFactory> factory_;
Austin Schuh5f1cc5c2019-12-01 18:01:11 -0800347
348 int event_loop_count_ = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800349};
350
Brian Silverman4f4e0612020-08-12 19:54:41 -0700351using AbstractEventLoopDeathTest = AbstractEventLoopTest;
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700352
Parker Schuhe4a70d62017-12-27 20:10:20 -0800353} // namespace testing
354} // namespace aos
355
356#endif // _AOS_EVENTS_EVENT_LOOP_PARAM_TEST_H_