Add GetNodesWithTag
This makes tags much easier to work with. It is common to want to find
all the matching nodes for a tag/function.
Change-Id: Ibe2876fc825dea1ffee5686f7e40dce85ebc8793
diff --git a/aos/configuration.cc b/aos/configuration.cc
index 1d39f27..67d2b96 100644
--- a/aos/configuration.cc
+++ b/aos/configuration.cc
@@ -956,6 +956,31 @@
return nodes;
}
+std::vector<const Node *> GetNodesWithTag(const Configuration *config,
+ std::string_view tag) {
+ std::vector<const Node *> nodes;
+ if (!MultiNode(config)) {
+ nodes.emplace_back(nullptr);
+ } else {
+ for (const Node *node : *config->nodes()) {
+ if (!node->has_tags()) {
+ continue;
+ }
+ bool did_found_tag = false;
+ for (const flatbuffers::String *found_tag : *node->tags()) {
+ if (found_tag->string_view() == tag) {
+ did_found_tag = true;
+ break;
+ }
+ }
+ if (did_found_tag) {
+ nodes.emplace_back(node);
+ }
+ }
+ }
+ return nodes;
+}
+
bool MultiNode(const Configuration *config) { return config->has_nodes(); }
bool ChannelIsSendableOnNode(const Channel *channel, const Node *node) {
diff --git a/aos/configuration.h b/aos/configuration.h
index 5579334..7383a1a 100644
--- a/aos/configuration.h
+++ b/aos/configuration.h
@@ -96,6 +96,11 @@
// in a single node world.)
std::vector<const Node *> GetNodes(const Configuration *config);
+// Returns a vector of the nodes in the config with the provided tag. If this
+// is a single-node world, we assume that all tags match.
+std::vector<const Node *> GetNodesWithTag(const Configuration *config,
+ std::string_view tag);
+
// Returns the node index for a node. Note: will be faster if node is a pointer
// to a node in config, but is not required.
int GetNodeIndex(const Configuration *config, const Node *node);
diff --git a/aos/configuration_test.cc b/aos/configuration_test.cc
index c800017..a5b3b59 100644
--- a/aos/configuration_test.cc
+++ b/aos/configuration_test.cc
@@ -700,6 +700,30 @@
}
}
+// Tests that we can pull out all the nodes with a tag.
+TEST_F(ConfigurationTest, GetNodesWithTag) {
+ {
+ FlatbufferDetachedBuffer<Configuration> config =
+ ReadConfig(kConfigPrefix + "good_multinode.json");
+ const Node *pi1 = GetNode(&config.message(), "pi1");
+ const Node *pi2 = GetNode(&config.message(), "pi2");
+
+ EXPECT_THAT(GetNodesWithTag(&config.message(), "a"),
+ ::testing::ElementsAre(pi1));
+ EXPECT_THAT(GetNodesWithTag(&config.message(), "b"),
+ ::testing::ElementsAre(pi2));
+ EXPECT_THAT(GetNodesWithTag(&config.message(), "c"),
+ ::testing::ElementsAre(pi1, pi2));
+ }
+
+ {
+ FlatbufferDetachedBuffer<Configuration> config =
+ ReadConfig(kConfigPrefix + "config1.json");
+ EXPECT_THAT(GetNodesWithTag(&config.message(), "arglfish"),
+ ::testing::ElementsAre(nullptr));
+ }
+}
+
// Tests that we can extract a node index from a config.
TEST_F(ConfigurationTest, GetNodeIndex) {
FlatbufferDetachedBuffer<Configuration> config =
diff --git a/aos/testdata/good_multinode.json b/aos/testdata/good_multinode.json
index 52a53b0..f344691 100644
--- a/aos/testdata/good_multinode.json
+++ b/aos/testdata/good_multinode.json
@@ -70,11 +70,13 @@
"nodes": [
{
"name": "pi1",
- "hostname": "raspberrypi"
+ "hostname": "raspberrypi",
+ "tags": ["a", "c"]
},
{
"name": "pi2",
- "hostname": "raspberrypi2"
+ "hostname": "raspberrypi2",
+ "tags": ["b", "c"]
}
]
}