blob: 8e427d533712858baba536e8e7cca1ac57df4e43 [file] [log] [blame]
// Copyright 2020 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 {
component_hub::io::Directory,
component_hub::{doctor, list, select, show},
fidl_fidl_examples_routing_echo as fecho,
fuchsia_component::client::connect_to_protocol,
moniker::{AbsoluteMoniker, AbsoluteMonikerBase},
regex::Regex,
std::path::PathBuf,
};
const URL_REGEX: &str = r"fuchsia-pkg://fuchsia\.com/component_hub_integration_tests(\?hash=[0-9a-f]{64})?#meta/test\.cm";
#[fuchsia_async::run_singlethreaded(test)]
async fn list() {
let hub_path = PathBuf::from("/hub");
let hub_dir = Directory::from_namespace(hub_path).unwrap();
let list::Component { name, moniker, is_cmx, is_running, url, children } =
list::Component::parse(
"test_root".to_string(),
AbsoluteMoniker::parse_str("/test").unwrap(),
hub_dir,
)
.await
.unwrap();
assert!(!is_cmx);
assert!(is_running);
assert_eq!(name, "test_root");
assert_eq!(moniker.to_string(), "/test");
assert!(Regex::new(URL_REGEX).unwrap().is_match(&url));
assert_eq!(children.len(), 2);
let list::Component {
name,
moniker,
is_cmx,
is_running: _,
url: _url,
children: echo_server_children,
} = children.get(0).unwrap();
assert_eq!(name, "echo_server");
assert_eq!(moniker.to_string(), "/test/echo_server");
// assert!(!is_running); // This is not supposed to be running, but running the doctor test first might cause this to fail.
assert!(!is_cmx);
assert!(echo_server_children.is_empty());
let list::Component { name, is_cmx, is_running: _, moniker, url: _url, children } =
children.get(1).unwrap();
assert_eq!(name, "foo");
assert_eq!(moniker.to_string(), "/test/foo");
// assert!(!is_running);
assert!(!is_cmx);
assert!(children.is_empty());
}
#[fuchsia_async::run_singlethreaded(test)]
async fn show() {
let hub_path = PathBuf::from("/hub");
let hub_dir = Directory::from_namespace(&hub_path).unwrap();
let components = show::find_components("test.cm".to_string(), hub_dir).await.unwrap();
assert_eq!(components.len(), 1);
let component = &components[0];
assert!(Regex::new(URL_REGEX).unwrap().is_match(&component.url));
assert!(component.moniker.is_root());
assert_eq!(component.component_type, "CML static component");
assert!(component.resolved.is_some());
let resolved = component.resolved.as_ref().unwrap();
// capabilities are sorted alphabetically
assert_eq!(
&vec![
"fidl.examples.routing.echo.Echo",
"fuchsia.foo.Bar",
"fuchsia.logger.LogSink",
"hub",
"pkg"
],
&resolved.incoming_capabilities
);
// We do not verify the contents of the execution, because they are largely dependent on
// the Rust Test Runner
assert!(component.execution.is_some());
let hub_dir = Directory::from_namespace(&hub_path).unwrap();
let components = show::find_components("foo.cm".to_string(), hub_dir).await.unwrap();
assert_eq!(components.len(), 1);
let component = &components[0];
assert_eq!(component.moniker, AbsoluteMoniker::parse_str("/foo").unwrap());
assert_eq!(component.url, "#meta/foo.cm");
assert_eq!(component.component_type, "CML static component");
assert!(component.execution.is_none());
// check foo's config
let resolved_foo =
component.resolved.as_ref().expect("foo is eager, should have been resolved");
assert_eq!(resolved_foo.config.len(), 2);
let field1 = &resolved_foo.config[0];
let field2 = &resolved_foo.config[1];
assert_eq!(field1.key, "my_string");
assert_eq!(field1.value, "\"hello, world!\"");
assert_eq!(field2.key, "my_uint8");
assert_eq!(field2.value, "255");
}
#[fuchsia_async::run_singlethreaded(test)]
async fn select() {
let hub_path = PathBuf::from("/hub");
let hub_dir = Directory::from_namespace(hub_path).unwrap();
let select::MatchingComponents { mut exposed, mut used } =
select::find_components("fuchsia.foo.Bar".to_string(), hub_dir).await.unwrap();
assert_eq!(exposed.len(), 1);
assert_eq!(used.len(), 1);
let exposed_component = exposed.remove(0);
let used_component = used.remove(0);
assert!(exposed_component.is_root());
assert!(used_component.is_root());
let hub_path = PathBuf::from("/hub");
let hub_dir = Directory::from_namespace(hub_path).unwrap();
let select::MatchingComponents { mut exposed, used } =
select::find_components("minfs".to_string(), hub_dir).await.unwrap();
assert_eq!(exposed.len(), 1);
assert_eq!(used.len(), 0);
let exposed_component = exposed.remove(0);
assert!(exposed_component.is_root());
}
#[fuchsia_async::run_singlethreaded(test)]
async fn clone() {
let hub_path = PathBuf::from("/hub");
let hub_dir = Directory::from_namespace(hub_path).unwrap();
assert!(hub_dir.clone().is_ok());
}
#[fuchsia_async::run_singlethreaded(test)]
async fn doctor() {
let hub_path = PathBuf::from("/hub");
let hub_dir = Directory::from_namespace(&hub_path).unwrap();
let mut doctor_self =
doctor::DoctorComponent::from_moniker(AbsoluteMoniker::parse_str("/").unwrap(), &hub_dir)
.await
.unwrap();
assert!(!doctor_self.failed);
let self_exposed_outgoing_check_res = doctor_self.check_exposed_outgoing_capabilities();
assert!(!self_exposed_outgoing_check_res.success);
assert_eq!(
self_exposed_outgoing_check_res.missing_outgoing,
vec!["fuchsia.foo.Bar".to_string(), "minfs".to_string()]
);
assert!(self_exposed_outgoing_check_res.missing_exposed.is_empty());
let echo = connect_to_protocol::<fecho::EchoMarker>().expect("error connecting to echo server");
let echoed = echo.echo_string(Some("hippos")).await.expect("echo_string failed");
assert_eq!(echoed.unwrap(), "hippos");
let mut doctor_echo_server = doctor::DoctorComponent::from_moniker(
AbsoluteMoniker::parse_str("/echo_server").unwrap(),
&hub_dir,
)
.await
.unwrap();
assert!(!doctor_echo_server.failed);
let echo_server_exposed_outgoing_check_res =
doctor_echo_server.check_exposed_outgoing_capabilities();
assert!(!echo_server_exposed_outgoing_check_res.success);
// TODO(fxb/96477) Doctor should ignore the "hub" capability.
assert_eq!(
echo_server_exposed_outgoing_check_res.missing_outgoing,
vec!["fuchsia.component.Binder".to_string(), "hub".to_string()]
);
assert!(echo_server_exposed_outgoing_check_res.missing_exposed.is_empty());
}