blob: faf6361c65f73b4ae3ee17fb20b4d51d5162715e [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 {
Tyler Chatow67ddb032020-01-12 14:30:04 -0800106 "name": "/aos/me",
107 "type": "aos.logging.LogMessageFbs",
108 "source_node": "me"
109 },
110 {
111 "name": "/aos/them",
112 "type": "aos.logging.LogMessageFbs",
113 "source_node": "them"
114 },
115 {
Austin Schuh217a9782019-12-21 23:02:50 -0800116 "name": "/aos",
117 "type": "aos.timing.Report",
118 "source_node": "me"
119 },
120 {
121 "name": "/test",
122 "type": "aos.TestMessage",
123 "source_node": "me"
124 },
125 {
126 "name": "/test1",
127 "type": "aos.TestMessage",
128 "source_node": "me"
129 },
130 {
131 "name": "/test2",
132 "type": "aos.TestMessage",
133 "source_node": "me"
134 }
135 ],
136 "nodes": [
137 {
Austin Schuh898f4972020-01-11 17:21:25 -0800138 "name": "me",
Austin Schuh217a9782019-12-21 23:02:50 -0800139 "hostname": "myhostname"
Austin Schuh898f4972020-01-11 17:21:25 -0800140 },
141 {
142 "name": "them",
143 "hostname": "themhostname"
Austin Schuh217a9782019-12-21 23:02:50 -0800144 }
Tyler Chatow67ddb032020-01-12 14:30:04 -0800145 ],
146 "maps": [
147 {
148 "match": {
149 "name": "/aos",
150 "type": "aos.logging.LogMessageFbs",
151 "source_node": "me"
152 },
153 "rename": {
154 "name": "/aos/me"
155 }
156 },
157 {
158 "match": {
159 "name": "/aos",
160 "type": "aos.logging.LogMessageFbs",
161 "source_node": "them"
162 },
163 "rename": {
164 "name": "/aos/them"
165 }
166 }
Austin Schuh217a9782019-12-21 23:02:50 -0800167 ]
168})config";
169
170 flatbuffer_ = FlatbufferDetachedBuffer<Configuration>(
Brian Silverman77162972020-08-12 19:52:40 -0700171 JsonToFlatbuffer(kJson, Configuration::MiniReflectTypeTable()));
Austin Schuh217a9782019-12-21 23:02:50 -0800172
Austin Schuhac0771c2020-01-07 18:36:30 -0800173 my_node_ = configuration::GetNode(&flatbuffer_.message(), my_node);
Austin Schuh217a9782019-12-21 23:02:50 -0800174 }
175
Austin Schuhac0771c2020-01-07 18:36:30 -0800176 const Node *my_node() const { return my_node_; }
Austin Schuh217a9782019-12-21 23:02:50 -0800177
Alex Perrycb7da4b2019-08-28 19:35:56 -0700178 const Configuration *configuration() { return &flatbuffer_.message(); }
179
180 private:
181 FlatbufferDetachedBuffer<Configuration> flatbuffer_;
Austin Schuh217a9782019-12-21 23:02:50 -0800182
Austin Schuhac0771c2020-01-07 18:36:30 -0800183 const Node *my_node_ = nullptr;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800184};
185
Brian Silverman4f4e0612020-08-12 19:54:41 -0700186class AbstractEventLoopTest
Brian Silverman77162972020-08-12 19:52:40 -0700187 : public ::testing::TestWithParam<
188 std::tuple<std::function<EventLoopTestFactory *()>, ReadMethod>> {
Parker Schuhe4a70d62017-12-27 20:10:20 -0800189 public:
Brian Silverman4f4e0612020-08-12 19:54:41 -0700190 AbstractEventLoopTest() : factory_(std::get<0>(GetParam())()) {
Brian Silverman77162972020-08-12 19:52:40 -0700191 if (read_method() == ReadMethod::PIN) {
192 factory_->PinReads();
193 }
194 }
195
196 ReadMethod read_method() const { return std::get<1>(GetParam()); }
Parker Schuhe4a70d62017-12-27 20:10:20 -0800197
Brian Silverman4f4e0612020-08-12 19:54:41 -0700198 ::std::unique_ptr<EventLoop> Make(std::string_view name = "");
199
Austin Schuh5f1cc5c2019-12-01 18:01:11 -0800200 ::std::unique_ptr<EventLoop> MakePrimary(std::string_view name = "primary") {
201 ++event_loop_count_;
202 return factory_->MakePrimary(name);
203 }
Austin Schuh44019f92019-05-19 19:58:27 -0700204
Austin Schuh217a9782019-12-21 23:02:50 -0800205 void EnableNodes(std::string_view my_node) { factory_->EnableNodes(my_node); }
206
Austin Schuh44019f92019-05-19 19:58:27 -0700207 void Run() { return factory_->Run(); }
Austin Schuh52d325c2019-06-23 18:59:06 -0700208
Austin Schuh9fe68f72019-08-10 19:32:03 -0700209 void Exit() { return factory_->Exit(); }
210
Austin Schuh52d325c2019-06-23 18:59:06 -0700211 void SleepFor(::std::chrono::nanoseconds duration) {
212 return factory_->SleepFor(duration);
213 }
Austin Schuh9fe68f72019-08-10 19:32:03 -0700214
Austin Schuh217a9782019-12-21 23:02:50 -0800215 const Configuration *configuration() { return factory_->configuration(); }
216
Austin Schuhac0771c2020-01-07 18:36:30 -0800217 const Node *my_node() const { return factory_->my_node(); }
Austin Schuh217a9782019-12-21 23:02:50 -0800218
Austin Schuh9fe68f72019-08-10 19:32:03 -0700219 // Ends the given event loop at the given time from now.
220 void EndEventLoop(EventLoop *loop, ::std::chrono::milliseconds duration) {
221 auto end_timer = loop->AddTimer([this]() { this->Exit(); });
Austin Schuh7d87b672019-12-01 20:23:49 -0800222 end_timer->Setup(loop->monotonic_now() + duration);
Austin Schuh39788ff2019-12-01 18:22:57 -0800223 end_timer->set_name("end");
Austin Schuh9fe68f72019-08-10 19:32:03 -0700224 }
225
Brian Silverman4f4e0612020-08-12 19:54:41 -0700226 // Verifies that the buffer_index values for all of the given objects are
227 // consistent.
228 void VerifyBuffers(
229 int number_buffers,
230 std::vector<std::reference_wrapper<const Fetcher<TestMessage>>> fetchers,
231 std::vector<std::reference_wrapper<const Sender<TestMessage>>> senders);
232
Parker Schuhe4a70d62017-12-27 20:10:20 -0800233 private:
Brian Silverman77162972020-08-12 19:52:40 -0700234 const ::std::unique_ptr<EventLoopTestFactory> factory_;
Austin Schuh5f1cc5c2019-12-01 18:01:11 -0800235
236 int event_loop_count_ = 0;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800237};
238
Brian Silverman4f4e0612020-08-12 19:54:41 -0700239using AbstractEventLoopDeathTest = AbstractEventLoopTest;
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700240
Parker Schuhe4a70d62017-12-27 20:10:20 -0800241} // namespace testing
242} // namespace aos
243
244#endif // _AOS_EVENTS_EVENT_LOOP_PARAM_TEST_H_