blob: 72caf139203f3a5db985a12d21658c5f40f6c55a [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.
//! This test component creates a test component under the environment `sub`. This component has the option:
//! - with-event-listener: listens for started events of sub components.
use {
anyhow::{Context, Error},
fidl::endpoints::DiscoverableService,
fidl_fuchsia_sys::{
EnvironmentControllerEvent, EnvironmentControllerProxy, EnvironmentMarker,
EnvironmentOptions, EnvironmentProxy, ServiceProviderMarker,
},
fidl_fuchsia_sys_internal::{
ComponentEventListenerMarker, ComponentEventListenerRequest,
ComponentEventListenerRequestStream, ComponentEventProviderMarker,
ComponentEventProviderProxy,
},
fuchsia_async as fasync,
fuchsia_component::{
client::{connect_to_service, launch},
server::ServiceFs,
},
futures::prelude::*,
lazy_static::lazy_static,
};
lazy_static! {
static ref TEST_COMPONENT_URL: &'static str =
"fuchsia-pkg://fuchsia.com/component_events_integration_tests#meta/test_component.cmx";
static ref SELF_COMPONENT: &'static str = "test_component_with_subrealm.cmx";
static ref TEST_COMPONENT: &'static str = "test_component.cmx";
}
async fn create_nested_environment(
parent: &EnvironmentProxy,
label: &str,
) -> Result<(EnvironmentProxy, EnvironmentControllerProxy), Error> {
let (new_env, new_env_server_end) =
fidl::endpoints::create_proxy::<EnvironmentMarker>().context("could not create proxy")?;
let (controller, controller_server_end) =
fidl::endpoints::create_proxy().context("could not create proxy")?;
let mut env_options = EnvironmentOptions {
inherit_parent_services: true,
use_parent_runners: true,
kill_on_oom: true,
delete_storage_on_death: true,
};
parent
.create_nested_environment(
new_env_server_end,
controller_server_end,
label,
None,
&mut env_options,
)
.context("could not create isolated environment")?;
let EnvironmentControllerEvent::OnCreated {} = controller
.take_event_stream()
.next()
.await
.unwrap()
.expect("failed to get env created event");
Ok((new_env, controller))
}
fn listen_for_component_events(
env: &EnvironmentProxy,
) -> Result<(ComponentEventProviderProxy, ComponentEventListenerRequestStream), Error> {
let (service_provider, server_end) =
fidl::endpoints::create_proxy::<ServiceProviderMarker>().context("create proxy")?;
env.get_services(server_end)?;
let (event_provider, server_end) =
fidl::endpoints::create_proxy::<ComponentEventProviderMarker>().context("create proxy")?;
service_provider.connect_to_service(
ComponentEventProviderMarker::SERVICE_NAME,
server_end.into_channel(),
)?;
let (events_client_end, listener_request_stream) =
fidl::endpoints::create_request_stream::<ComponentEventListenerMarker>()
.context("Create request stream")?;
event_provider.set_listener(events_client_end)?;
Ok((event_provider, listener_request_stream))
}
#[fasync::run_singlethreaded]
async fn main() -> Result<(), Error> {
let mut fs = ServiceFs::new();
let env = connect_to_service::<EnvironmentMarker>().expect("connect to current environment");
let (nested_env, _env_controller) =
create_nested_environment(&env, "sub").await.context("create env")?;
let args: Vec<String> = std::env::args().collect();
let (launcher, launcher_server_end) =
fidl::endpoints::create_proxy().context("launcher proxy")?;
nested_env.get_launcher(launcher_server_end).context("get launcher")?;
let _app = launch(&launcher, TEST_COMPONENT_URL.to_string(), None)?;
// Keep provider and stream alive for the lifetime of the program.
let (provider, mut stream) = {
if args.len() > 1 && args[1] == "with-event-listener" {
let (p, s) = listen_for_component_events(&env).context("listen for events")?;
(Some(p), Some(s))
} else {
(None, None)
}
};
match (provider.as_ref(), stream.as_mut()) {
(Some(_), Some(stream)) => {
let request = stream.try_next().await.expect("Fetch self start");
if let Some(ComponentEventListenerRequest::OnStart { component, .. }) = request {
assert_eq!(component.component_name, Some(SELF_COMPONENT.to_string()));
}
let request = stream.try_next().await.expect("Fetch component start");
if let Some(ComponentEventListenerRequest::OnStart { component, .. }) = request {
assert_eq!(component.component_name, Some(TEST_COMPONENT.to_string()));
}
}
_ => {}
}
fs.take_and_serve_directory_handle()?;
fs.collect::<()>().await;
Ok(())
}