blob: 4b52b2c2f4dfd394c9e02f754aa18fd089405ffa [file] [log] [blame]
// Copyright 2022 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::Error;
use fidl_fuchsia_io as fio;
use fuchsia_component_test::new::{
Capability, ChildOptions, LocalComponentHandles, RealmBuilder, Ref, Route,
};
use futures::channel::mpsc;
use futures::{FutureExt, SinkExt, StreamExt};
fn get_expected_config_contents() -> String {
std::fs::read_to_string("/pkg/data/example_config")
.expect("failed to read example config from test namespace")
}
async fn read_example_config_and_assert_contents(
path: &str,
handles: LocalComponentHandles,
mut success_sender: mpsc::Sender<()>,
) -> Result<(), Error> {
let config_dir =
handles.clone_from_namespace("config").expect("failed to clone config from namespace");
let example_config_file =
fuchsia_fs::directory::open_file(&config_dir, path, fio::OpenFlags::RIGHT_READABLE)
.await
.expect("failed to open example config file");
let example_config_contents = fuchsia_fs::file::read_to_string(&example_config_file)
.await
.expect("failed to read example config file");
assert_eq!(example_config_contents, get_expected_config_contents());
success_sender.send(()).await.expect("failed to send success");
Ok(())
}
#[fuchsia::test]
async fn offer_pkg_from_framework() {
let (success_sender, mut success_receiver) = mpsc::channel(1);
let builder = RealmBuilder::new().await.unwrap();
let config_reader = builder
.add_local_child(
"config-reader",
move |h| {
read_example_config_and_assert_contents("example_config", h, success_sender.clone())
.boxed()
},
ChildOptions::new().eager(),
)
.await
.unwrap();
builder
.add_route(
Route::new()
.capability(
Capability::directory("pkg")
.as_("config")
.subdir("data")
.path("/config")
.rights(fio::R_STAR_DIR),
)
.from(Ref::framework())
.to(&config_reader),
)
.await
.unwrap();
let _instance =
builder.build_in_nested_component_manager("#meta/component_manager.cm").await.unwrap();
assert!(
success_receiver.next().await.is_some(),
"failed to receive success signal from local component"
);
}
#[fuchsia::test]
async fn offer_pkg_from_framework_no_subdir() {
let (success_sender, mut success_receiver) = mpsc::channel(1);
let builder = RealmBuilder::new().await.unwrap();
let config_reader = builder
.add_local_child(
"config-reader",
move |h| {
read_example_config_and_assert_contents(
"data/example_config",
h,
success_sender.clone(),
)
.boxed()
},
ChildOptions::new().eager(),
)
.await
.unwrap();
builder
.add_route(
Route::new()
.capability(
Capability::directory("pkg")
.as_("config")
.path("/config")
.rights(fio::R_STAR_DIR),
)
.from(Ref::framework())
.to(&config_reader),
)
.await
.unwrap();
let _instance =
builder.build_in_nested_component_manager("#meta/component_manager.cm").await.unwrap();
assert!(
success_receiver.next().await.is_some(),
"failed to receive success signal from local component"
);
}
#[fuchsia::test]
async fn expose_pkg_from_framework() {
let (success_sender, mut success_receiver) = mpsc::channel(1);
let builder = RealmBuilder::new().await.unwrap();
let config_reader = builder
.add_local_child(
"config-reader",
move |h| {
read_example_config_and_assert_contents("example_config", h, success_sender.clone())
.boxed()
},
ChildOptions::new().eager(),
)
.await
.unwrap();
let config_provider = builder
.add_child_from_decl(
"config-provider",
cm_rust::ComponentDecl {
exposes: vec![cm_rust::ExposeDecl::Directory(cm_rust::ExposeDirectoryDecl {
source: cm_rust::ExposeSource::Framework,
source_name: "pkg".parse().unwrap(),
source_dictionary: Default::default(),
target: cm_rust::ExposeTarget::Parent,
target_name: "config".parse().unwrap(),
rights: Some(fio::R_STAR_DIR),
subdir: "data".parse().unwrap(),
availability: cm_rust::Availability::Required,
})],
..cm_rust::ComponentDecl::default()
},
ChildOptions::new(),
)
.await
.unwrap();
builder
.add_route(
Route::new()
.capability(Capability::directory("config").path("/config").rights(fio::R_STAR_DIR))
.from(&config_provider)
.to(&config_reader),
)
.await
.unwrap();
let _instance =
builder.build_in_nested_component_manager("#meta/component_manager.cm").await.unwrap();
assert!(
success_receiver.next().await.is_some(),
"failed to receive success signal from local component"
);
}
#[fuchsia::test]
async fn use_pkg_from_framework() {
let (success_sender, mut success_receiver) = mpsc::channel(1);
let builder = RealmBuilder::new().await.unwrap();
let config_reader = builder
.add_local_child(
"config-reader",
move |h| {
read_example_config_and_assert_contents("example_config", h, success_sender.clone())
.boxed()
},
ChildOptions::new().eager(),
)
.await
.unwrap();
let mut config_reader_decl = builder.get_component_decl(&config_reader).await.unwrap();
config_reader_decl.uses.push(cm_rust::UseDecl::Directory(cm_rust::UseDirectoryDecl {
source: cm_rust::UseSource::Framework,
source_name: "pkg".parse().unwrap(),
source_dictionary: Default::default(),
target_path: "/config".parse().unwrap(),
rights: fio::R_STAR_DIR,
subdir: "data".parse().unwrap(),
dependency_type: cm_rust::DependencyType::Strong,
availability: cm_rust::Availability::Required,
}));
builder.replace_component_decl(&config_reader, config_reader_decl).await.unwrap();
let _instance =
builder.build_in_nested_component_manager("#meta/component_manager.cm").await.unwrap();
assert!(
success_receiver.next().await.is_some(),
"failed to receive success signal from local component"
);
}