Add utility function for appending channel to a config
This is helpful for certain log-replay tasks.
Change-Id: I46da77a0481ab1f7d61f7e9eb3ce8fe553e6c7ae
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/configuration.cc b/aos/configuration.cc
index ad6fb54..8b2e1b8 100644
--- a/aos/configuration.cc
+++ b/aos/configuration.cc
@@ -1618,5 +1618,31 @@
return RecursiveCopyFlatBuffer(found_schema);
}
+aos::FlatbufferDetachedBuffer<Configuration> AddChannelToConfiguration(
+ const Configuration *config, std::string_view name,
+ aos::FlatbufferVector<reflection::Schema> schema, const aos::Node *node,
+ ChannelT overrides) {
+ overrides.name = name;
+ overrides.type = schema.message().root_table()->name()->string_view();
+ if (node != nullptr) {
+ CHECK(node->has_name());
+ overrides.source_node = node->name()->string_view();
+ }
+ flatbuffers::FlatBufferBuilder fbb;
+ // Don't populate fields from overrides that the user doesn't explicitly
+ // override.
+ fbb.ForceDefaults(false);
+ const flatbuffers::Offset<Channel> channel_offset =
+ Channel::Pack(fbb, &overrides);
+ const flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Channel>>>
+ channels_offset = fbb.CreateVector({channel_offset});
+ Configuration::Builder config_builder(fbb);
+ config_builder.add_channels(channels_offset);
+ fbb.Finish(config_builder.Finish());
+ FlatbufferDetachedBuffer<Configuration> new_channel_config = fbb.Release();
+ new_channel_config = MergeConfiguration(new_channel_config, {schema});
+ return MergeWithConfig(config, new_channel_config);
+}
+
} // namespace configuration
} // namespace aos
diff --git a/aos/configuration.h b/aos/configuration.h
index 4d84b23..0e5ef74 100644
--- a/aos/configuration.h
+++ b/aos/configuration.h
@@ -227,6 +227,15 @@
GetSchemaDetachedBuffer(const Configuration *config,
std::string_view schema_type);
+// Adds the specified channel to the config and returns the new, merged, config.
+// The channel name is derived from the specified name, the type and schema from
+// the provided schema, the source node from the specified node, and all other
+// fields (e.g., frequency) will be derived from the overrides parameter.
+aos::FlatbufferDetachedBuffer<Configuration> AddChannelToConfiguration(
+ const Configuration *config, std::string_view name,
+ aos::FlatbufferVector<reflection::Schema> schema,
+ const aos::Node *source_node = nullptr, ChannelT overrides = {});
+
} // namespace configuration
// Compare and equality operators for Channel. Note: these only check the name
diff --git a/aos/configuration_test.cc b/aos/configuration_test.cc
index fc45d88..823f43c 100644
--- a/aos/configuration_test.cc
+++ b/aos/configuration_test.cc
@@ -1049,6 +1049,60 @@
std::nullopt);
}
+// Tests that we can use a utility to add individual channels to a single-node
+// config.
+TEST_F(ConfigurationTest, AddChannelToConfigSingleNode) {
+ FlatbufferDetachedBuffer<Configuration> base_config =
+ ReadConfig(ArtifactPath("aos/testdata/config1.json"));
+
+ FlatbufferVector<reflection::Schema> schema =
+ FileToFlatbuffer<reflection::Schema>(
+ ArtifactPath("aos/events/ping.bfbs"));
+
+ FlatbufferDetachedBuffer<Configuration> new_config =
+ AddChannelToConfiguration(&base_config.message(), "/new", schema);
+
+ ASSERT_EQ(new_config.message().channels()->size(),
+ base_config.message().channels()->size() + 1);
+
+ const Channel *channel =
+ GetChannel(new_config, "/new", "aos.examples.Ping", "", nullptr);
+ ASSERT_TRUE(channel != nullptr);
+ ASSERT_TRUE(channel->has_schema());
+ // Check that we don't populate channel settings that we don't override the
+ // defaults of.
+ ASSERT_FALSE(channel->has_frequency());
+}
+
+// Tests that we can use a utility to add individual channels to a multi-node
+// config.
+TEST_F(ConfigurationTest, AddChannelToConfigMultiNode) {
+ FlatbufferDetachedBuffer<Configuration> base_config =
+ ReadConfig(ArtifactPath("aos/testdata/good_multinode.json"));
+
+ FlatbufferVector<reflection::Schema> schema =
+ FileToFlatbuffer<reflection::Schema>(
+ ArtifactPath("aos/events/ping.bfbs"));
+
+ aos::ChannelT channel_overrides;
+ channel_overrides.frequency = 971;
+ FlatbufferDetachedBuffer<Configuration> new_config =
+ AddChannelToConfiguration(&base_config.message(), "/new", schema,
+ GetNode(&base_config.message(), "pi1"),
+ channel_overrides);
+
+ ASSERT_EQ(new_config.message().channels()->size(),
+ base_config.message().channels()->size() + 1);
+
+ const Channel *channel =
+ GetChannel(new_config, "/new", "aos.examples.Ping", "", nullptr);
+ ASSERT_TRUE(channel != nullptr);
+ ASSERT_TRUE(channel->has_schema());
+ ASSERT_TRUE(channel->has_source_node());
+ ASSERT_EQ("pi1", channel->source_node()->string_view());
+ ASSERT_EQ(971, channel->frequency());
+}
+
} // namespace testing
} // namespace configuration
} // namespace aos
diff --git a/aos/events/logging/log_replayer.cc b/aos/events/logging/log_replayer.cc
index 4de4052..0f7444a 100644
--- a/aos/events/logging/log_replayer.cc
+++ b/aos/events/logging/log_replayer.cc
@@ -70,25 +70,14 @@
const aos::Configuration *raw_config = FLAGS_config.empty()
? config_reader.configuration()
: &config.message();
- const std::string channel_node =
- aos::configuration::MultiNode(raw_config)
- ? absl::StrFormat("\"source_node\": \"%s%s",
- aos::configuration::GetMyNode(raw_config)
- ->name()
- ->string_view(),
- "\",")
- : "";
- config = aos::configuration::MergeWithConfig(
- raw_config,
- aos::configuration::AddSchema(
- absl::StrFormat(
- "{ \"channels\": [{ \"name\": \"/timing\", \"type\": "
- "\"aos.timing.ReplayTiming\", \"max_size\": 10000, "
- "\"frequency\": 10000, %s %s",
- channel_node, "\"num_senders\": 2 }]}"),
- {aos::FlatbufferVector<reflection::Schema>(
- aos::FlatbufferSpan<reflection::Schema>(
- aos::timing::ReplayTimingSchema()))}));
+ aos::ChannelT channel_overrides;
+ channel_overrides.max_size = 10000;
+ channel_overrides.frequency = 10000;
+ config = aos::configuration::AddChannelToConfiguration(
+ raw_config, "/timing",
+ aos::FlatbufferSpan<reflection::Schema>(
+ aos::timing::ReplayTimingSchema()),
+ aos::configuration::GetMyNode(raw_config), channel_overrides);
}
if (!FLAGS_merge_with_config.empty()) {