aconfig: cache: reject empty namespace and name fields

Add invariant to struct Cache: all flag namespace and name fields added
to the cache are required to be non-empty strings.

Bug: 279485059
Test: atest aconfig.test
Change-Id: I5ff34ec8feccc19e52241d4221fc87699518f3ff
diff --git a/tools/aconfig/src/cache.rs b/tools/aconfig/src/cache.rs
index 5ef1829..c546f7b 100644
--- a/tools/aconfig/src/cache.rs
+++ b/tools/aconfig/src/cache.rs
@@ -52,8 +52,9 @@
 }
 
 impl Cache {
-    pub fn new(namespace: String) -> Cache {
-        Cache { namespace, items: vec![] }
+    pub fn new(namespace: String) -> Result<Cache> {
+        ensure!(!namespace.is_empty(), "empty namespace");
+        Ok(Cache { namespace, items: vec![] })
     }
 
     pub fn read_from_reader(reader: impl Read) -> Result<Cache> {
@@ -69,6 +70,8 @@
         source: Source,
         declaration: FlagDeclaration,
     ) -> Result<()> {
+        ensure!(!declaration.name.is_empty(), "empty flag name");
+        ensure!(!declaration.description.is_empty(), "empty flag description");
         ensure!(
             self.items.iter().all(|item| item.name != declaration.name),
             "failed to declare flag {} from {}: flag already declared",
@@ -91,6 +94,8 @@
     }
 
     pub fn add_flag_value(&mut self, source: Source, value: FlagValue) -> Result<()> {
+        ensure!(!value.namespace.is_empty(), "empty flag namespace");
+        ensure!(!value.name.is_empty(), "empty flag name");
         ensure!(
             value.namespace == self.namespace,
             "failed to set values for flag {}/{} from {}: expected namespace {}",
@@ -121,6 +126,7 @@
     }
 
     pub fn namespace(&self) -> &str {
+        debug_assert!(!self.namespace.is_empty());
         &self.namespace
     }
 }
@@ -132,7 +138,7 @@
 
     #[test]
     fn test_add_flag_declaration() {
-        let mut cache = Cache::new("ns".to_string());
+        let mut cache = Cache::new("ns".to_string()).unwrap();
         cache
             .add_flag_declaration(
                 Source::File("first.txt".to_string()),
@@ -158,7 +164,7 @@
             item.state == expected.0 && item.permission == expected.1
         }
 
-        let mut cache = Cache::new("ns".to_string());
+        let mut cache = Cache::new("ns".to_string()).unwrap();
         let error = cache
             .add_flag_value(
                 Source::Memory,
@@ -224,4 +230,67 @@
         assert_eq!(&format!("{:?}", error), "failed to set values for flag some-other-namespace/foo from <memory>: expected namespace ns");
         assert!(check(&cache, "foo", (FlagState::Enabled, Permission::ReadWrite)));
     }
+
+    #[test]
+    fn test_reject_empty_cache_namespace() {
+        Cache::new("".to_string()).unwrap_err();
+    }
+
+    #[test]
+    fn test_reject_empty_flag_declaration_fields() {
+        let mut cache = Cache::new("ns".to_string()).unwrap();
+
+        let error = cache
+            .add_flag_declaration(
+                Source::Memory,
+                FlagDeclaration { name: "".to_string(), description: "Description".to_string() },
+            )
+            .unwrap_err();
+        assert_eq!(&format!("{:?}", error), "empty flag name");
+
+        let error = cache
+            .add_flag_declaration(
+                Source::Memory,
+                FlagDeclaration { name: "foo".to_string(), description: "".to_string() },
+            )
+            .unwrap_err();
+        assert_eq!(&format!("{:?}", error), "empty flag description");
+    }
+
+    #[test]
+    fn test_reject_empty_flag_value_files() {
+        let mut cache = Cache::new("ns".to_string()).unwrap();
+        cache
+            .add_flag_declaration(
+                Source::Memory,
+                FlagDeclaration { name: "foo".to_string(), description: "desc".to_string() },
+            )
+            .unwrap();
+
+        let error = cache
+            .add_flag_value(
+                Source::Memory,
+                FlagValue {
+                    namespace: "".to_string(),
+                    name: "foo".to_string(),
+                    state: FlagState::Enabled,
+                    permission: Permission::ReadOnly,
+                },
+            )
+            .unwrap_err();
+        assert_eq!(&format!("{:?}", error), "empty flag namespace");
+
+        let error = cache
+            .add_flag_value(
+                Source::Memory,
+                FlagValue {
+                    namespace: "ns".to_string(),
+                    name: "".to_string(),
+                    state: FlagState::Enabled,
+                    permission: Permission::ReadOnly,
+                },
+            )
+            .unwrap_err();
+        assert_eq!(&format!("{:?}", error), "empty flag name");
+    }
 }