| // 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, |
| cm_stress_tests_lib::{create_child, stop_child, Child}, |
| fidl::endpoints::RequestStream, |
| fidl_test_componentmanager_stresstests as fstresstests, fuchsia_async as fasync, |
| fuchsia_component::server::ServiceFs, |
| futures::prelude::*, |
| std::sync::{Arc, Mutex}, |
| }; |
| |
| #[fuchsia::main(logging_tags = ["child_for_stress_test"])] |
| async fn main() -> Result<(), Error> { |
| const URL: &str = |
| "fuchsia-pkg://fuchsia.com/component-manager-stress-tests#meta/child-for-stress-test.cm"; |
| const COL: &str = "children"; |
| tracing::debug!("started"); |
| let mut fs = ServiceFs::new_local(); |
| let children_vec = Arc::new(Mutex::new(vec![])); |
| fs.dir("svc").add_fidl_service(move |mut stream: fstresstests::ChildRealmRequestStream| { |
| let children_vec = children_vec.clone(); |
| fasync::Task::local(async move { |
| stream.control_handle().send_on_connected().unwrap(); |
| while let Some(event) = stream.try_next().await.expect("Cannot read request stream") { |
| match event { |
| fstresstests::ChildRealmRequest::Stop { .. } => { |
| std::process::exit(0); |
| } |
| fstresstests::ChildRealmRequest::CreateChildren { |
| direct_children, |
| tree_height, |
| responder, |
| } => { |
| let stream = stream::iter(0..direct_children); |
| let mut children: Vec<Child> = stream |
| .then(|_| async { create_child(COL, URL).await.unwrap() }) |
| .collect() |
| .await; |
| stream::iter(&children) |
| .for_each_concurrent(None, |child| async move { |
| if tree_height > 1 { |
| child |
| .realm |
| .create_children(direct_children, tree_height - 1) |
| .await |
| .unwrap(); |
| } |
| match child |
| .realm |
| .take_event_stream() |
| .try_next() |
| .await |
| .unwrap() |
| .unwrap() |
| { |
| fstresstests::ChildRealmEvent::OnConnected {} => {} |
| } |
| }) |
| .await; |
| children_vec.lock().unwrap().append(&mut children); |
| responder.send().unwrap(); |
| } |
| fstresstests::ChildRealmRequest::StopChildren { responder } => { |
| // TODO: this variable triggered the `must_not_suspend` lint and may be held across an await |
| // If this is the case, it is an error. See fxbug.dev/87757 for more details |
| let mut children_vec = children_vec.lock().unwrap(); |
| let mut children = vec![]; |
| children.append(&mut children_vec); |
| |
| stream::iter(children) |
| .for_each_concurrent(None, |child| async { |
| child |
| .realm |
| .stop_children() |
| .await |
| .expect("Error calling stop_children"); |
| stop_child(child).await.unwrap(); |
| }) |
| .await; |
| responder.send().unwrap(); |
| } |
| } |
| } |
| }) |
| }); |
| fs.take_and_serve_directory_handle()?; |
| fs.for_each_concurrent(None, |t| async { |
| t.await; |
| }) |
| .await; |
| Ok(()) |
| } |