blob: 0b842cb9f602951013ceeaaf48e57c7991b8b2fc [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
Austin Schuhf1fff282020-03-28 16:57:32 -070098// Tests that we reject invalid channel names. This means any channels with //
99// in their name, a trailing /, or regex characters.
100TEST_F(ConfigurationDeathTest, InvalidChannelName) {
101 EXPECT_DEATH(
102 {
103 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700104 ReadConfig(ArtifactPath("aos/testdata/invalid_channel_name1.json"));
Austin Schuhf1fff282020-03-28 16:57:32 -0700105 },
106 "Channel names can't end with '/'");
107 EXPECT_DEATH(
108 {
109 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700110 ReadConfig(ArtifactPath("aos/testdata/invalid_channel_name2.json"));
Austin Schuhf1fff282020-03-28 16:57:32 -0700111 },
112 "Invalid channel name");
113 EXPECT_DEATH(
114 {
115 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700116 ReadConfig(ArtifactPath("aos/testdata/invalid_channel_name3.json"));
Austin Schuhf1fff282020-03-28 16:57:32 -0700117 LOG(FATAL) << "Foo";
118 },
119 "Invalid channel name");
120}
121
Austin Schuh8d6cea82020-02-28 12:17:16 -0800122// Tests that we can modify a config with a json snippet.
123TEST_F(ConfigurationTest, MergeWithConfig) {
124 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700125 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Ravago Jonescf453ab2020-05-06 21:14:53 -0700126 LOG(INFO) << "Read: " << FlatbufferToJson(config, {.multi_line = true});
Austin Schuh8d6cea82020-02-28 12:17:16 -0800127
128 FlatbufferDetachedBuffer<Configuration> updated_config =
129 MergeWithConfig(&config.message(),
130 R"channel({
131 "channels": [
132 {
133 "name": "/foo",
134 "type": ".aos.bar",
135 "max_size": 100
136 }
137 ]
138})channel");
139
Austin Schuh373f1762021-06-02 21:07:09 -0700140 EXPECT_EQ(absl::StripSuffix(util::ReadFileToStringOrDie(ArtifactPath(
141 "aos/testdata/expected_merge_with.json")),
Ravago Jonescf453ab2020-05-06 21:14:53 -0700142 "\n"),
143 FlatbufferToJson(updated_config, {.multi_line = true}));
Austin Schuh8d6cea82020-02-28 12:17:16 -0800144}
145
Austin Schuhcb108412019-10-13 16:09:54 -0700146// Tests that we can lookup a location, complete with maps, from a merged
147// config.
Austin Schuh40485ed2019-10-26 21:51:44 -0700148TEST_F(ConfigurationTest, GetChannel) {
149 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700150 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Austin Schuhcb108412019-10-13 16:09:54 -0700151
152 // Test a basic lookup first.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800153 EXPECT_THAT(GetChannel(config, "/foo", ".aos.bar", "app1", nullptr),
154 aos::testing::FlatbufferEq(ExpectedLocation()));
Austin Schuhcb108412019-10-13 16:09:54 -0700155
156 // Test that an invalid name results in nullptr back.
Austin Schuhbca6cf02019-12-22 17:28:34 -0800157 EXPECT_EQ(GetChannel(config, "/invalid_name", ".aos.bar", "app1", nullptr),
158 nullptr);
Austin Schuhcb108412019-10-13 16:09:54 -0700159
160 // Tests that a root map/rename works. And that they get processed from the
161 // bottom up.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800162 EXPECT_THAT(GetChannel(config, "/batman", ".aos.bar", "app1", nullptr),
163 aos::testing::FlatbufferEq(ExpectedLocation()));
Austin Schuhcb108412019-10-13 16:09:54 -0700164
165 // And then test that an application specific map/rename works.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800166 EXPECT_THAT(GetChannel(config, "/bar", ".aos.bar", "app1", nullptr),
167 aos::testing::FlatbufferEq(ExpectedLocation()));
168 EXPECT_THAT(GetChannel(config, "/baz", ".aos.bar", "app2", nullptr),
169 aos::testing::FlatbufferEq(ExpectedLocation()));
Austin Schuhcb108412019-10-13 16:09:54 -0700170
171 // And then test that an invalid application name gets properly ignored.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800172 EXPECT_THAT(GetChannel(config, "/foo", ".aos.bar", "app3", nullptr),
173 aos::testing::FlatbufferEq(ExpectedLocation()));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800174}
175
176// Tests that we can lookup a location with node specific maps.
177TEST_F(ConfigurationTest, GetChannelMultinode) {
178 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700179 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800180 const Node *pi1 = GetNode(&config.message(), "pi1");
181 const Node *pi2 = GetNode(&config.message(), "pi2");
182
183 // Test a basic lookup first.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800184 EXPECT_THAT(GetChannel(config, "/foo", ".aos.bar", "app1", pi1),
185 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
186 EXPECT_THAT(GetChannel(config, "/foo", ".aos.bar", "app1", pi2),
187 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800188
189 // Tests that a root map/rename works with a node specific map.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800190 EXPECT_THAT(GetChannel(config, "/batman", ".aos.bar", "app1", pi1),
191 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800192
193 // Tests that a root map/rename fails with a node specific map for the wrong
194 // node.
195 EXPECT_EQ(GetChannel(config, "/batman", ".aos.bar", "app1", pi2), nullptr);
196
197 // And then test that an application specific map/rename works.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800198 EXPECT_THAT(GetChannel(config, "/batman2", ".aos.bar", "app1", pi1),
199 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
200 EXPECT_THAT(GetChannel(config, "/batman3", ".aos.bar", "app1", pi1),
201 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800202
203 // And then that it fails when the node changes.
204 EXPECT_EQ(GetChannel(config, "/batman3", ".aos.bar", "app1", pi2), nullptr);
205}
206
207// Tests that we can lookup a location with type specific maps.
208TEST_F(ConfigurationTest, GetChannelTypedMultinode) {
209 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700210 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800211 const Node *pi1 = GetNode(&config.message(), "pi1");
212
213 // Test a basic lookup first.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800214 EXPECT_THAT(GetChannel(config, "/batman", ".aos.bar", "app1", pi1),
215 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
Austin Schuhbca6cf02019-12-22 17:28:34 -0800216
217 // Now confirm that a second message on the same name doesn't get remapped.
218 const char *kExpectedBazMultinodeLocation =
219 "{ \"name\": \"/batman\", \"type\": \".aos.baz\", \"max_size\": 5, "
220 "\"source_node\": \"pi1\" }";
221 EXPECT_EQ(
222 FlatbufferToJson(GetChannel(config, "/batman", ".aos.baz", "app1", pi1)),
223 kExpectedBazMultinodeLocation);
Austin Schuhcb108412019-10-13 16:09:54 -0700224}
225
Austin Schuhf1fff282020-03-28 16:57:32 -0700226// Tests that we can lookup a location with a glob
227TEST_F(ConfigurationTest, GetChannelGlob) {
228 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700229 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhf1fff282020-03-28 16:57:32 -0700230 const Node *pi1 = GetNode(&config.message(), "pi1");
231
232 // Confirm that a glob with nothing after it matches.
Austin Schuh1ef01ef2021-02-07 20:40:36 -0800233 EXPECT_THAT(GetChannel(config, "/magic/string", ".aos.bar", "app7", pi1),
234 aos::testing::FlatbufferEq(ExpectedMultinodeLocation()));
Austin Schuhf1fff282020-03-28 16:57:32 -0700235
236 // Now confirm that glob with something following it matches and renames
237 // correctly.
238 const char *kExpectedSubfolderMultinodeLocation =
239 "{ \"name\": \"/foo/subfolder\", \"type\": \".aos.bar\", \"max_size\": "
240 "5, \"source_node\": \"pi1\" }";
241 EXPECT_EQ(FlatbufferToJson(GetChannel(config, "/magic/string/subfolder",
242 ".aos.bar", "app7", pi1)),
243 kExpectedSubfolderMultinodeLocation);
244}
245
Austin Schuh217a9782019-12-21 23:02:50 -0800246// Tests that we reject a configuration which has a nodes list, but has channels
247// withoout source_node filled out.
248TEST_F(ConfigurationDeathTest, InvalidSourceNode) {
249 EXPECT_DEATH(
250 {
251 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700252 ReadConfig(ArtifactPath("aos/testdata/invalid_nodes.json"));
Austin Schuh217a9782019-12-21 23:02:50 -0800253 },
254 "source_node");
255
256 EXPECT_DEATH(
257 {
258 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700259 ReadConfig(ArtifactPath("aos/testdata/invalid_source_node.json"));
Austin Schuh217a9782019-12-21 23:02:50 -0800260 },
261 "source_node");
262
263 EXPECT_DEATH(
264 {
Austin Schuh373f1762021-06-02 21:07:09 -0700265 FlatbufferDetachedBuffer<Configuration> config = ReadConfig(
266 ArtifactPath("aos/testdata/invalid_destination_node.json"));
Austin Schuh217a9782019-12-21 23:02:50 -0800267 },
268 "destination_nodes");
269
270 EXPECT_DEATH(
271 {
272 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700273 ReadConfig(ArtifactPath("aos/testdata/self_forward.json"));
Austin Schuh217a9782019-12-21 23:02:50 -0800274 },
275 "forwarding data to itself");
276}
277
278// Tests that our node writeable helpers work as intended.
279TEST_F(ConfigurationTest, ChannelIsSendableOnNode) {
280 FlatbufferDetachedBuffer<Channel> good_channel(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800281 R"channel({
Austin Schuh217a9782019-12-21 23:02:50 -0800282 "name": "/test",
283 "type": "aos.examples.Ping",
284 "source_node": "foo"
285})channel",
286 Channel::MiniReflectTypeTable()));
287
288 FlatbufferDetachedBuffer<Channel> bad_channel(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800289 R"channel({
Austin Schuh217a9782019-12-21 23:02:50 -0800290 "name": "/test",
291 "type": "aos.examples.Ping",
292 "source_node": "bar"
293})channel",
294 Channel::MiniReflectTypeTable()));
295
296 FlatbufferDetachedBuffer<Node> node(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800297 R"node({
Austin Schuh217a9782019-12-21 23:02:50 -0800298 "name": "foo"
299})node",
300 Node::MiniReflectTypeTable()));
301
302 EXPECT_TRUE(
303 ChannelIsSendableOnNode(&good_channel.message(), &node.message()));
304 EXPECT_FALSE(
305 ChannelIsSendableOnNode(&bad_channel.message(), &node.message()));
306}
307
308// Tests that our node readable and writeable helpers work as intended.
309TEST_F(ConfigurationTest, ChannelIsReadableOnNode) {
310 FlatbufferDetachedBuffer<Channel> good_channel(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800311 R"channel({
Austin Schuh217a9782019-12-21 23:02:50 -0800312 "name": "/test",
313 "type": "aos.examples.Ping",
314 "source_node": "bar",
315 "destination_nodes": [
Austin Schuh719946b2019-12-28 14:51:01 -0800316 {
317 "name": "baz"
318 },
319 {
320 "name": "foo"
321 }
Austin Schuh217a9782019-12-21 23:02:50 -0800322 ]
323})channel",
324 Channel::MiniReflectTypeTable()));
325
326 FlatbufferDetachedBuffer<Channel> bad_channel1(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800327 R"channel({
Austin Schuh217a9782019-12-21 23:02:50 -0800328 "name": "/test",
329 "type": "aos.examples.Ping",
330 "source_node": "bar"
331})channel",
332 Channel::MiniReflectTypeTable()));
333
334 FlatbufferDetachedBuffer<Channel> bad_channel2(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800335 R"channel({
Austin Schuh217a9782019-12-21 23:02:50 -0800336 "name": "/test",
337 "type": "aos.examples.Ping",
338 "source_node": "bar",
339 "destination_nodes": [
Austin Schuh719946b2019-12-28 14:51:01 -0800340 {
341 "name": "baz"
342 }
Austin Schuh217a9782019-12-21 23:02:50 -0800343 ]
344})channel",
345 Channel::MiniReflectTypeTable()));
346
347 FlatbufferDetachedBuffer<Node> node(JsonToFlatbuffer(
Austin Schuh719946b2019-12-28 14:51:01 -0800348 R"node({
Austin Schuh217a9782019-12-21 23:02:50 -0800349 "name": "foo"
350})node",
351 Node::MiniReflectTypeTable()));
352
353 EXPECT_TRUE(
354 ChannelIsReadableOnNode(&good_channel.message(), &node.message()));
355 EXPECT_FALSE(
356 ChannelIsReadableOnNode(&bad_channel1.message(), &node.message()));
357 EXPECT_FALSE(
358 ChannelIsReadableOnNode(&bad_channel2.message(), &node.message()));
359}
360
Austin Schuh719946b2019-12-28 14:51:01 -0800361// Tests that our node message is logged helpers work as intended.
362TEST_F(ConfigurationTest, ChannelMessageIsLoggedOnNode) {
363 FlatbufferDetachedBuffer<Channel> logged_on_self_channel(JsonToFlatbuffer(
364 R"channel({
365 "name": "/test",
366 "type": "aos.examples.Ping",
367 "source_node": "bar",
368 "destination_nodes": [
369 {
370 "name": "baz"
371 }
372 ]
373})channel",
374 Channel::MiniReflectTypeTable()));
Austin Schuh217a9782019-12-21 23:02:50 -0800375
Austin Schuh719946b2019-12-28 14:51:01 -0800376 FlatbufferDetachedBuffer<Channel> not_logged_channel(JsonToFlatbuffer(
377 R"channel({
378 "name": "/test",
379 "type": "aos.examples.Ping",
380 "source_node": "bar",
381 "logger": "NOT_LOGGED",
382 "destination_nodes": [
383 {
384 "name": "baz",
385 "timestamp_logger": "LOCAL_LOGGER"
386 }
387 ]
388})channel",
389 Channel::MiniReflectTypeTable()));
390
391 FlatbufferDetachedBuffer<Channel> logged_on_remote_channel(JsonToFlatbuffer(
392 R"channel({
393 "name": "/test",
394 "type": "aos.examples.Ping",
395 "source_node": "bar",
396 "logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700397 "logger_nodes": ["baz"],
Austin Schuh719946b2019-12-28 14:51:01 -0800398 "destination_nodes": [
399 {
400 "name": "baz"
401 }
402 ]
403})channel",
404 Channel::MiniReflectTypeTable()));
405
406 FlatbufferDetachedBuffer<Channel> logged_on_separate_logger_node_channel(
407 JsonToFlatbuffer(
408 R"channel({
409 "name": "/test",
410 "type": "aos.examples.Ping",
411 "source_node": "bar",
412 "logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700413 "logger_nodes": ["foo"],
Austin Schuh719946b2019-12-28 14:51:01 -0800414 "destination_nodes": [
415 {
416 "name": "baz"
417 }
418 ]
419})channel",
420 Channel::MiniReflectTypeTable()));
421
Ravago Jonescf453ab2020-05-06 21:14:53 -0700422 FlatbufferDetachedBuffer<Channel> logged_on_both_channel(JsonToFlatbuffer(
423 R"channel({
Austin Schuh719946b2019-12-28 14:51:01 -0800424 "name": "/test",
425 "type": "aos.examples.Ping",
426 "source_node": "bar",
427 "logger": "LOCAL_AND_REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700428 "logger_nodes": ["baz"],
Austin Schuh719946b2019-12-28 14:51:01 -0800429 "destination_nodes": [
430 {
431 "name": "baz"
432 }
433 ]
434})channel",
Ravago Jonescf453ab2020-05-06 21:14:53 -0700435 Channel::MiniReflectTypeTable()));
Austin Schuh719946b2019-12-28 14:51:01 -0800436
437 FlatbufferDetachedBuffer<Node> foo_node(JsonToFlatbuffer(
438 R"node({
439 "name": "foo"
440})node",
441 Node::MiniReflectTypeTable()));
442
443 FlatbufferDetachedBuffer<Node> bar_node(JsonToFlatbuffer(
444 R"node({
445 "name": "bar"
446})node",
447 Node::MiniReflectTypeTable()));
448
449 FlatbufferDetachedBuffer<Node> baz_node(JsonToFlatbuffer(
450 R"node({
451 "name": "baz"
452})node",
453 Node::MiniReflectTypeTable()));
454
455 // Local logger.
456 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&logged_on_self_channel.message(),
457 &foo_node.message()));
458 EXPECT_TRUE(ChannelMessageIsLoggedOnNode(&logged_on_self_channel.message(),
459 &bar_node.message()));
460 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&logged_on_self_channel.message(),
461 &baz_node.message()));
Austin Schuh48e94502021-06-18 18:35:53 -0700462 EXPECT_TRUE(
463 ChannelMessageIsLoggedOnNode(&logged_on_self_channel.message(), nullptr));
Austin Schuh719946b2019-12-28 14:51:01 -0800464
465 // No logger.
466 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&not_logged_channel.message(),
467 &foo_node.message()));
468 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&not_logged_channel.message(),
Ravago Jonescf453ab2020-05-06 21:14:53 -0700469 &bar_node.message()));
Austin Schuh719946b2019-12-28 14:51:01 -0800470 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&not_logged_channel.message(),
471 &baz_node.message()));
Austin Schuh48e94502021-06-18 18:35:53 -0700472 EXPECT_FALSE(
473 ChannelMessageIsLoggedOnNode(&not_logged_channel.message(), nullptr));
Austin Schuh719946b2019-12-28 14:51:01 -0800474
475 // Remote logger.
476 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&logged_on_remote_channel.message(),
477 &foo_node.message()));
478 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&logged_on_remote_channel.message(),
479 &bar_node.message()));
480 EXPECT_TRUE(ChannelMessageIsLoggedOnNode(&logged_on_remote_channel.message(),
481 &baz_node.message()));
482
483 // Separate logger.
484 EXPECT_TRUE(ChannelMessageIsLoggedOnNode(
485 &logged_on_separate_logger_node_channel.message(), &foo_node.message()));
486 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(
487 &logged_on_separate_logger_node_channel.message(), &bar_node.message()));
488 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(
489 &logged_on_separate_logger_node_channel.message(), &baz_node.message()));
490
491 // Logged in multiple places.
492 EXPECT_FALSE(ChannelMessageIsLoggedOnNode(&logged_on_both_channel.message(),
493 &foo_node.message()));
494 EXPECT_TRUE(ChannelMessageIsLoggedOnNode(&logged_on_both_channel.message(),
495 &bar_node.message()));
496 EXPECT_TRUE(ChannelMessageIsLoggedOnNode(&logged_on_both_channel.message(),
497 &baz_node.message()));
498}
499
Austin Schuh48e94502021-06-18 18:35:53 -0700500// Tests that our node message is logged helpers work as intended.
501TEST_F(ConfigurationDeathTest, ChannelMessageIsLoggedOnNode) {
502 FlatbufferDetachedBuffer<Channel> logged_on_both_channel(JsonToFlatbuffer(
503 R"channel({
504 "name": "/test",
505 "type": "aos.examples.Ping",
506 "source_node": "bar",
507 "logger": "LOCAL_AND_REMOTE_LOGGER",
508 "logger_nodes": ["baz"],
509 "destination_nodes": [
510 {
511 "name": "baz"
512 }
513 ]
514})channel",
515 Channel::MiniReflectTypeTable()));
516
517 FlatbufferDetachedBuffer<Channel> logged_on_separate_logger_node_channel(
518 JsonToFlatbuffer(
519 R"channel({
520 "name": "/test",
521 "type": "aos.examples.Ping",
522 "source_node": "bar",
523 "logger": "REMOTE_LOGGER",
524 "logger_nodes": ["foo"],
525 "destination_nodes": [
526 {
527 "name": "baz"
528 }
529 ]
530})channel",
531 Channel::MiniReflectTypeTable()));
532
533 EXPECT_DEATH(
534 {
535 ChannelMessageIsLoggedOnNode(&logged_on_both_channel.message(),
536 nullptr);
537 },
538 "Unsupported logging configuration in a single node world");
539 EXPECT_DEATH(
540 {
541 ChannelMessageIsLoggedOnNode(
542 &logged_on_separate_logger_node_channel.message(), nullptr);
543 },
544 "Unsupported logging configuration in a single node world");
545}
546
Austin Schuh719946b2019-12-28 14:51:01 -0800547// Tests that our forwarding timestamps are logged helpers work as intended.
548TEST_F(ConfigurationTest, ConnectionDeliveryTimeIsLoggedOnNode) {
549 FlatbufferDetachedBuffer<Channel> logged_on_self_channel(JsonToFlatbuffer(
550 R"channel({
551 "name": "/test",
552 "type": "aos.examples.Ping",
553 "source_node": "bar",
554 "logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700555 "logger_nodes": ["baz"],
Austin Schuh719946b2019-12-28 14:51:01 -0800556 "destination_nodes": [
557 {
558 "name": "baz"
559 }
560 ]
561})channel",
562 Channel::MiniReflectTypeTable()));
563
564 FlatbufferDetachedBuffer<Channel> not_logged_channel(JsonToFlatbuffer(
565 R"channel({
566 "name": "/test",
567 "type": "aos.examples.Ping",
568 "source_node": "bar",
569 "logger": "NOT_LOGGED",
570 "destination_nodes": [
571 {
572 "name": "baz",
573 "timestamp_logger": "NOT_LOGGED"
574 }
575 ]
576})channel",
577 Channel::MiniReflectTypeTable()));
578
579 FlatbufferDetachedBuffer<Channel> logged_on_remote_channel(JsonToFlatbuffer(
580 R"channel({
581 "name": "/test",
582 "type": "aos.examples.Ping",
583 "source_node": "bar",
584 "destination_nodes": [
585 {
586 "name": "baz",
587 "timestamp_logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700588 "timestamp_logger_nodes": ["bar"]
Austin Schuh719946b2019-12-28 14:51:01 -0800589 }
590 ]
591})channel",
592 Channel::MiniReflectTypeTable()));
593
594 FlatbufferDetachedBuffer<Channel> logged_on_separate_logger_node_channel(
595 JsonToFlatbuffer(
596 R"channel({
597 "name": "/test",
598 "type": "aos.examples.Ping",
599 "source_node": "bar",
600 "logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700601 "logger_nodes": ["foo"],
Austin Schuh719946b2019-12-28 14:51:01 -0800602 "destination_nodes": [
603 {
604 "name": "baz",
605 "timestamp_logger": "REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700606 "timestamp_logger_nodes": ["foo"]
Austin Schuh719946b2019-12-28 14:51:01 -0800607 }
608 ]
609})channel",
610 Channel::MiniReflectTypeTable()));
611
Ravago Jonescf453ab2020-05-06 21:14:53 -0700612 FlatbufferDetachedBuffer<Channel> logged_on_both_channel(JsonToFlatbuffer(
613 R"channel({
Austin Schuh719946b2019-12-28 14:51:01 -0800614 "name": "/test",
615 "type": "aos.examples.Ping",
616 "source_node": "bar",
617 "destination_nodes": [
618 {
619 "name": "baz",
620 "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
Austin Schuhda40e472020-03-28 15:15:29 -0700621 "timestamp_logger_nodes": ["bar"]
Austin Schuh719946b2019-12-28 14:51:01 -0800622 }
623 ]
624})channel",
Ravago Jonescf453ab2020-05-06 21:14:53 -0700625 Channel::MiniReflectTypeTable()));
Austin Schuh719946b2019-12-28 14:51:01 -0800626
627 FlatbufferDetachedBuffer<Node> foo_node(JsonToFlatbuffer(
628 R"node({
629 "name": "foo"
630})node",
631 Node::MiniReflectTypeTable()));
632
633 FlatbufferDetachedBuffer<Node> bar_node(JsonToFlatbuffer(
634 R"node({
635 "name": "bar"
636})node",
637 Node::MiniReflectTypeTable()));
638
639 FlatbufferDetachedBuffer<Node> baz_node(JsonToFlatbuffer(
640 R"node({
641 "name": "baz"
642})node",
643 Node::MiniReflectTypeTable()));
644
645 // Local logger.
646 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
647 &logged_on_self_channel.message(), &baz_node.message(),
648 &foo_node.message()));
649 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
650 &logged_on_self_channel.message(), &baz_node.message(),
651 &bar_node.message()));
652 EXPECT_TRUE(ConnectionDeliveryTimeIsLoggedOnNode(
653 &logged_on_self_channel.message(), &baz_node.message(),
654 &baz_node.message()));
655
656 // No logger means.
657 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
658 &not_logged_channel.message(), &baz_node.message(), &foo_node.message()));
659 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
660 &not_logged_channel.message(), &baz_node.message(), &bar_node.message()));
661 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
662 &not_logged_channel.message(), &baz_node.message(), &baz_node.message()));
663
664 // Remote logger.
665 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
666 &logged_on_remote_channel.message(), &baz_node.message(),
667 &foo_node.message()));
668 EXPECT_TRUE(ConnectionDeliveryTimeIsLoggedOnNode(
669 &logged_on_remote_channel.message(), &baz_node.message(),
670 &bar_node.message()));
671 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
672 &logged_on_remote_channel.message(), &baz_node.message(),
673 &baz_node.message()));
674
675 // Separate logger.
676 EXPECT_TRUE(ConnectionDeliveryTimeIsLoggedOnNode(
677 &logged_on_separate_logger_node_channel.message(), &baz_node.message(),
678 &foo_node.message()));
679 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
680 &logged_on_separate_logger_node_channel.message(), &baz_node.message(),
681 &bar_node.message()));
682 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
683 &logged_on_separate_logger_node_channel.message(), &baz_node.message(),
684 &baz_node.message()));
685
686 // Logged on both the node and a remote node.
687 EXPECT_FALSE(ConnectionDeliveryTimeIsLoggedOnNode(
688 &logged_on_both_channel.message(), &baz_node.message(),
689 &foo_node.message()));
690 EXPECT_TRUE(ConnectionDeliveryTimeIsLoggedOnNode(
691 &logged_on_both_channel.message(), &baz_node.message(),
692 &bar_node.message()));
693 EXPECT_TRUE(ConnectionDeliveryTimeIsLoggedOnNode(
694 &logged_on_both_channel.message(), &baz_node.message(),
695 &baz_node.message()));
696}
Austin Schuhe84c3ed2019-12-14 15:29:48 -0800697
698// Tests that we can deduce source nodes from a multinode config.
699TEST_F(ConfigurationTest, SourceNodeNames) {
700 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700701 ReadConfig(ArtifactPath("aos/testdata/config1_multinode.json"));
Austin Schuhe84c3ed2019-12-14 15:29:48 -0800702
703 // This is a bit simplistic in that it doesn't test deduplication, but it does
704 // exercise a lot of the logic.
705 EXPECT_THAT(
706 SourceNodeNames(&config.message(), config.message().nodes()->Get(0)),
707 ::testing::ElementsAreArray({"pi2"}));
708 EXPECT_THAT(
709 SourceNodeNames(&config.message(), config.message().nodes()->Get(1)),
710 ::testing::ElementsAreArray({"pi1"}));
711}
712
713// Tests that we can deduce destination nodes from a multinode config.
714TEST_F(ConfigurationTest, DestinationNodeNames) {
715 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700716 ReadConfig(ArtifactPath("aos/testdata/config1_multinode.json"));
Austin Schuhe84c3ed2019-12-14 15:29:48 -0800717
718 // This is a bit simplistic in that it doesn't test deduplication, but it does
719 // exercise a lot of the logic.
720 EXPECT_THAT(
721 DestinationNodeNames(&config.message(), config.message().nodes()->Get(0)),
722 ::testing::ElementsAreArray({"pi2"}));
723 EXPECT_THAT(
724 DestinationNodeNames(&config.message(), config.message().nodes()->Get(1)),
725 ::testing::ElementsAreArray({"pi1"}));
726}
727
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800728// Tests that we can pull out all the nodes.
729TEST_F(ConfigurationTest, GetNodes) {
730 {
731 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700732 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800733 const Node *pi1 = GetNode(&config.message(), "pi1");
734 const Node *pi2 = GetNode(&config.message(), "pi2");
735
736 EXPECT_THAT(GetNodes(&config.message()), ::testing::ElementsAre(pi1, pi2));
737 }
738
739 {
740 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700741 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800742 EXPECT_THAT(GetNodes(&config.message()), ::testing::ElementsAre(nullptr));
743 }
744}
745
Austin Schuh65465332020-11-05 17:36:53 -0800746// Tests that we can pull out all the nodes with a tag.
747TEST_F(ConfigurationTest, GetNodesWithTag) {
748 {
749 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700750 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuh65465332020-11-05 17:36:53 -0800751 const Node *pi1 = GetNode(&config.message(), "pi1");
752 const Node *pi2 = GetNode(&config.message(), "pi2");
753
754 EXPECT_THAT(GetNodesWithTag(&config.message(), "a"),
755 ::testing::ElementsAre(pi1));
756 EXPECT_THAT(GetNodesWithTag(&config.message(), "b"),
757 ::testing::ElementsAre(pi2));
758 EXPECT_THAT(GetNodesWithTag(&config.message(), "c"),
759 ::testing::ElementsAre(pi1, pi2));
760 }
761
762 {
763 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700764 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Austin Schuh65465332020-11-05 17:36:53 -0800765 EXPECT_THAT(GetNodesWithTag(&config.message(), "arglfish"),
766 ::testing::ElementsAre(nullptr));
767 }
768}
769
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800770// Tests that we can extract a node index from a config.
771TEST_F(ConfigurationTest, GetNodeIndex) {
772 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700773 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuh04408fc2020-02-16 21:48:54 -0800774 FlatbufferDetachedBuffer<Configuration> config2 =
Austin Schuh373f1762021-06-02 21:07:09 -0700775 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800776 const Node *pi1 = GetNode(&config.message(), "pi1");
777 const Node *pi2 = GetNode(&config.message(), "pi2");
778
Austin Schuh04408fc2020-02-16 21:48:54 -0800779 // Try the normal case.
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800780 EXPECT_EQ(GetNodeIndex(&config.message(), pi1), 0);
781 EXPECT_EQ(GetNodeIndex(&config.message(), pi2), 1);
Austin Schuh04408fc2020-02-16 21:48:54 -0800782
783 // Now try if we have node pointers from a different message.
784 EXPECT_EQ(GetNodeIndex(&config2.message(), pi1), 0);
785 EXPECT_EQ(GetNodeIndex(&config2.message(), pi2), 1);
786
787 // And now try string names.
788 EXPECT_EQ(GetNodeIndex(&config2.message(), pi1->name()->string_view()), 0);
789 EXPECT_EQ(GetNodeIndex(&config2.message(), pi2->name()->string_view()), 1);
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800790}
791
792// Tests that GetNodeOrDie handles both single and multi-node worlds and returns
793// valid nodes.
794TEST_F(ConfigurationDeathTest, GetNodeOrDie) {
795 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700796 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800797 FlatbufferDetachedBuffer<Configuration> config2 =
Austin Schuh373f1762021-06-02 21:07:09 -0700798 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800799 {
800 // Simple case, nullptr -> nullptr
801 FlatbufferDetachedBuffer<Configuration> single_node_config =
Austin Schuh373f1762021-06-02 21:07:09 -0700802 ReadConfig(ArtifactPath("aos/testdata/config1.json"));
Austin Schuhc9e10ec2020-01-26 16:08:28 -0800803 EXPECT_EQ(nullptr, GetNodeOrDie(&single_node_config.message(), nullptr));
804
805 // Confirm that we die when a node is passed in.
806 EXPECT_DEATH(
807 {
808 GetNodeOrDie(&single_node_config.message(),
809 config.message().nodes()->Get(0));
810 },
811 "Provided a node in a single node world.");
812 }
813
814 const Node *pi1 = GetNode(&config.message(), "pi1");
815 // Now try a lookup using a node from a different instance of the config.
816 EXPECT_EQ(pi1,
817 GetNodeOrDie(&config.message(), config2.message().nodes()->Get(0)));
818}
819
Brian Silvermanaa2633f2020-02-17 21:04:14 -0800820TEST_F(ConfigurationTest, GetNodeFromHostname) {
821 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700822 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
Brian Silvermanaa2633f2020-02-17 21:04:14 -0800823 EXPECT_EQ("pi1",
824 CHECK_NOTNULL(GetNodeFromHostname(&config.message(), "raspberrypi"))
825 ->name()
826 ->string_view());
827 EXPECT_EQ("pi2", CHECK_NOTNULL(
828 GetNodeFromHostname(&config.message(), "raspberrypi2"))
829 ->name()
830 ->string_view());
831 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "raspberrypi3"));
832 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "localhost"));
833 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "3"));
834}
835
836TEST_F(ConfigurationTest, GetNodeFromHostnames) {
837 FlatbufferDetachedBuffer<Configuration> config =
Austin Schuh373f1762021-06-02 21:07:09 -0700838 ReadConfig(ArtifactPath("aos/testdata/good_multinode_hostnames.json"));
Brian Silvermanaa2633f2020-02-17 21:04:14 -0800839 EXPECT_EQ("pi1",
840 CHECK_NOTNULL(GetNodeFromHostname(&config.message(), "raspberrypi"))
841 ->name()
842 ->string_view());
843 EXPECT_EQ("pi2", CHECK_NOTNULL(
844 GetNodeFromHostname(&config.message(), "raspberrypi2"))
845 ->name()
846 ->string_view());
847 EXPECT_EQ("pi2", CHECK_NOTNULL(
848 GetNodeFromHostname(&config.message(), "raspberrypi3"))
849 ->name()
850 ->string_view());
Ravago Jonescf453ab2020-05-06 21:14:53 -0700851 EXPECT_EQ("pi2",
852 CHECK_NOTNULL(GetNodeFromHostname(&config.message(), "other"))
853 ->name()
854 ->string_view());
Brian Silvermanaa2633f2020-02-17 21:04:14 -0800855 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "raspberrypi4"));
856 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "localhost"));
857 EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "3"));
858}
859
Austin Schuhfc7b6a02021-07-12 21:19:07 -0700860// Tests that SourceNodeIndex reasonably handles a multi-node log file.
861TEST_F(ConfigurationTest, SourceNodeIndex) {
862 FlatbufferDetachedBuffer<Configuration> config =
863 ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
864 std::vector<size_t> result = SourceNodeIndex(&config.message());
865
866 EXPECT_THAT(result, ::testing::ElementsAreArray({0, 1, 0, 0}));
867}
868
Austin Schuh5e95bd62021-10-11 18:40:22 -0700869// Tests that we reject invalid logging configurations.
870TEST_F(ConfigurationDeathTest, InvalidLoggerConfig) {
871 EXPECT_DEATH(
872 {
873 FlatbufferDetachedBuffer<Configuration> config =
874 ReadConfig(ArtifactPath("aos/testdata/invalid_logging_configuration.json"));
875 },
876 "Logging timestamps without data");
877}
878
Austin Schuhcb108412019-10-13 16:09:54 -0700879} // namespace testing
880} // namespace configuration
881} // namespace aos