aconfig: introduce namespace, rename proto messages
Flags belong to a namespace. Update the proto files to reflect this.
Config files can only refer to a single namespace. Override files can
refer to multiple namespaces; an override directive for a flag in a
different namespace than the one represented by the cache will be
silently ignored.
Rename the proto messages to make it more clear what they are. Propagate
this change through the wrappers in aconfig.rs and the rest of the code.
Also, settle on Tracepoint instead of TracePoint.
Bug: 279485059
Test: atest aconfig.test
Change-Id: I16e69dd14687bc498b2ba89d6a35879459903801
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index 645d395..2c80a4a 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -14,16 +14,16 @@
* limitations under the License.
*/
-use anyhow::{Context, Result};
+use anyhow::{ensure, Context, Result};
use clap::ValueEnum;
use protobuf::Message;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::io::Read;
-use crate::aconfig::{Flag, Override};
+use crate::aconfig::{Namespace, Override};
use crate::cache::Cache;
-use crate::protos::ProtoDump;
+use crate::protos::ProtoParsedFlags;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum Source {
@@ -46,15 +46,27 @@
pub reader: Box<dyn Read>,
}
-pub fn create_cache(build_id: u32, aconfigs: Vec<Input>, overrides: Vec<Input>) -> Result<Cache> {
- let mut cache = Cache::new(build_id);
+pub fn create_cache(
+ build_id: u32,
+ namespace: &str,
+ aconfigs: Vec<Input>,
+ overrides: Vec<Input>,
+) -> Result<Cache> {
+ let mut cache = Cache::new(build_id, namespace.to_owned());
for mut input in aconfigs {
let mut contents = String::new();
input.reader.read_to_string(&mut contents)?;
- let flags = Flag::try_from_text_proto_list(&contents)
+ let ns = Namespace::try_from_text_proto(&contents)
.with_context(|| format!("Failed to parse {}", input.source))?;
- for flag in flags {
+ ensure!(
+ namespace == ns.namespace,
+ "Failed to parse {}: expected namespace {}, got {}",
+ input.source,
+ namespace,
+ ns.namespace
+ );
+ for flag in ns.flags.into_iter() {
cache.add_flag(input.source.clone(), flag)?;
}
}
@@ -84,7 +96,7 @@
Format::Text => {
let mut lines = vec![];
for item in cache.iter() {
- lines.push(format!("{}: {:?}\n", item.id, item.state));
+ lines.push(format!("{}: {:?}\n", item.name, item.state));
}
Ok(lines.concat().into())
}
@@ -96,9 +108,9 @@
Ok(lines.concat().into())
}
Format::Protobuf => {
- let dump: ProtoDump = cache.into();
+ let parsed_flags: ProtoParsedFlags = cache.into();
let mut output = vec![];
- dump.write_to_vec(&mut output)?;
+ parsed_flags.write_to_vec(&mut output)?;
Ok(output)
}
}
@@ -111,8 +123,9 @@
fn create_test_cache() -> Cache {
let s = r#"
+ namespace: "ns"
flag {
- id: "a"
+ name: "a"
description: "Description of a"
value {
state: ENABLED
@@ -120,7 +133,7 @@
}
}
flag {
- id: "b"
+ name: "b"
description: "Description of b"
value {
state: ENABLED
@@ -130,20 +143,21 @@
"#;
let aconfigs = vec![Input { source: Source::Memory, reader: Box::new(s.as_bytes()) }];
let o = r#"
- override {
- id: "a"
+ flag_override {
+ namespace: "ns"
+ name: "a"
state: DISABLED
permission: READ_ONLY
}
"#;
let overrides = vec![Input { source: Source::Memory, reader: Box::new(o.as_bytes()) }];
- create_cache(1, aconfigs, overrides).unwrap()
+ create_cache(1, "ns", aconfigs, overrides).unwrap()
}
#[test]
fn test_create_cache() {
let cache = create_test_cache(); // calls create_cache
- let item = cache.iter().find(|&item| item.id == "a").unwrap();
+ let item = cache.iter().find(|&item| item.name == "a").unwrap();
assert_eq!(FlagState::Disabled, item.state);
assert_eq!(Permission::ReadOnly, item.permission);
}
@@ -158,15 +172,29 @@
#[test]
fn test_dump_protobuf_format() {
+ use crate::protos::{ProtoFlagPermission, ProtoFlagState, ProtoTracepoint};
use protobuf::Message;
let cache = create_test_cache();
let bytes = dump_cache(cache, Format::Protobuf).unwrap();
- let actual = ProtoDump::parse_from_bytes(&bytes).unwrap();
+ let actual = ProtoParsedFlags::parse_from_bytes(&bytes).unwrap();
assert_eq!(
vec!["a".to_string(), "b".to_string()],
- actual.item.iter().map(|item| item.id.clone().unwrap()).collect::<Vec<_>>()
+ actual.parsed_flag.iter().map(|item| item.name.clone().unwrap()).collect::<Vec<_>>()
);
+
+ let item =
+ actual.parsed_flag.iter().find(|item| item.name == Some("b".to_string())).unwrap();
+ assert_eq!(item.namespace(), "ns");
+ assert_eq!(item.name(), "b");
+ assert_eq!(item.description(), "Description of b");
+ assert_eq!(item.state(), ProtoFlagState::ENABLED);
+ assert_eq!(item.permission(), ProtoFlagPermission::READ_ONLY);
+ let mut tp = ProtoTracepoint::new();
+ tp.set_source("<memory>".to_string());
+ tp.set_state(ProtoFlagState::ENABLED);
+ tp.set_permission(ProtoFlagPermission::READ_ONLY);
+ assert_eq!(item.trace, vec![tp]);
}
}