blob: a9d280e061ce11aa7fe5c91c510478c2d86f192a [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",
milind945708b2021-07-03 13:30:15 -070039 "type": "aos.TestMessage",
40 "frequency": 800
Brian Silverman77162972020-08-12 19:52:40 -070041 },
42 {
43 "name": "/test1",
44 "type": "aos.TestMessage"
45 },
46 {
47 "name": "/test2",
48 "type": "aos.TestMessage"
49 }
50 ]
Austin Schuha9df9ad2021-06-16 14:49:39 -070051})config",
52 {aos::FlatbufferSpan<reflection::Schema>(
53 logging::LogMessageFbsSchema()),
54 aos::FlatbufferSpan<reflection::Schema>(timing::ReportSchema()),
55 aos::FlatbufferSpan<reflection::Schema>(TestMessageSchema())})) {}
Alex Perrycb7da4b2019-08-28 19:35:56 -070056
Parker Schuhe4a70d62017-12-27 20:10:20 -080057 virtual ~EventLoopTestFactory() {}
58
Austin Schuh44019f92019-05-19 19:58:27 -070059 // Makes a connected event loop.
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080060 virtual std::unique_ptr<EventLoop> Make(std::string_view name) = 0;
Austin Schuh44019f92019-05-19 19:58:27 -070061 // Makes a primary event loop. This is the one the tests will try to use for
62 // anything blocking.
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080063 virtual std::unique_ptr<EventLoop> MakePrimary(std::string_view name) = 0;
Austin Schuh44019f92019-05-19 19:58:27 -070064
65 // Runs the loops until they quit.
66 virtual void Run() = 0;
Austin Schuh52d325c2019-06-23 18:59:06 -070067
Austin Schuh9fe68f72019-08-10 19:32:03 -070068 // Quits the loops.
69 virtual void Exit() = 0;
70
Austin Schuh52d325c2019-06-23 18:59:06 -070071 // Advances time by sleeping. Can't be called from inside a loop.
72 virtual void SleepFor(::std::chrono::nanoseconds duration) = 0;
Alex Perrycb7da4b2019-08-28 19:35:56 -070073
Austin Schuhd54780b2020-10-03 16:26:02 -070074 // Sets the config to a config with a max size with an invalid alignment.
75 void InvalidChannelAlignment() {
Austin Schuha9df9ad2021-06-16 14:49:39 -070076 flatbuffer_ = configuration::AddSchema(
77 R"config({
Austin Schuhd54780b2020-10-03 16:26:02 -070078 "channels": [
79 {
80 "name": "/aos",
81 "type": "aos.logging.LogMessageFbs"
82 },
83 {
84 "name": "/aos",
85 "type": "aos.timing.Report"
86 },
87 {
88 "name": "/test",
89 "type": "aos.TestMessage",
90 "max_size": 13
91 },
92 {
93 "name": "/test1",
94 "type": "aos.TestMessage"
95 },
96 {
97 "name": "/test2",
98 "type": "aos.TestMessage"
99 }
100 ]
Austin Schuha9df9ad2021-06-16 14:49:39 -0700101})config",
102 {aos::FlatbufferSpan<reflection::Schema>(
103 logging::LogMessageFbsSchema()),
104 aos::FlatbufferSpan<reflection::Schema>(timing::ReportSchema()),
105 aos::FlatbufferSpan<reflection::Schema>(TestMessageSchema())});
Austin Schuhd54780b2020-10-03 16:26:02 -0700106 }
107
Brian Silverman77162972020-08-12 19:52:40 -0700108 void PinReads() {
109 static const std::string kJson = R"config({
110 "channels": [
111 {
112 "name": "/aos",
113 "type": "aos.logging.LogMessageFbs",
114 "read_method": "PIN",
115 "num_readers": 10
116 },
117 {
118 "name": "/aos",
119 "type": "aos.timing.Report",
120 "read_method": "PIN",
121 "num_readers": 10
122 },
123 {
124 "name": "/test",
125 "type": "aos.TestMessage",
126 "read_method": "PIN",
milind945708b2021-07-03 13:30:15 -0700127 "num_readers": 10,
128 "frequency": 800
Brian Silverman77162972020-08-12 19:52:40 -0700129 },
130 {
131 "name": "/test1",
132 "type": "aos.TestMessage",
133 "read_method": "PIN",
134 "num_readers": 10
135 },
136 {
137 "name": "/test2",
138 "type": "aos.TestMessage",
139 "read_method": "PIN",
140 "num_readers": 10
141 }
142 ]
143})config";
144
Austin Schuha9df9ad2021-06-16 14:49:39 -0700145 flatbuffer_ = configuration::AddSchema(
146 kJson, {aos::FlatbufferSpan<reflection::Schema>(
147 logging::LogMessageFbsSchema()),
148 aos::FlatbufferSpan<reflection::Schema>(timing::ReportSchema()),
149 aos::FlatbufferSpan<reflection::Schema>(TestMessageSchema())});
Brian Silverman77162972020-08-12 19:52:40 -0700150 }
151
Austin Schuh217a9782019-12-21 23:02:50 -0800152 void EnableNodes(std::string_view my_node) {
Brian Silverman77162972020-08-12 19:52:40 -0700153 static const std::string kJson = R"config({
Austin Schuh217a9782019-12-21 23:02:50 -0800154 "channels": [
155 {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700156 "name": "/me/aos",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800157 "type": "aos.logging.LogMessageFbs",
158 "source_node": "me"
159 },
160 {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700161 "name": "/them/aos",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800162 "type": "aos.logging.LogMessageFbs",
163 "source_node": "them"
164 },
165 {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700166 "name": "/me/aos",
167 "type": "aos.message_bridge.Timestamp",
168 "source_node": "me",
169 "destination_nodes": [
170 {
171 "name": "them"
172 }
173 ]
174 },
175 {
176 "name": "/them/aos",
177 "type": "aos.message_bridge.Timestamp",
178 "source_node": "them",
179 "destination_nodes": [
180 {
181 "name": "me"
182 }
183 ]
184 },
185 {
186 "name": "/me/aos",
187 "type": "aos.message_bridge.ServerStatistics",
188 "source_node": "me",
189 "frequency": 2
190 },
191 {
192 "name": "/them/aos",
193 "type": "aos.message_bridge.ServerStatistics",
194 "source_node": "them",
195 "frequency": 2
196 },
197 {
198 "name": "/me/aos",
199 "type": "aos.message_bridge.ClientStatistics",
200 "source_node": "me",
201 "frequency": 2
202 },
203 {
204 "name": "/them/aos",
205 "type": "aos.message_bridge.ClientStatistics",
206 "source_node": "them",
207 "frequency": 2
208 },
209 {
Austin Schuh217a9782019-12-21 23:02:50 -0800210 "name": "/aos",
211 "type": "aos.timing.Report",
212 "source_node": "me"
213 },
214 {
215 "name": "/test",
216 "type": "aos.TestMessage",
217 "source_node": "me"
218 },
219 {
220 "name": "/test1",
221 "type": "aos.TestMessage",
222 "source_node": "me"
223 },
224 {
225 "name": "/test2",
226 "type": "aos.TestMessage",
227 "source_node": "me"
Brian Silverman631b6262021-11-10 12:25:08 -0800228 },
229 {
230 "name": "/test_forward",
231 "type": "aos.TestMessage",
232 "source_node": "them",
233 "destination_nodes": [
234 {
235 "name": "me"
236 }
237 ]
238 },
239 {
240 "name": "/test_noforward",
241 "type": "aos.TestMessage",
242 "source_node": "them"
Austin Schuh217a9782019-12-21 23:02:50 -0800243 }
244 ],
245 "nodes": [
246 {
Austin Schuh898f4972020-01-11 17:21:25 -0800247 "name": "me",
Austin Schuh217a9782019-12-21 23:02:50 -0800248 "hostname": "myhostname"
Austin Schuh898f4972020-01-11 17:21:25 -0800249 },
250 {
251 "name": "them",
252 "hostname": "themhostname"
Austin Schuh217a9782019-12-21 23:02:50 -0800253 }
Tyler Chatow67ddb032020-01-12 14:30:04 -0800254 ],
255 "maps": [
256 {
257 "match": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700258 "name": "/aos*",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800259 "source_node": "me"
260 },
261 "rename": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700262 "name": "/me/aos"
Tyler Chatow67ddb032020-01-12 14:30:04 -0800263 }
264 },
265 {
266 "match": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700267 "name": "/aos*",
Tyler Chatow67ddb032020-01-12 14:30:04 -0800268 "source_node": "them"
269 },
270 "rename": {
Austin Schuh4c3b9702020-08-30 11:34:55 -0700271 "name": "/them/aos"
Tyler Chatow67ddb032020-01-12 14:30:04 -0800272 }
273 }
Austin Schuh217a9782019-12-21 23:02:50 -0800274 ]
275})config";
276
Austin Schuh4c3b9702020-08-30 11:34:55 -0700277 flatbuffer_ = configuration::MergeConfiguration(
Austin Schuha9df9ad2021-06-16 14:49:39 -0700278 configuration::MergeConfiguration(
279 aos::FlatbufferDetachedBuffer<Configuration>(
280 JsonToFlatbuffer<Configuration>(kJson))),
281 {aos::FlatbufferSpan<reflection::Schema>(
282 logging::LogMessageFbsSchema()),
283 aos::FlatbufferSpan<reflection::Schema>(timing::ReportSchema()),
284 aos::FlatbufferSpan<reflection::Schema>(TestMessageSchema()),
285 aos::FlatbufferSpan<reflection::Schema>(
286 message_bridge::ClientStatisticsSchema()),
287 aos::FlatbufferSpan<reflection::Schema>(
288 message_bridge::ServerStatisticsSchema()),
289 aos::FlatbufferSpan<reflection::Schema>(
290 message_bridge::TimestampSchema())});
Austin Schuh217a9782019-12-21 23:02:50 -0800291
Austin Schuhac0771c2020-01-07 18:36:30 -0800292 my_node_ = configuration::GetNode(&flatbuffer_.message(), my_node);
Austin Schuh217a9782019-12-21 23:02:50 -0800293 }
294
Austin Schuhac0771c2020-01-07 18:36:30 -0800295 const Node *my_node() const { return my_node_; }
Austin Schuh217a9782019-12-21 23:02:50 -0800296
Alex Perrycb7da4b2019-08-28 19:35:56 -0700297 const Configuration *configuration() { return &flatbuffer_.message(); }
298
299 private:
300 FlatbufferDetachedBuffer<Configuration> flatbuffer_;
Austin Schuh217a9782019-12-21 23:02:50 -0800301
Austin Schuhac0771c2020-01-07 18:36:30 -0800302 const Node *my_node_ = nullptr;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800303};
304
Austin Schuh6bae8252021-02-07 22:01:49 -0800305enum class DoTimingReports { kYes, kNo };
306
Brian Silverman4f4e0612020-08-12 19:54:41 -0700307class AbstractEventLoopTest
Brian Silverman77162972020-08-12 19:52:40 -0700308 : public ::testing::TestWithParam<
Austin Schuh6bae8252021-02-07 22:01:49 -0800309 std::tuple<std::function<EventLoopTestFactory *()>, ReadMethod,
310 DoTimingReports>> {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800311 public:
Brian Silverman4f4e0612020-08-12 19:54:41 -0700312 AbstractEventLoopTest() : factory_(std::get<0>(GetParam())()) {
Brian Silverman77162972020-08-12 19:52:40 -0700313 if (read_method() == ReadMethod::PIN) {
314 factory_->PinReads();
315 }
316 }
317
318 ReadMethod read_method() const { return std::get<1>(GetParam()); }
Austin Schuh6bae8252021-02-07 22:01:49 -0800319 DoTimingReports do_timing_reports() const { return std::get<2>(GetParam()); }
Parker Schuhe4a70d62017-12-27 20:10:20 -0800320
Brian Silverman4f4e0612020-08-12 19:54:41 -0700321 ::std::unique_ptr<EventLoop> Make(std::string_view name = "");
322
Austin Schuh5f1cc5c2019-12-01 18:01:11 -0800323 ::std::unique_ptr<EventLoop> MakePrimary(std::string_view name = "primary") {
324 ++event_loop_count_;
Austin Schuh6bae8252021-02-07 22:01:49 -0800325 auto result = factory_->MakePrimary(name);
326 if (do_timing_reports() == DoTimingReports::kNo) {
327 result->SkipTimingReport();
328 }
329 return result;
Austin Schuh5f1cc5c2019-12-01 18:01:11 -0800330 }
Austin Schuh44019f92019-05-19 19:58:27 -0700331
Austin Schuhd54780b2020-10-03 16:26:02 -0700332 void InvalidChannelAlignment() { factory_->InvalidChannelAlignment(); }
333
Austin Schuh217a9782019-12-21 23:02:50 -0800334 void EnableNodes(std::string_view my_node) { factory_->EnableNodes(my_node); }
335
Austin Schuh44019f92019-05-19 19:58:27 -0700336 void Run() { return factory_->Run(); }
Austin Schuh52d325c2019-06-23 18:59:06 -0700337
Austin Schuh9fe68f72019-08-10 19:32:03 -0700338 void Exit() { return factory_->Exit(); }
339
Austin Schuh52d325c2019-06-23 18:59:06 -0700340 void SleepFor(::std::chrono::nanoseconds duration) {
341 return factory_->SleepFor(duration);
342 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700343
Austin Schuh217a9782019-12-21 23:02:50 -0800344 const Configuration *configuration() { return factory_->configuration(); }
345
Austin Schuhac0771c2020-01-07 18:36:30 -0800346 const Node *my_node() const { return factory_->my_node(); }
Austin Schuh217a9782019-12-21 23:02:50 -0800347
Austin Schuh9fe68f72019-08-10 19:32:03 -0700348 // Ends the given event loop at the given time from now.
349 void EndEventLoop(EventLoop *loop, ::std::chrono::milliseconds duration) {
350 auto end_timer = loop->AddTimer([this]() { this->Exit(); });
Austin Schuh7d87b672019-12-01 20:23:49 -0800351 end_timer->Setup(loop->monotonic_now() + duration);
Austin Schuh39788ff2019-12-01 18:22:57 -0800352 end_timer->set_name("end");
Austin Schuh9fe68f72019-08-10 19:32:03 -0700353 }
354
Brian Silverman4f4e0612020-08-12 19:54:41 -0700355 // Verifies that the buffer_index values for all of the given objects are
356 // consistent.
357 void VerifyBuffers(
358 int number_buffers,
359 std::vector<std::reference_wrapper<const Fetcher<TestMessage>>> fetchers,
360 std::vector<std::reference_wrapper<const Sender<TestMessage>>> senders);
361
Parker Schuhe4a70d62017-12-27 20:10:20 -0800362 private:
Brian Silverman77162972020-08-12 19:52:40 -0700363 const ::std::unique_ptr<EventLoopTestFactory> factory_;
Austin Schuh5f1cc5c2019-12-01 18:01:11 -0800364
365 int event_loop_count_ = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800366};
367
Brian Silverman4f4e0612020-08-12 19:54:41 -0700368using AbstractEventLoopDeathTest = AbstractEventLoopTest;
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700369
Parker Schuhe4a70d62017-12-27 20:10:20 -0800370} // namespace testing
371} // namespace aos
372
373#endif // _AOS_EVENTS_EVENT_LOOP_PARAM_TEST_H_