blob: c5f86c5ea14f407480d6e35f477aa64a924154d4 [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::Error,
async_trait::async_trait,
fidl_fidl_test_components as test_protocol, fuchsia_async as fasync,
fuchsia_component::client::ScopedInstance,
fuchsia_syslog::{self as fxlog, fx_log_info},
futures_util::stream::TryStreamExt,
std::sync::{Arc, Mutex},
test_utils_lib::{
events::{self as events, Event, EventMode, EventSource, EventSubscription},
injectors::*,
matcher::EventMatcher,
sequence::EventSequence,
},
};
#[fasync::run_singlethreaded(test)]
async fn test_exit_detection() {
fxlog::init().unwrap();
let event_source = EventSource::new_sync().unwrap();
let event_stream = event_source
.subscribe(vec![EventSubscription::new(vec![events::Stopped::NAME], EventMode::Sync)])
.await
.unwrap();
event_source.start_component_tree().await;
let collection_name = String::from("test-collection");
let instance = ScopedInstance::new(
collection_name.clone(),
String::from(
"fuchsia-pkg://fuchsia.com/elf_runner_lifecycle_test#meta/immediate_exit_component.cm",
),
)
.await
.unwrap();
let target_moniker = format!("./{}:{}:*", collection_name, instance.child_name());
EventSequence::new()
.then(EventMatcher::ok().r#type(events::Stopped::TYPE).moniker(&target_moniker))
.expect(event_stream)
.await
.unwrap();
}
#[fasync::run_singlethreaded(test)]
async fn test_exit_after_rendezvous() {
fxlog::init().unwrap();
// Get the event source, install our service injector, and then start the
// component tree.
let event_source = EventSource::new_sync().unwrap();
let rendezvous_service = Arc::new(RendezvousService { call_count: Mutex::new(0) });
rendezvous_service.inject(&event_source, EventMatcher::ok()).await;
let event_stream = event_source
.subscribe(vec![EventSubscription::new(vec![events::Stopped::NAME], EventMode::Sync)])
.await
.unwrap();
event_source.start_component_tree().await;
// Launch the component under test.
let collection_name = String::from("test-collection");
let instance = ScopedInstance::new(
collection_name.clone(),
String::from(
"fuchsia-pkg://fuchsia.com/elf_runner_lifecycle_test#meta/rendezvous_exit_component.cm",
),
)
.await
.unwrap();
// Wait to get confirmation that the component under test exited.
let target_moniker = format!("./{}:{}:*", collection_name, instance.child_name());
EventSequence::new()
.then(EventMatcher::ok().r#type(events::Stopped::TYPE).moniker(&target_moniker))
.expect(event_stream)
.await
.unwrap();
// Check that we received a request from the component under test.
assert_eq!(*rendezvous_service.call_count.lock().unwrap(), 1);
}
struct RendezvousService {
call_count: Mutex<u32>,
}
#[async_trait]
impl ProtocolInjector for RendezvousService {
type Marker = test_protocol::TriggerMarker;
async fn serve(
self: Arc<Self>,
mut stream: test_protocol::TriggerRequestStream,
) -> Result<(), Error> {
while let Some(request) = stream.try_next().await.unwrap() {
match request {
test_protocol::TriggerRequest::Run { responder } => {
{
let mut count = self.call_count.lock().unwrap();
*count += 1;
}
fx_log_info!("Received rendezvous from target");
responder.send("").unwrap();
}
}
}
Ok(())
}
}