blob: b4930580eb65cbc6336a278a749b15ac48ad9696 [file] [log] [blame]
Austin Schuhcb108412019-10-13 16:09:54 -07001#include "aos/configuration.h"
2
3#include "absl/strings/strip.h"
4#include "aos/json_to_flatbuffer.h"
Austin Schuh1ef01ef2021-02-07 20:40:36 -08005#include "aos/testing/flatbuffer_eq.h"
Austin Schuh373f1762021-06-02 21:07:09 -07006#include "aos/testing/path.h"
Austin Schuhcb108412019-10-13 16:09:54 -07007#include "aos/testing/test_logging.h"
8#include "aos/util/file.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -07009#include "flatbuffers/reflection.h"
10#include "glog/logging.h"
Austin Schuhe84c3ed2019-12-14 15:29:48 -080011#include "gmock/gmock.h"
Austin Schuh1ef01ef2021-02-07 20:40:36 -080012#include "gtest/gtest.h"
Austin Schuhcb108412019-10-13 16:09:54 -070013
14namespace aos {
15namespace configuration {
16namespace testing {
17
Austin Schuh373f1762021-06-02 21:07:09 -070018using aos::testing::ArtifactPath;
Austin Schuh66602132020-02-28 13:38:37 -080019
Austin Schuhcb108412019-10-13 16:09:54 -070020class ConfigurationTest : public ::testing::Test {
21 public:
22 ConfigurationTest() { ::aos::testing::EnableTestLogging(); }
23};
24
25typedef ConfigurationTest ConfigurationDeathTest;
26
27// *the* expected location for all working tests.
Austin Schuh1ef01ef2021-02-07 20:40:36 -080028aos::FlatbufferDetachedBuffer<Channel> ExpectedLocation() {
29 return JsonToFlatbuffer<Channel>(
30 "{ \"name\": \"/foo\", \"type\": \".aos.bar\", \"max_size\": 5 }");
31}
32
Austin Schuhbca6cf02019-12-22 17:28:34 -080033// And for multinode setups
Austin Schuh1ef01ef2021-02-07 20:40:36 -080034aos::FlatbufferDetachedBuffer<Channel> ExpectedMultinodeLocation() {
35 return JsonToFlatbuffer<Channel>(
36 "{ \"name\": \"/foo\", \"type\": \".aos.bar\", \"max_size\": 5, "
37 "\"source_node\": \"pi1\" }");
38}
Austin Schuhcb108412019-10-13 16:09:54 -070039
40// Tests that we can read and merge a configuration.
41TEST_F(ConfigurationTest, ConfigMerge) {
Austin Schuh40485ed2019-10-26 21:51:44 -070042 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -070043 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Ravago Jonescf453ab2020-05-06 21:14:53 -070044 LOG(INFO) << "Read: " << FlatbufferToJson(config, {.multi_line = true});
Austin Schuhcb108412019-10-13 16:09:54 -070045
Austin Schuh373f1762021-06-02 21:07:09 -070046 EXPECT_EQ(absl::StripSuffix(util::ReadFileToStringOrDie(
47 ArtifactPath("aos/testdata/expected.json")),
48 "\n"),
49 FlatbufferToJson(config, {.multi_line = true}));
Austin Schuhcb108412019-10-13 16:09:54 -070050}
51
Austin Schuhc9e10ec2020-01-26 16:08:28 -080052// Tests that we can get back a ChannelIndex.
53TEST_F(ConfigurationTest, ChannelIndex) {
54 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -070055 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -080056
57 EXPECT_EQ(
58 ChannelIndex(&config.message(), config.message().channels()->Get(1u)),
59 1u);
60}
61
Austin Schuh217a9782019-12-21 23:02:50 -080062// Tests that we can read and merge a multinode configuration.
63TEST_F(ConfigurationTest, ConfigMergeMultinode) {
64 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -070065 ReadConfig(ArtifactPath("aos/testdata/config1_multinode.json"));
Ravago Jonescf453ab2020-05-06 21:14:53 -070066 LOG(INFO) << "Read: " << FlatbufferToJson(config, {.multi_line = true});
Austin Schuh217a9782019-12-21 23:02:50 -080067
Ravago Jonescf453ab2020-05-06 21:14:53 -070068 EXPECT_EQ(std::string(absl::StripSuffix(
Austin Schuh373f1762021-06-02 21:07:09 -070069 util::ReadFileToStringOrDie(
70 ArtifactPath("aos/testdata/expected_multinode.json")),
Ravago Jonescf453ab2020-05-06 21:14:53 -070071 "\n")),
72 FlatbufferToJson(config, {.multi_line = true}));
Austin Schuh217a9782019-12-21 23:02:50 -080073}
74
Alex Perrycb7da4b2019-08-28 19:35:56 -070075// Tests that we sort the entries in a config so we can look entries up.
76TEST_F(ConfigurationTest, UnsortedConfig) {
77 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -070078 ReadConfig(ArtifactPath("aos/testdata/backwards.json"));
Alex Perrycb7da4b2019-08-28 19:35:56 -070079
Ravago Jonescf453ab2020-05-06 21:14:53 -070080 LOG(INFO) << "Read: " << FlatbufferToJson(config, {.multi_line = true});
Alex Perrycb7da4b2019-08-28 19:35:56 -070081
Austin Schuhf1fff282020-03-28 16:57:32 -070082 EXPECT_EQ(FlatbufferToJson(GetChannel(config, "/aos/robot_state",
Austin Schuhbca6cf02019-12-22 17:28:34 -080083 "aos.RobotState", "app1", nullptr)),
Austin Schuhf1fff282020-03-28 16:57:32 -070084 "{ \"name\": \"/aos/robot_state\", \"type\": \"aos.RobotState\", "
Alex Perrycb7da4b2019-08-28 19:35:56 -070085 "\"max_size\": 5 }");
86}
87
Austin Schuhcb108412019-10-13 16:09:54 -070088// Tests that we die when a file is imported twice.
89TEST_F(ConfigurationDeathTest, DuplicateFile) {
90 EXPECT_DEATH(
91 {
Austin Schuh40485ed2019-10-26 21:51:44 -070092 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -070093 ReadConfig(ArtifactPath("aos/testdata/config1_bad.json"));
Austin Schuhcb108412019-10-13 16:09:54 -070094 },
Austin Schuh373f1762021-06-02 21:07:09 -070095 "aos/testdata/config1_bad.json");
Austin Schuhcb108412019-10-13 16:09:54 -070096}
97
Milind Upadhyay17098ba2022-04-15 22:18:50 -070098// Tests that we die when we give an invalid path.
99TEST_F(ConfigurationDeathTest, NonexistentFile) {
100 EXPECT_DEATH(
101 {
102 FlatbufferDetachedBuffer<Configuration> config =
103 ReadConfig("nonexistent/config.json");
104 },
105 "above error");
106}
107
108// Tests that we return std::nullopt when we give an invalid path.
109TEST_F(ConfigurationTest, NonexistentFileOptional) {
110 std::optional<FlatbufferDetachedBuffer<Configuration>> config =
111 MaybeReadConfig("nonexistent/config.json");
112 EXPECT_FALSE(config.has_value());
113}
114
Austin Schuhf1fff282020-03-28 16:57:32 -0700115// Tests that we reject invalid channel names. This means any channels with //
116// in their name, a trailing /, or regex characters.
117TEST_F(ConfigurationDeathTest, InvalidChannelName) {
118 EXPECT_DEATH(
119 {
120 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700121 ReadConfig(ArtifactPath("aos/testdata/invalid_channel_name1.json"));
Austin Schuhf1fff282020-03-28 16:57:32 -0700122 },
123 "Channel names can't end with '/'");
124 EXPECT_DEATH(
125 {
126 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700127 ReadConfig(ArtifactPath("aos/testdata/invalid_channel_name2.json"));
Austin Schuhf1fff282020-03-28 16:57:32 -0700128 },
129 "Invalid channel name");
130 EXPECT_DEATH(
131 {
132 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700133 ReadConfig(ArtifactPath("aos/testdata/invalid_channel_name3.json"));
Austin Schuhf1fff282020-03-28 16:57:32 -0700134 LOG(FATAL) << "Foo";
135 },
136 "Invalid channel name");
137}
138
Austin Schuh8d6cea82020-02-28 12:17:16 -0800139// Tests that we can modify a config with a json snippet.
140TEST_F(ConfigurationTest, MergeWithConfig) {
141 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700142 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Ravago Jonescf453ab2020-05-06 21:14:53 -0700143 LOG(INFO) << "Read: " << FlatbufferToJson(config, {.multi_line = true});
Austin Schuh8d6cea82020-02-28 12:17:16 -0800144
145 FlatbufferDetachedBuffer<Configuration> updated_config =
146 MergeWithConfig(&config.message(),
147 R"channel({
148 "channels": [
149 {
150 "name": "/foo",
151 "type": ".aos.bar",
152 "max_size": 100
153 }
154 ]
155})channel");
156
Austin Schuh373f1762021-06-02 21:07:09 -0700157 EXPECT_EQ(absl::StripSuffix(util::ReadFileToStringOrDie(ArtifactPath(
158 "aos/testdata/expected_merge_with.json")),
Ravago Jonescf453ab2020-05-06 21:14:53 -0700159 "\n"),
160 FlatbufferToJson(updated_config, {.multi_line = true}));
Austin Schuh8d6cea82020-02-28 12:17:16 -0800161}
162
Austin Schuhcb108412019-10-13 16:09:54 -0700163// Tests that we can lookup a location, complete with maps, from a merged
164// config.
Austin Schuh40485ed2019-10-26 21:51:44 -0700165TEST_F(ConfigurationTest, GetChannel) {
166 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700167 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Austin Schuhcb108412019-10-13 16:09:54 -0700168
169 // Test a basic lookup first.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800170 EXPECT_THAT(GetChannel(config, "/foo", ".aos.bar", "app1", nullptr),
171 aos::testing::FlatbufferEq(ExpectedLocation()));
Austin Schuhcb108412019-10-13 16:09:54 -0700172
173 // Test that an invalid name results in nullptr back.
Austin Schuhbca6cf02019-12-22 17:28:34 -0800174 EXPECT_EQ(GetChannel(config, "/invalid_name", ".aos.bar", "app1", nullptr),
175 nullptr);
Austin Schuhcb108412019-10-13 16:09:54 -0700176
177 // Tests that a root map/rename works. And that they get processed from the
178 // bottom up.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800179 EXPECT_THAT(GetChannel(config, "/batman", ".aos.bar", "app1", nullptr),
180 aos::testing::FlatbufferEq(ExpectedLocation()));
Austin Schuhcb108412019-10-13 16:09:54 -0700181
182 // And then test that an application specific map/rename works.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800183 EXPECT_THAT(GetChannel(config, "/bar", ".aos.bar", "app1", nullptr),
184 aos::testing::FlatbufferEq(ExpectedLocation()));
185 EXPECT_THAT(GetChannel(config, "/baz", ".aos.bar", "app2", nullptr),
186 aos::testing::FlatbufferEq(ExpectedLocation()));
Austin Schuhcb108412019-10-13 16:09:54 -0700187
188 // And then test that an invalid application name gets properly ignored.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800189 EXPECT_THAT(GetChannel(config, "/foo", ".aos.bar", "app3", nullptr),
190 aos::testing::FlatbufferEq(ExpectedLocation()));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800191}
192
193// Tests that we can lookup a location with node specific maps.
194TEST_F(ConfigurationTest, GetChannelMultinode) {
195 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700196 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800197 const Node *pi1 = GetNode(&config.message(), "pi1");
198 const Node *pi2 = GetNode(&config.message(), "pi2");
199
200 // Test a basic lookup first.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800201 EXPECT_THAT(GetChannel(config, "/foo", ".aos.bar", "app1", pi1),
202 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
203 EXPECT_THAT(GetChannel(config, "/foo", ".aos.bar", "app1", pi2),
204 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800205
206 // Tests that a root map/rename works with a node specific map.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800207 EXPECT_THAT(GetChannel(config, "/batman", ".aos.bar", "app1", pi1),
208 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800209
210 // Tests that a root map/rename fails with a node specific map for the wrong
211 // node.
212 EXPECT_EQ(GetChannel(config, "/batman", ".aos.bar", "app1", pi2), nullptr);
213
214 // And then test that an application specific map/rename works.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800215 EXPECT_THAT(GetChannel(config, "/batman2", ".aos.bar", "app1", pi1),
216 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
217 EXPECT_THAT(GetChannel(config, "/batman3", ".aos.bar", "app1", pi1),
218 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800219
220 // And then that it fails when the node changes.
221 EXPECT_EQ(GetChannel(config, "/batman3", ".aos.bar", "app1", pi2), nullptr);
222}
223
224// Tests that we can lookup a location with type specific maps.
225TEST_F(ConfigurationTest, GetChannelTypedMultinode) {
226 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700227 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800228 const Node *pi1 = GetNode(&config.message(), "pi1");
229
230 // Test a basic lookup first.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800231 EXPECT_THAT(GetChannel(config, "/batman", ".aos.bar", "app1", pi1),
232 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800233
234 // Now confirm that a second message on the same name doesn't get remapped.
235 const char *kExpectedBazMultinodeLocation =
236 "{ \"name\": \"/batman\", \"type\": \".aos.baz\", \"max_size\": 5, "
237 "\"source_node\": \"pi1\" }";
238 EXPECT_EQ(
239 FlatbufferToJson(GetChannel(config, "/batman", ".aos.baz", "app1", pi1)),
240 kExpectedBazMultinodeLocation);
Austin Schuhcb108412019-10-13 16:09:54 -0700241}
242
Austin Schuhf1fff282020-03-28 16:57:32 -0700243// Tests that we can lookup a location with a glob
244TEST_F(ConfigurationTest, GetChannelGlob) {
245 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700246 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhf1fff282020-03-28 16:57:32 -0700247 const Node *pi1 = GetNode(&config.message(), "pi1");
248
249 // Confirm that a glob with nothing after it matches.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800250 EXPECT_THAT(GetChannel(config, "/magic/string", ".aos.bar", "app7", pi1),
251 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
Austin Schuhf1fff282020-03-28 16:57:32 -0700252
253 // Now confirm that glob with something following it matches and renames
254 // correctly.
255 const char *kExpectedSubfolderMultinodeLocation =
256 "{ \"name\": \"/foo/subfolder\", \"type\": \".aos.bar\", \"max_size\": "
257 "5, \"source_node\": \"pi1\" }";
258 EXPECT_EQ(FlatbufferToJson(GetChannel(config, "/magic/string/subfolder",
259 ".aos.bar", "app7", pi1)),
260 kExpectedSubfolderMultinodeLocation);
261}
262
Austin Schuh217a9782019-12-21 23:02:50 -0800263// Tests that we reject a configuration which has a nodes list, but has channels
264// withoout source_node filled out.
265TEST_F(ConfigurationDeathTest, InvalidSourceNode) {
266 EXPECT_DEATH(
267 {
268 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700269 ReadConfig(ArtifactPath("aos/testdata/invalid_nodes.json"));
Austin Schuh217a9782019-12-21 23:02:50 -0800270 },
271 "source_node");
272
273 EXPECT_DEATH(
274 {
275 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700276 ReadConfig(ArtifactPath("aos/testdata/invalid_source_node.json"));
Austin Schuh217a9782019-12-21 23:02:50 -0800277 },
278 "source_node");
279
280 EXPECT_DEATH(
281 {
Austin Schuh373f1762021-06-02 21:07:09 -0700282 FlatbufferDetachedBuffer<Configuration> config = ReadConfig(
283 ArtifactPath("aos/testdata/invalid_destination_node.json"));
Austin Schuh217a9782019-12-21 23:02:50 -0800284 },
285 "destination_nodes");
286
287 EXPECT_DEATH(
288 {
289 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700290 ReadConfig(ArtifactPath("aos/testdata/self_forward.json"));
Austin Schuh217a9782019-12-21 23:02:50 -0800291 },
292 "forwarding data to itself");
293}
294
295// Tests that our node writeable helpers work as intended.
296TEST_F(ConfigurationTest, ChannelIsSendableOnNode) {
297 FlatbufferDetachedBuffer<Channel> good_channel(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800298 R"channel({
Austin Schuh217a9782019-12-21 23:02:50 -0800299 "name": "/test",
300 "type": "aos.examples.Ping",
301 "source_node": "foo"
302})channel",
303 Channel::MiniReflectTypeTable()));
304
305 FlatbufferDetachedBuffer<Channel> bad_channel(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800306 R"channel({
Austin Schuh217a9782019-12-21 23:02:50 -0800307 "name": "/test",
308 "type": "aos.examples.Ping",
309 "source_node": "bar"
310})channel",
311 Channel::MiniReflectTypeTable()));
312
313 FlatbufferDetachedBuffer<Node> node(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800314 R"node({
Austin Schuh217a9782019-12-21 23:02:50 -0800315 "name": "foo"
316})node",
317 Node::MiniReflectTypeTable()));
318
319 EXPECT_TRUE(
320 ChannelIsSendableOnNode(&good_channel.message(), &node.message()));
321 EXPECT_FALSE(
322 ChannelIsSendableOnNode(&bad_channel.message(), &node.message()));
323}
324
325// Tests that our node readable and writeable helpers work as intended.
326TEST_F(ConfigurationTest, ChannelIsReadableOnNode) {
327 FlatbufferDetachedBuffer<Channel> good_channel(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800328 R"channel({
Austin Schuh217a9782019-12-21 23:02:50 -0800329 "name": "/test",
330 "type": "aos.examples.Ping",
331 "source_node": "bar",
332 "destination_nodes": [
Austin Schuh719946b2019-12-28 14:51:01 -0800333 {
334 "name": "baz"
335 },
336 {
337 "name": "foo"
338 }
Austin Schuh217a9782019-12-21 23:02:50 -0800339 ]
340})channel",
341 Channel::MiniReflectTypeTable()));
342
343 FlatbufferDetachedBuffer<Channel> bad_channel1(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800344 R"channel({
Austin Schuh217a9782019-12-21 23:02:50 -0800345 "name": "/test",
346 "type": "aos.examples.Ping",
347 "source_node": "bar"
348})channel",
349 Channel::MiniReflectTypeTable()));
350
351 FlatbufferDetachedBuffer<Channel> bad_channel2(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800352 R"channel({
Austin Schuh217a9782019-12-21 23:02:50 -0800353 "name": "/test",
354 "type": "aos.examples.Ping",
355 "source_node": "bar",
356 "destination_nodes": [
Austin Schuh719946b2019-12-28 14:51:01 -0800357 {
358 "name": "baz"
359 }
Austin Schuh217a9782019-12-21 23:02:50 -0800360 ]
361})channel",
362 Channel::MiniReflectTypeTable()));
363
364 FlatbufferDetachedBuffer<Node> node(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800365 R"node({
Austin Schuh217a9782019-12-21 23:02:50 -0800366 "name": "foo"
367})node",
368 Node::MiniReflectTypeTable()));
369
370 EXPECT_TRUE(
371 ChannelIsReadableOnNode(&good_channel.message(), &node.message()));
372 EXPECT_FALSE(
373 ChannelIsReadableOnNode(&bad_channel1.message(), &node.message()));
374 EXPECT_FALSE(
375 ChannelIsReadableOnNode(&bad_channel2.message(), &node.message()));
376}
377
Austin Schuh719946b2019-12-28 14:51:01 -0800378// Tests that our node message is logged helpers work as intended.
379TEST_F(ConfigurationTest, ChannelMessageIsLoggedOnNode) {
380 FlatbufferDetachedBuffer<Channel> logged_on_self_channel(JsonToFlatbuffer(
381 R"channel({
382 "name": "/test",
383 "type": "aos.examples.Ping",
384 "source_node": "bar",
385 "destination_nodes": [
386 {
387 "name": "baz"
388 }
389 ]
390})channel",
391 Channel::MiniReflectTypeTable()));
Austin Schuh217a9782019-12-21 23:02:50 -0800392
Austin Schuh719946b2019-12-28 14:51:01 -0800393 FlatbufferDetachedBuffer<Channel> not_logged_channel(JsonToFlatbuffer(
394 R"channel({
395 "name": "/test",
396 "type": "aos.examples.Ping",
397 "source_node": "bar",
398 "logger": "NOT_LOGGED",
399 "destination_nodes": [
400 {
401 "name": "baz",
402 "timestamp_logger": "LOCAL_LOGGER"
403 }
404 ]
405})channel",
406 Channel::MiniReflectTypeTable()));
407
408 FlatbufferDetachedBuffer<Channel> logged_on_remote_channel(JsonToFlatbuffer(
409 R"channel({
410 "name": "/test",
411 "type": "aos.examples.Ping",
412 "source_node": "bar",
413 "logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700414 "logger_nodes": ["baz"],
Austin Schuh719946b2019-12-28 14:51:01 -0800415 "destination_nodes": [
416 {
417 "name": "baz"
418 }
419 ]
420})channel",
421 Channel::MiniReflectTypeTable()));
422
423 FlatbufferDetachedBuffer<Channel> logged_on_separate_logger_node_channel(
424 JsonToFlatbuffer(
425 R"channel({
426 "name": "/test",
427 "type": "aos.examples.Ping",
428 "source_node": "bar",
429 "logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700430 "logger_nodes": ["foo"],
Austin Schuh719946b2019-12-28 14:51:01 -0800431 "destination_nodes": [
432 {
433 "name": "baz"
434 }
435 ]
436})channel",
437 Channel::MiniReflectTypeTable()));
438
Ravago Jonescf453ab2020-05-06 21:14:53 -0700439 FlatbufferDetachedBuffer<Channel> logged_on_both_channel(JsonToFlatbuffer(
440 R"channel({
Austin Schuh719946b2019-12-28 14:51:01 -0800441 "name": "/test",
442 "type": "aos.examples.Ping",
443 "source_node": "bar",
444 "logger": "LOCAL_AND_REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700445 "logger_nodes": ["baz"],
Austin Schuh719946b2019-12-28 14:51:01 -0800446 "destination_nodes": [
447 {
448 "name": "baz"
449 }
450 ]
451})channel",
Ravago Jonescf453ab2020-05-06 21:14:53 -0700452 Channel::MiniReflectTypeTable()));
Austin Schuh719946b2019-12-28 14:51:01 -0800453
454 FlatbufferDetachedBuffer<Node> foo_node(JsonToFlatbuffer(
455 R"node({
456 "name": "foo"
457})node",
458 Node::MiniReflectTypeTable()));
459
460 FlatbufferDetachedBuffer<Node> bar_node(JsonToFlatbuffer(
461 R"node({
462 "name": "bar"
463})node",
464 Node::MiniReflectTypeTable()));
465
466 FlatbufferDetachedBuffer<Node> baz_node(JsonToFlatbuffer(
467 R"node({
468 "name": "baz"
469})node",
470 Node::MiniReflectTypeTable()));
471
472 // Local logger.
473 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&logged_on_self_channel.message(),
474 &foo_node.message()));
475 EXPECT_TRUE(ChannelMessageIsLoggedOnNode(&logged_on_self_channel.message(),
476 &bar_node.message()));
477 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&logged_on_self_channel.message(),
478 &baz_node.message()));
Austin Schuh48e94502021-06-18 18:35:53 -0700479 EXPECT_TRUE(
480 ChannelMessageIsLoggedOnNode(&logged_on_self_channel.message(), nullptr));
Austin Schuh719946b2019-12-28 14:51:01 -0800481
482 // No logger.
483 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&not_logged_channel.message(),
484 &foo_node.message()));
485 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&not_logged_channel.message(),
Ravago Jonescf453ab2020-05-06 21:14:53 -0700486 &bar_node.message()));
Austin Schuh719946b2019-12-28 14:51:01 -0800487 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&not_logged_channel.message(),
488 &baz_node.message()));
Austin Schuh48e94502021-06-18 18:35:53 -0700489 EXPECT_FALSE(
490 ChannelMessageIsLoggedOnNode(&not_logged_channel.message(), nullptr));
Austin Schuh719946b2019-12-28 14:51:01 -0800491
492 // Remote logger.
493 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&logged_on_remote_channel.message(),
494 &foo_node.message()));
495 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&logged_on_remote_channel.message(),
496 &bar_node.message()));
497 EXPECT_TRUE(ChannelMessageIsLoggedOnNode(&logged_on_remote_channel.message(),
498 &baz_node.message()));
499
500 // Separate logger.
501 EXPECT_TRUE(ChannelMessageIsLoggedOnNode(
502 &logged_on_separate_logger_node_channel.message(), &foo_node.message()));
503 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(
504 &logged_on_separate_logger_node_channel.message(), &bar_node.message()));
505 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(
506 &logged_on_separate_logger_node_channel.message(), &baz_node.message()));
507
508 // Logged in multiple places.
509 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&logged_on_both_channel.message(),
510 &foo_node.message()));
511 EXPECT_TRUE(ChannelMessageIsLoggedOnNode(&logged_on_both_channel.message(),
512 &bar_node.message()));
513 EXPECT_TRUE(ChannelMessageIsLoggedOnNode(&logged_on_both_channel.message(),
514 &baz_node.message()));
515}
516
Austin Schuh48e94502021-06-18 18:35:53 -0700517// Tests that our node message is logged helpers work as intended.
518TEST_F(ConfigurationDeathTest, ChannelMessageIsLoggedOnNode) {
519 FlatbufferDetachedBuffer<Channel> logged_on_both_channel(JsonToFlatbuffer(
520 R"channel({
521 "name": "/test",
522 "type": "aos.examples.Ping",
523 "source_node": "bar",
524 "logger": "LOCAL_AND_REMOTE_LOGGER",
525 "logger_nodes": ["baz"],
526 "destination_nodes": [
527 {
528 "name": "baz"
529 }
530 ]
531})channel",
532 Channel::MiniReflectTypeTable()));
533
534 FlatbufferDetachedBuffer<Channel> logged_on_separate_logger_node_channel(
535 JsonToFlatbuffer(
536 R"channel({
537 "name": "/test",
538 "type": "aos.examples.Ping",
539 "source_node": "bar",
540 "logger": "REMOTE_LOGGER",
541 "logger_nodes": ["foo"],
542 "destination_nodes": [
543 {
544 "name": "baz"
545 }
546 ]
547})channel",
548 Channel::MiniReflectTypeTable()));
549
550 EXPECT_DEATH(
551 {
552 ChannelMessageIsLoggedOnNode(&logged_on_both_channel.message(),
553 nullptr);
554 },
555 "Unsupported logging configuration in a single node world");
556 EXPECT_DEATH(
557 {
558 ChannelMessageIsLoggedOnNode(
559 &logged_on_separate_logger_node_channel.message(), nullptr);
560 },
561 "Unsupported logging configuration in a single node world");
562}
563
Austin Schuh719946b2019-12-28 14:51:01 -0800564// Tests that our forwarding timestamps are logged helpers work as intended.
565TEST_F(ConfigurationTest, ConnectionDeliveryTimeIsLoggedOnNode) {
566 FlatbufferDetachedBuffer<Channel> logged_on_self_channel(JsonToFlatbuffer(
567 R"channel({
568 "name": "/test",
569 "type": "aos.examples.Ping",
570 "source_node": "bar",
571 "logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700572 "logger_nodes": ["baz"],
Austin Schuh719946b2019-12-28 14:51:01 -0800573 "destination_nodes": [
574 {
575 "name": "baz"
576 }
577 ]
578})channel",
579 Channel::MiniReflectTypeTable()));
580
581 FlatbufferDetachedBuffer<Channel> not_logged_channel(JsonToFlatbuffer(
582 R"channel({
583 "name": "/test",
584 "type": "aos.examples.Ping",
585 "source_node": "bar",
586 "logger": "NOT_LOGGED",
587 "destination_nodes": [
588 {
589 "name": "baz",
590 "timestamp_logger": "NOT_LOGGED"
591 }
592 ]
593})channel",
594 Channel::MiniReflectTypeTable()));
595
596 FlatbufferDetachedBuffer<Channel> logged_on_remote_channel(JsonToFlatbuffer(
597 R"channel({
598 "name": "/test",
599 "type": "aos.examples.Ping",
600 "source_node": "bar",
601 "destination_nodes": [
602 {
603 "name": "baz",
604 "timestamp_logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700605 "timestamp_logger_nodes": ["bar"]
Austin Schuh719946b2019-12-28 14:51:01 -0800606 }
607 ]
608})channel",
609 Channel::MiniReflectTypeTable()));
610
611 FlatbufferDetachedBuffer<Channel> logged_on_separate_logger_node_channel(
612 JsonToFlatbuffer(
613 R"channel({
614 "name": "/test",
615 "type": "aos.examples.Ping",
616 "source_node": "bar",
617 "logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700618 "logger_nodes": ["foo"],
Austin Schuh719946b2019-12-28 14:51:01 -0800619 "destination_nodes": [
620 {
621 "name": "baz",
622 "timestamp_logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700623 "timestamp_logger_nodes": ["foo"]
Austin Schuh719946b2019-12-28 14:51:01 -0800624 }
625 ]
626})channel",
627 Channel::MiniReflectTypeTable()));
628
Ravago Jonescf453ab2020-05-06 21:14:53 -0700629 FlatbufferDetachedBuffer<Channel> logged_on_both_channel(JsonToFlatbuffer(
630 R"channel({
Austin Schuh719946b2019-12-28 14:51:01 -0800631 "name": "/test",
632 "type": "aos.examples.Ping",
633 "source_node": "bar",
634 "destination_nodes": [
635 {
636 "name": "baz",
637 "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700638 "timestamp_logger_nodes": ["bar"]
Austin Schuh719946b2019-12-28 14:51:01 -0800639 }
640 ]
641})channel",
Ravago Jonescf453ab2020-05-06 21:14:53 -0700642 Channel::MiniReflectTypeTable()));
Austin Schuh719946b2019-12-28 14:51:01 -0800643
644 FlatbufferDetachedBuffer<Node> foo_node(JsonToFlatbuffer(
645 R"node({
646 "name": "foo"
647})node",
648 Node::MiniReflectTypeTable()));
649
650 FlatbufferDetachedBuffer<Node> bar_node(JsonToFlatbuffer(
651 R"node({
652 "name": "bar"
653})node",
654 Node::MiniReflectTypeTable()));
655
656 FlatbufferDetachedBuffer<Node> baz_node(JsonToFlatbuffer(
657 R"node({
658 "name": "baz"
659})node",
660 Node::MiniReflectTypeTable()));
661
662 // Local logger.
663 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
664 &logged_on_self_channel.message(), &baz_node.message(),
665 &foo_node.message()));
666 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
667 &logged_on_self_channel.message(), &baz_node.message(),
668 &bar_node.message()));
669 EXPECT_TRUE(ConnectionDeliveryTimeIsLoggedOnNode(
670 &logged_on_self_channel.message(), &baz_node.message(),
671 &baz_node.message()));
672
673 // No logger means.
674 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
675 &not_logged_channel.message(), &baz_node.message(), &foo_node.message()));
676 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
677 &not_logged_channel.message(), &baz_node.message(), &bar_node.message()));
678 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
679 &not_logged_channel.message(), &baz_node.message(), &baz_node.message()));
680
681 // Remote logger.
682 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
683 &logged_on_remote_channel.message(), &baz_node.message(),
684 &foo_node.message()));
685 EXPECT_TRUE(ConnectionDeliveryTimeIsLoggedOnNode(
686 &logged_on_remote_channel.message(), &baz_node.message(),
687 &bar_node.message()));
688 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
689 &logged_on_remote_channel.message(), &baz_node.message(),
690 &baz_node.message()));
691
692 // Separate logger.
693 EXPECT_TRUE(ConnectionDeliveryTimeIsLoggedOnNode(
694 &logged_on_separate_logger_node_channel.message(), &baz_node.message(),
695 &foo_node.message()));
696 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
697 &logged_on_separate_logger_node_channel.message(), &baz_node.message(),
698 &bar_node.message()));
699 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
700 &logged_on_separate_logger_node_channel.message(), &baz_node.message(),
701 &baz_node.message()));
702
703 // Logged on both the node and a remote node.
704 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
705 &logged_on_both_channel.message(), &baz_node.message(),
706 &foo_node.message()));
707 EXPECT_TRUE(ConnectionDeliveryTimeIsLoggedOnNode(
708 &logged_on_both_channel.message(), &baz_node.message(),
709 &bar_node.message()));
710 EXPECT_TRUE(ConnectionDeliveryTimeIsLoggedOnNode(
711 &logged_on_both_channel.message(), &baz_node.message(),
712 &baz_node.message()));
713}
Austin Schuhe84c3ed2019-12-14 15:29:48 -0800714
715// Tests that we can deduce source nodes from a multinode config.
716TEST_F(ConfigurationTest, SourceNodeNames) {
717 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700718 ReadConfig(ArtifactPath("aos/testdata/config1_multinode.json"));
Austin Schuhe84c3ed2019-12-14 15:29:48 -0800719
720 // This is a bit simplistic in that it doesn't test deduplication, but it does
721 // exercise a lot of the logic.
722 EXPECT_THAT(
723 SourceNodeNames(&config.message(), config.message().nodes()->Get(0)),
724 ::testing::ElementsAreArray({"pi2"}));
725 EXPECT_THAT(
726 SourceNodeNames(&config.message(), config.message().nodes()->Get(1)),
727 ::testing::ElementsAreArray({"pi1"}));
728}
729
730// Tests that we can deduce destination nodes from a multinode config.
731TEST_F(ConfigurationTest, DestinationNodeNames) {
732 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700733 ReadConfig(ArtifactPath("aos/testdata/config1_multinode.json"));
Austin Schuhe84c3ed2019-12-14 15:29:48 -0800734
735 // This is a bit simplistic in that it doesn't test deduplication, but it does
736 // exercise a lot of the logic.
737 EXPECT_THAT(
738 DestinationNodeNames(&config.message(), config.message().nodes()->Get(0)),
739 ::testing::ElementsAreArray({"pi2"}));
740 EXPECT_THAT(
741 DestinationNodeNames(&config.message(), config.message().nodes()->Get(1)),
742 ::testing::ElementsAreArray({"pi1"}));
743}
744
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800745// Tests that we can pull out all the nodes.
746TEST_F(ConfigurationTest, GetNodes) {
747 {
748 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700749 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800750 const Node *pi1 = GetNode(&config.message(), "pi1");
751 const Node *pi2 = GetNode(&config.message(), "pi2");
752
753 EXPECT_THAT(GetNodes(&config.message()), ::testing::ElementsAre(pi1, pi2));
754 }
755
756 {
757 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700758 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800759 EXPECT_THAT(GetNodes(&config.message()), ::testing::ElementsAre(nullptr));
760 }
761}
762
Austin Schuh65465332020-11-05 17:36:53 -0800763// Tests that we can pull out all the nodes with a tag.
764TEST_F(ConfigurationTest, GetNodesWithTag) {
765 {
766 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700767 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuh65465332020-11-05 17:36:53 -0800768 const Node *pi1 = GetNode(&config.message(), "pi1");
769 const Node *pi2 = GetNode(&config.message(), "pi2");
770
771 EXPECT_THAT(GetNodesWithTag(&config.message(), "a"),
772 ::testing::ElementsAre(pi1));
773 EXPECT_THAT(GetNodesWithTag(&config.message(), "b"),
774 ::testing::ElementsAre(pi2));
775 EXPECT_THAT(GetNodesWithTag(&config.message(), "c"),
776 ::testing::ElementsAre(pi1, pi2));
777 }
778
779 {
780 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700781 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Austin Schuh65465332020-11-05 17:36:53 -0800782 EXPECT_THAT(GetNodesWithTag(&config.message(), "arglfish"),
783 ::testing::ElementsAre(nullptr));
784 }
785}
786
Brian Silverman631b6262021-11-10 12:25:08 -0800787// Tests that we can check if a node has a tag.
788TEST_F(ConfigurationTest, NodeHasTag) {
789 {
790 FlatbufferDetachedBuffer<Configuration> config =
791 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
792 const Node *pi1 = GetNode(&config.message(), "pi1");
793 const Node *pi2 = GetNode(&config.message(), "pi2");
794
795 EXPECT_TRUE(NodeHasTag(pi1, "a"));
796 EXPECT_FALSE(NodeHasTag(pi2, "a"));
797 EXPECT_FALSE(NodeHasTag(pi1, "b"));
798 EXPECT_TRUE(NodeHasTag(pi2, "b"));
799 EXPECT_TRUE(NodeHasTag(pi1, "c"));
800 EXPECT_TRUE(NodeHasTag(pi2, "c"));
801 EXPECT_FALSE(NodeHasTag(pi1, "nope"));
802 EXPECT_FALSE(NodeHasTag(pi2, "nope"));
803 }
804
805 EXPECT_TRUE(NodeHasTag(nullptr, "arglfish"));
806}
807
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800808// Tests that we can extract a node index from a config.
809TEST_F(ConfigurationTest, GetNodeIndex) {
810 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700811 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuh04408fc2020-02-16 21:48:54 -0800812 FlatbufferDetachedBuffer<Configuration> config2 =
Austin Schuh373f1762021-06-02 21:07:09 -0700813 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800814 const Node *pi1 = GetNode(&config.message(), "pi1");
815 const Node *pi2 = GetNode(&config.message(), "pi2");
816
Austin Schuh04408fc2020-02-16 21:48:54 -0800817 // Try the normal case.
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800818 EXPECT_EQ(GetNodeIndex(&config.message(), pi1), 0);
819 EXPECT_EQ(GetNodeIndex(&config.message(), pi2), 1);
Austin Schuh04408fc2020-02-16 21:48:54 -0800820
821 // Now try if we have node pointers from a different message.
822 EXPECT_EQ(GetNodeIndex(&config2.message(), pi1), 0);
823 EXPECT_EQ(GetNodeIndex(&config2.message(), pi2), 1);
824
825 // And now try string names.
826 EXPECT_EQ(GetNodeIndex(&config2.message(), pi1->name()->string_view()), 0);
827 EXPECT_EQ(GetNodeIndex(&config2.message(), pi2->name()->string_view()), 1);
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800828}
829
830// Tests that GetNodeOrDie handles both single and multi-node worlds and returns
831// valid nodes.
832TEST_F(ConfigurationDeathTest, GetNodeOrDie) {
833 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700834 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800835 FlatbufferDetachedBuffer<Configuration> config2 =
Austin Schuh373f1762021-06-02 21:07:09 -0700836 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800837 {
838 // Simple case, nullptr -> nullptr
839 FlatbufferDetachedBuffer<Configuration> single_node_config =
Austin Schuh373f1762021-06-02 21:07:09 -0700840 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800841 EXPECT_EQ(nullptr, GetNodeOrDie(&single_node_config.message(), nullptr));
842
843 // Confirm that we die when a node is passed in.
844 EXPECT_DEATH(
845 {
846 GetNodeOrDie(&single_node_config.message(),
847 config.message().nodes()->Get(0));
848 },
849 "Provided a node in a single node world.");
850 }
851
852 const Node *pi1 = GetNode(&config.message(), "pi1");
853 // Now try a lookup using a node from a different instance of the config.
854 EXPECT_EQ(pi1,
855 GetNodeOrDie(&config.message(), config2.message().nodes()->Get(0)));
856}
857
Brian Silvermanaa2633f2020-02-17 21:04:14 -0800858TEST_F(ConfigurationTest, GetNodeFromHostname) {
859 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700860 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Brian Silvermanaa2633f2020-02-17 21:04:14 -0800861 EXPECT_EQ("pi1",
862 CHECK_NOTNULL(GetNodeFromHostname(&config.message(), "raspberrypi"))
863 ->name()
864 ->string_view());
865 EXPECT_EQ("pi2", CHECK_NOTNULL(
866 GetNodeFromHostname(&config.message(), "raspberrypi2"))
867 ->name()
868 ->string_view());
869 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "raspberrypi3"));
870 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "localhost"));
871 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "3"));
872}
873
874TEST_F(ConfigurationTest, GetNodeFromHostnames) {
875 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700876 ReadConfig(ArtifactPath("aos/testdata/good_multinode_hostnames.json"));
Brian Silvermanaa2633f2020-02-17 21:04:14 -0800877 EXPECT_EQ("pi1",
878 CHECK_NOTNULL(GetNodeFromHostname(&config.message(), "raspberrypi"))
879 ->name()
880 ->string_view());
881 EXPECT_EQ("pi2", CHECK_NOTNULL(
882 GetNodeFromHostname(&config.message(), "raspberrypi2"))
883 ->name()
884 ->string_view());
885 EXPECT_EQ("pi2", CHECK_NOTNULL(
886 GetNodeFromHostname(&config.message(), "raspberrypi3"))
887 ->name()
888 ->string_view());
Ravago Jonescf453ab2020-05-06 21:14:53 -0700889 EXPECT_EQ("pi2",
890 CHECK_NOTNULL(GetNodeFromHostname(&config.message(), "other"))
891 ->name()
892 ->string_view());
Brian Silvermanaa2633f2020-02-17 21:04:14 -0800893 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "raspberrypi4"));
894 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "localhost"));
895 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "3"));
896}
897
Austin Schuhfc7b6a02021-07-12 21:19:07 -0700898// Tests that SourceNodeIndex reasonably handles a multi-node log file.
899TEST_F(ConfigurationTest, SourceNodeIndex) {
900 FlatbufferDetachedBuffer<Configuration> config =
901 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
902 std::vector<size_t> result = SourceNodeIndex(&config.message());
903
904 EXPECT_THAT(result, ::testing::ElementsAreArray({0, 1, 0, 0}));
905}
906
Austin Schuh5e95bd62021-10-11 18:40:22 -0700907// Tests that we reject invalid logging configurations.
908TEST_F(ConfigurationDeathTest, InvalidLoggerConfig) {
909 EXPECT_DEATH(
910 {
Milind Upadhyay17098ba2022-04-15 22:18:50 -0700911 FlatbufferDetachedBuffer<Configuration> config = ReadConfig(
912 ArtifactPath("aos/testdata/invalid_logging_configuration.json"));
Austin Schuh5e95bd62021-10-11 18:40:22 -0700913 },
914 "Logging timestamps without data");
915}
916
Austin Schuha156fb22021-10-11 19:23:21 -0700917// Tests that we reject duplicate timestamp destination node configurations.
918TEST_F(ConfigurationDeathTest, DuplicateTimestampDestinationNodes) {
919 EXPECT_DEATH(
920 {
921 FlatbufferDetachedBuffer<Configuration> config = ReadConfig(
922 ArtifactPath("aos/testdata/duplicate_destination_nodes.json"));
923 },
924 "Found duplicate timestamp_logger_nodes in");
925}
926
927// Tests that we reject duplicate logger node configurations for a channel's
928// data.
929TEST_F(ConfigurationDeathTest, DuplicateLoggerNodes) {
930 EXPECT_DEATH(
931 {
932 FlatbufferDetachedBuffer<Configuration> config = ReadConfig(
933 ArtifactPath("aos/testdata/duplicate_logger_nodes.json"));
934 },
935 "Found duplicate logger_nodes in");
936}
937
Austin Schuhcb108412019-10-13 16:09:54 -0700938} // namespace testing
939} // namespace configuration
940} // namespace aos