blob: 2719b12bdf504a53537f8600f045676091daa338 [file]
// Copyright 2019 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, Error},
component_manager_lib::{
builtin_environment::BuiltinEnvironmentBuilder,
model::{
binding::Binder, moniker::AbsoluteMoniker, realm::BindReason, testing::test_helpers,
},
startup,
},
fidl::endpoints::ServiceMarker,
fidl_fuchsia_io::{OPEN_RIGHT_READABLE, OPEN_RIGHT_WRITABLE},
fidl_fuchsia_test_manager::HarnessMarker,
fuchsia_async as fasync,
fuchsia_component::server::{ServiceFs, ServiceObj},
fuchsia_syslog as syslog,
futures::prelude::*,
log::*,
std::{path::PathBuf, process},
};
/// Returns a usage message for the supported arguments.
pub fn usage() -> String {
format!(
"Usage: {} ",
std::env::args().next().unwrap_or("component_manager_for_test".to_string())
)
}
const NUM_THREADS: usize = 2;
/// This is a prototype used with ftf to launch v2 tests.
/// This is a temporary workaround till we get around using actual component manager.
/// We will start test as root component and using hub v2 attach its "expose/svc" directory to this
/// managers out/svc(v1 version) directory.
fn main() -> Result<(), Error> {
syslog::init_with_tags(&["component_manager_for_test"])?;
let mut executor = fasync::Executor::new().context("error creating executor")?;
let args = std::env::args();
// replace first argument(binary name) with test manager envelope so that it
// can be launched as root component.
let args =
vec!["fuchsia-pkg://fuchsia.com/component_manager_for_test#meta/test_manager_envelope.cm"
.to_owned()]
.into_iter()
.chain(args.skip(1));
let args = match startup::Arguments::new(args) {
Ok(args) => args,
Err(err) => {
error!("{}\n{}", err, usage());
return Err(err);
}
};
info!("Component manager for test is starting up...");
executor.run(run_root(args), NUM_THREADS)
}
// Run root component and expose services.
async fn run_root(args: startup::Arguments) -> Result<(), Error> {
// Set up environment.
let builtin_environment = BuiltinEnvironmentBuilder::new()
.set_args(args)
.populate_config_from_args()
.await?
.add_elf_runner()?
.include_namespace_resolvers()
.build()
.await?;
let hub_proxy = builtin_environment.bind_service_fs_for_hub().await?;
let root_moniker = AbsoluteMoniker::root();
match builtin_environment.model.bind(&root_moniker, &BindReason::Root).await {
Ok(_) => {
// TODO: Exit the component manager when the root component's binding is lost
// (when it terminates).
}
Err(error) => {
error!("Failed to bind to root component: {:?}", error);
process::exit(1)
}
}
// make sure root component exposes test suite protocol.
let expose_dir_proxy = io_util::open_directory(
&hub_proxy,
&PathBuf::from("exec/expose"),
OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
)
.expect("Failed to open directory");
assert_eq!(
vec![HarnessMarker::DEBUG_NAME],
test_helpers::list_directory(&expose_dir_proxy).await
);
// bind expose/svc to out/svc of this v1 component.
let mut fs = ServiceFs::<ServiceObj<'_, ()>>::new();
fs.add_remote("svc", expose_dir_proxy);
fs.take_and_serve_directory_handle()?;
fs.collect::<()>().await;
Ok(())
}