blob: 6d937ffb2f61146713f30c4c855af7d0eb0e1f8e [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 {
anyhow::{Context as _, Error},
async_trait::async_trait,
component_events::{
events::{Destroyed, Event},
injectors::{CapabilityInjector as _, ProtocolInjector},
matcher::EventMatcher,
sequence::{EventSequence, Ordering},
},
fidl_fuchsia_component_client_test::{EmptyProtocolMarker, EmptyProtocolRequestStream},
fuchsia_async as fasync, fuchsia_syslog as syslog,
futures::{SinkExt as _, StreamExt as _},
log::info,
std::sync::Arc,
test_case::test_case,
test_utils_lib::opaque_test::OpaqueTest,
};
struct PassthroughInjector {
sender: futures::channel::mpsc::Sender<EmptyProtocolRequestStream>,
}
#[async_trait]
impl ProtocolInjector for PassthroughInjector {
type Marker = EmptyProtocolMarker;
async fn serve(
self: Arc<Self>,
request_stream: EmptyProtocolRequestStream,
) -> Result<(), Error> {
self.sender.clone().send(request_stream).await.context("failed to send request stream")
}
}
#[test_case("fuchsia-pkg://fuchsia.com/fuchsia-component-tests#meta/realm_with_wait.cm"; "wait")]
#[test_case("fuchsia-pkg://fuchsia.com/fuchsia-component-tests#meta/realm.cm"; "no_wait")]
#[fasync::run_singlethreaded(test)]
async fn scoped_instances(root_component: &'static str) -> Result<(), Error> {
syslog::init_with_tags(&["fuchsia_component_v2_test"]).expect("could not initialize logging");
let test = OpaqueTest::default(root_component).await?;
let mut event_source = test.connect_to_event_source().await?;
let event = EventMatcher::ok().r#type(Destroyed::TYPE).moniker("./coll:auto-*".to_string());
let mut expected_events: Vec<_> = (0..3).map(|_| event.clone()).collect();
expected_events
.push(EventMatcher::ok().r#type(Destroyed::TYPE).moniker("./coll:static_name".to_string()));
let expectation = EventSequence::new()
.all_of(expected_events, Ordering::Unordered)
.subscribe_and_expect(&mut event_source)
.await?;
let (sender, mut receiver) = futures::channel::mpsc::channel(1);
let injector = Arc::new(PassthroughInjector { sender });
let () = injector.inject(&event_source, EventMatcher::ok()).await;
let () = event_source.start_component_tree().await;
// The realm component will connect to our injected capability once it's done with its work.
// Wait for that to happen before matching on event expectations.
info!("Waiting for test component to signal ready");
let mut request_stream =
receiver.next().await.context("failed to observe capability request")?;
info!("Waiting for scoped instances to be destroyed");
let () = expectation.await?;
drop(test);
// Prove connection to the component under test is severed after dropping everything.
match request_stream.next().await {
Some(r) => panic!("unexpected item from request stream: {:?}", r),
None => (),
}
Ok(())
}