blob: e23e411ae641dd6be562d6809cabca7f0bcceac0 [file] [log] [blame]
// 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.
#![recursion_limit = "512"]
use {
anyhow::{format_err, Error},
directory_broker, fdio,
fidl::endpoints::{create_endpoints, create_proxy, Proxy},
fidl_fidl_examples_echo as fidl_echo, fidl_fuchsia_io as fio, fuchsia_async as fasync,
fuchsia_runtime::{job_default, HandleInfo, HandleType},
fuchsia_vfs_pseudo_fs_mt::{
directory::entry::DirectoryEntry, execution_scope::ExecutionScope,
file::pcb::asynchronous::read_only_static, path::Path as pfsPath, pseudo_directory,
},
fuchsia_zircon::HandleBased,
io_util,
std::{ffi::CString, path::Path},
};
/// This integration test creates a new appmgr process and confirms that it can connect to a sysmgr
/// run echo service through appmgr's outgoing directory.
const APPMGR_BIN_PATH: &'static str = "/pkg/bin/appmgr";
const SYSMGR_SERVICES_CONFIG: &'static str = r#"{
"services": {
"fidl.examples.echo.Echo": "fuchsia-pkg://fuchsia.com/echo_server#meta/echo_server.cmx"
}
}"#;
const APPMGR_SCHEME_MAP: &'static str = r#"{
"launchers": {
"package": [ "file", "fuchsia-pkg" ]
}
}
"#;
#[fasync::run_singlethreaded]
async fn main() -> Result<(), Error> {
let (appmgr_out_dir_proxy, appmgr_out_dir_server_end) = create_proxy::<fio::DirectoryMarker>()?;
let mut spawn_actions = vec![];
spawn_actions.push(fdio::SpawnAction::add_handle(
HandleInfo::new(HandleType::DirectoryRequest, 0),
appmgr_out_dir_server_end.into_channel().into_handle(),
));
let pkg_dir = io_util::open_directory_in_namespace("/pkg", io_util::OPEN_RIGHT_READABLE)
.expect("failed to open /pkg");
let pkg_c_str = CString::new("/pkg").unwrap();
spawn_actions.push(fdio::SpawnAction::add_namespace_entry(
&pkg_c_str,
pkg_dir.into_channel().unwrap().into_zx_channel().into_handle(),
));
let svc_dir = io_util::open_directory_in_namespace(
"/svc",
io_util::OPEN_RIGHT_READABLE | io_util::OPEN_RIGHT_WRITABLE,
)
.expect("failed to open /svc");
let svc_c_str = CString::new("/svc").unwrap();
spawn_actions.push(fdio::SpawnAction::add_namespace_entry(
&svc_c_str,
svc_dir.into_channel().unwrap().into_zx_channel().into_handle(),
));
let (pkgfs_client_end, pkgfs_server_end) = create_endpoints::<fio::NodeMarker>()?;
fasync::spawn(async move {
let pkg_dir = io_util::open_directory_in_namespace("/pkg", fio::OPEN_RIGHT_READABLE)
.expect("failed to open /pkg");
let pkg_dir_2 = io_util::clone_directory(&pkg_dir, fio::CLONE_FLAG_SAME_RIGHTS)
.expect("failed to clone /pkg handle");
let fake_pkgfs = pseudo_directory! {
"packages" => pseudo_directory! {
"sysmgr" => pseudo_directory! {
"0" => directory_broker::DirectoryBroker::from_directory_proxy(pkg_dir),
},
"echo_server" => pseudo_directory! {
"0" => directory_broker::DirectoryBroker::from_directory_proxy(pkg_dir_2),
},
"config-data" => pseudo_directory! {
"0" => pseudo_directory! {
"data" => pseudo_directory! {
"sysmgr" => pseudo_directory! {
"services.config" => read_only_static(SYSMGR_SERVICES_CONFIG),
},
"appmgr" => pseudo_directory! {
"scheme_map" => pseudo_directory! {
"default.config" => read_only_static(APPMGR_SCHEME_MAP),
}
},
},
},
},
},
};
fake_pkgfs.open(
ExecutionScope::from_executor(Box::new(fasync::EHandle::local())),
fio::OPEN_RIGHT_READABLE,
fio::MODE_TYPE_DIRECTORY,
pfsPath::empty(),
pkgfs_server_end,
);
});
let pkgfs_c_str = CString::new("/pkgfs").unwrap();
spawn_actions.push(fdio::SpawnAction::add_namespace_entry(
&pkgfs_c_str,
pkgfs_client_end.into_channel().into_handle(),
));
let (svc_for_sys_client_end, svc_for_sys_server_end) = create_endpoints::<fio::NodeMarker>()?;
fasync::spawn(async move {
let fake_svc_for_sys = pseudo_directory! {};
fake_svc_for_sys.open(
ExecutionScope::from_executor(Box::new(fasync::EHandle::local())),
fio::OPEN_RIGHT_READABLE,
fio::MODE_TYPE_DIRECTORY,
pfsPath::empty(),
svc_for_sys_server_end,
);
});
let svc_for_sys_c_str = CString::new("/svc_for_sys").unwrap();
spawn_actions.push(fdio::SpawnAction::add_namespace_entry(
&svc_for_sys_c_str,
svc_for_sys_client_end.into_channel().into_handle(),
));
let mut spawn_options = fdio::SpawnOptions::empty();
spawn_options.insert(fdio::SpawnOptions::DEFAULT_LOADER);
spawn_options.insert(fdio::SpawnOptions::CLONE_JOB);
spawn_options.insert(fdio::SpawnOptions::CLONE_STDIO);
let appmgr_bin_path_c_str = CString::new(APPMGR_BIN_PATH).unwrap();
let res = fdio::spawn_etc(
&job_default(),
spawn_options,
&appmgr_bin_path_c_str,
&[&appmgr_bin_path_c_str],
None,
spawn_actions.as_mut_slice(),
);
let _ =
res.map_err(|(status, msg)| format_err!("failed to spawn appmgr ({}): {:?}", status, msg))?;
let echo_service_node = io_util::open_node(
&appmgr_out_dir_proxy,
&Path::new("svc/fidl.examples.echo.Echo"),
fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_WRITABLE,
fio::MODE_TYPE_SERVICE,
)?;
let echo_node_chan = echo_service_node.into_channel().map_err(|e| format_err!("{:?}", e))?;
let echo_proxy = fidl_echo::EchoProxy::from_channel(echo_node_chan);
assert_eq!(Some("hippos!".to_string()), echo_proxy.echo_string(Some("hippos!")).await?);
Ok(())
}