blob: fcf30027c8f71d6d9d12b6809d4ac5b9ba02de28 [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use anyhow::Context as _;
use diagnostics_assertions::assert_data_tree;
use diagnostics_reader::{ArchiveReader, Inspect};
use fidl_fuchsia_component::{BinderMarker, CreateChildArgs, RealmMarker};
use fidl_fuchsia_component_decl::{
Child, CollectionRef, ConfigOverride, ConfigSingleValue, ConfigValue, StartupMode,
};
use fuchsia_component::client::{
connect_to_protocol, connect_to_protocol_at_dir_root, open_childs_exposed_directory,
};
use fuchsia_component_test::{Capability, ChildOptions, RealmBuilder, Ref, Route};
const CHILD_URL: &str = "#meta/config_example.cm";
const COLLECTION_NAME: &str = "realm_api_collection";
#[fuchsia::test]
async fn inspect_parent_override() -> anyhow::Result<()> {
let child_name = "dynamic_child_realm_api_parent_values";
let expected_greeting = "parent component";
let realm = connect_to_protocol::<RealmMarker>()?;
// [START create_child]
let child_decl = Child {
name: Some(child_name.to_string()),
url: Some(String::from(CHILD_URL)),
startup: Some(StartupMode::Lazy),
config_overrides: Some(vec![ConfigOverride {
key: Some("greeting".to_string()),
value: Some(ConfigValue::Single(ConfigSingleValue::String(
expected_greeting.to_string(),
))),
..ConfigOverride::default()
}]),
..Child::default()
};
let collection_ref = CollectionRef { name: COLLECTION_NAME.to_string() };
realm
.create_child(&collection_ref, &child_decl, CreateChildArgs::default())
.await
.context("sending create child message")?
.map_err(|e| anyhow::format_err!("creating child: {e:?}"))?;
// [END create_child]
let exposed_dir = open_childs_exposed_directory(child_name, Some(COLLECTION_NAME.to_string()))
.await
.context("opening exposed directory")?;
connect_to_protocol_at_dir_root::<BinderMarker>(&exposed_dir)
.context("connecting to Binder")?;
let example_payload = ArchiveReader::new()
.add_selector(format!("{COLLECTION_NAME}\\:{child_name}:root"))
.with_minimum_schema_count(1)
.snapshot::<Inspect>()
.await
.context("snapshotting inspect")?
.into_iter()
.next()
.and_then(|result| result.payload)
.context("getting first paylod")?;
assert_eq!(example_payload.children.len(), 1, "selector must return exactly one child");
assert_data_tree!(example_payload, root: {
config: {
greeting: expected_greeting,
}
});
Ok(())
}
/// This test ensures that the test above is passing because parent overrides work rather than
/// lucking into the same value as the packaged config.
#[fuchsia::test]
async fn inspect_default_value() -> anyhow::Result<()> {
let child_name = "dynamic_child_realm_api_default_values";
let expected_greeting = "World";
let realm = connect_to_protocol::<RealmMarker>()?;
let child_decl = Child {
name: Some(child_name.to_string()),
url: Some(String::from(CHILD_URL)),
startup: Some(StartupMode::Lazy),
..Child::default()
};
let collection_ref = CollectionRef { name: COLLECTION_NAME.to_string() };
realm
.create_child(&collection_ref, &child_decl, CreateChildArgs::default())
.await
.context("sending create child message")?
.map_err(|e| anyhow::format_err!("creating child: {e:?}"))?;
let exposed_dir = open_childs_exposed_directory(child_name, Some(COLLECTION_NAME.to_string()))
.await
.context("opening exposed directory")?;
connect_to_protocol_at_dir_root::<BinderMarker>(&exposed_dir)
.context("connecting to Binder")?;
let example_payload = ArchiveReader::new()
.add_selector(format!("{COLLECTION_NAME}\\:{child_name}:root"))
.with_minimum_schema_count(1)
.snapshot::<Inspect>()
.await
.context("snapshotting inspect")?
.into_iter()
.next()
.and_then(|result| result.payload)
.context("getting first paylod")?;
assert_eq!(example_payload.children.len(), 1, "selector must return exactly one child");
assert_data_tree!(example_payload, root: {
config: {
greeting: expected_greeting,
}
});
Ok(())
}
#[fuchsia::test]
async fn inspect_realm_builder_parent_override() {
let mut child_overrides: Vec<fidl_fuchsia_component_decl::ConfigOverride> =
Vec::with_capacity(1);
child_overrides.push(fidl_fuchsia_component_decl::ConfigOverride {
key: Some("greeting".to_string()),
value: Some(fidl_fuchsia_component_decl::ConfigValue::Single(
fidl_fuchsia_component_decl::ConfigSingleValue::String("parent component".to_string()),
)),
..Default::default()
});
let builder = RealmBuilder::new().await.unwrap();
let config_component = builder
.add_child(
"config_example_realm_builder_parent_override",
CHILD_URL,
ChildOptions::new().eager().config_overrides(child_overrides),
)
.await
.unwrap();
builder
.add_route(
Route::new()
.capability(Capability::protocol_by_name("fuchsia.logger.LogSink"))
.from(Ref::parent())
.to(&config_component),
)
.await
.unwrap();
let _instance = builder.build().await.unwrap();
let inspector = ArchiveReader::new()
.add_selector("*/config_example_realm_builder_parent_override:root")
.with_minimum_schema_count(1)
.snapshot::<Inspect>()
.await
.unwrap()
.into_iter()
.next()
.and_then(|result| result.payload)
.unwrap();
assert_eq!(inspector.children.len(), 1, "selector must return exactly one child");
assert_data_tree!(inspector, root: {
config: {
greeting: "parent component",
}
})
}