blob: 3510dfe7283d0b1b78312756ec4f021697ff081c [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.
use {
anyhow::Context as _,
fidl::endpoints,
fidl_fuchsia_io::DirectoryMarker,
fidl_fuchsia_sys2 as fsys, fuchsia_async as fasync,
fuchsia_component::client::connect_to_service,
futures::prelude::*,
hub_report::HubReport,
test_utils_lib::{events::*, matcher::EventMatcher},
};
#[fasync::run_singlethreaded]
async fn main() {
let event_source = EventSource::new_sync().unwrap();
// Subscribe to relevant events
let mut event_stream = event_source
.subscribe(vec![Stopped::NAME, MarkedForDestruction::NAME, Destroyed::NAME])
.await
.unwrap();
// Creating children will not complete until `start_component_tree` is called.
event_source.start_component_tree().await;
// Create a dynamic child component
let realm =
connect_to_service::<fsys::RealmMarker>().context("error connecting to realm").unwrap();
let mut collection_ref = fsys::CollectionRef { name: String::from("coll") };
let child_decl = fsys::ChildDecl {
name: Some(String::from("simple_instance")),
url: Some(String::from("fuchsia-pkg://fuchsia.com/hub_integration_test#meta/simple.cm")),
startup: Some(fsys::StartupMode::Lazy),
environment: None,
..fsys::ChildDecl::EMPTY
};
realm
.create_child(&mut collection_ref, child_decl)
.await
.context("create_child failed")
.unwrap()
.expect("failed to create child");
let hub_report = HubReport::new().unwrap();
// Read the children of this component and pass the results to the integration test
// via HubReport.
hub_report.report_directory_contents("/hub/children").await.unwrap();
// Read the hub of the dynamic child and pass the results to the integration test
// via HubReport
hub_report.report_directory_contents("/hub/children/coll:simple_instance").await.unwrap();
// Read the instance id of the dynamic child and pass the results to the integration test
// via HubReport
hub_report.report_file_content("/hub/children/coll:simple_instance/id").await.unwrap();
// Read the children of the dynamic child and pass the results to the integration test
// via HubReport
hub_report
.report_directory_contents("/hub/children/coll:simple_instance/children")
.await
.unwrap();
// Bind to the dynamic child
let mut child_ref = fsys::ChildRef {
name: "simple_instance".to_string(),
collection: Some("coll".to_string()),
};
let (_dir_proxy, server_end) = endpoints::create_proxy::<DirectoryMarker>().unwrap();
realm.bind_child(&mut child_ref, server_end).await.unwrap().expect("failed to bind to child");
// Read the hub of the dynamic child and pass the results to the integration test
// via HubReport
hub_report.report_directory_contents("/hub/children/coll:simple_instance").await.unwrap();
// Read the children of the dynamic child and pass the results to the integration test
// via HubReport
hub_report
.report_directory_contents("/hub/children/coll:simple_instance/children")
.await
.unwrap();
// Read the instance id of the dynamic child's static child and pass the results to the
// integration test via HubReport
hub_report
.report_file_content("/hub/children/coll:simple_instance/children/child/id")
.await
.unwrap();
// Delete the dynamic child
let mut child_ref = fsys::ChildRef {
name: "simple_instance".to_string(),
collection: Some("coll".to_string()),
};
let (f, destroy_handle) = realm.destroy_child(&mut child_ref).remote_handle();
fasync::Task::spawn(f).detach();
// Wait for the dynamic child to begin deletion
let event = EventMatcher::ok()
.moniker("./coll:simple_instance:1")
.expect_match::<MarkedForDestruction>(&mut event_stream)
.await;
hub_report.report_directory_contents("/hub/children").await.unwrap();
hub_report.report_directory_contents("/hub/deleting").await.unwrap();
hub_report.report_directory_contents("/hub/deleting/coll:simple_instance:1").await.unwrap();
event.resume().await.unwrap();
// Wait for the destroy call to return
destroy_handle.await.context("delete_child failed").unwrap().expect("failed to delete child");
// Wait for the dynamic child to stop
let event = EventMatcher::ok()
.moniker("./coll:simple_instance:1")
.expect_match::<Stopped>(&mut event_stream)
.await;
hub_report.report_directory_contents("/hub/deleting/coll:simple_instance:1").await.unwrap();
event.resume().await.unwrap();
// Wait for the dynamic child's static child to begin deletion
let event = EventMatcher::ok()
.moniker("./coll:simple_instance:1/child:0")
.expect_match::<MarkedForDestruction>(&mut event_stream)
.await;
hub_report
.report_directory_contents("/hub/deleting/coll:simple_instance:1/children")
.await
.unwrap();
hub_report
.report_directory_contents("/hub/deleting/coll:simple_instance:1/deleting")
.await
.unwrap();
hub_report
.report_directory_contents("/hub/deleting/coll:simple_instance:1/deleting/child:0")
.await
.unwrap();
event.resume().await.unwrap();
// Wait for the dynamic child's static child to be destroyed
let event = EventMatcher::ok()
.moniker("./coll:simple_instance:1/child:0")
.expect_match::<Destroyed>(&mut event_stream)
.await;
hub_report
.report_directory_contents("/hub/deleting/coll:simple_instance:1/deleting")
.await
.unwrap();
event.resume().await.unwrap();
// Wait for the dynamic child to be destroyed
let event = EventMatcher::ok()
.moniker("./coll:simple_instance:1")
.expect_match::<Destroyed>(&mut event_stream)
.await;
hub_report.report_directory_contents("/hub/deleting").await.unwrap();
event.resume().await.unwrap();
}