test_runners_elf_lib/
runner.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use fuchsia_component::server::ServiceFs;
6use futures::prelude::*;
7use log::{info, warn};
8use test_runners_lib::elf;
9use test_runners_lib::elf::SuiteServer;
10use test_runners_lib::errors::*;
11use thiserror::Error;
12use {fidl_fuchsia_component_runner as fcrunner, fuchsia_async as fasync};
13
14pub fn add_runner_service<F, U, S>(
15    get_test_server: F,
16    validate_args: U,
17) -> Result<(), anyhow::Error>
18where
19    F: 'static + Fn() -> S + Send + Copy,
20    U: 'static + Fn(&Vec<String>) -> Result<(), ArgumentError> + Copy,
21    S: SuiteServer,
22{
23    info!("started");
24    let mut executor = fasync::LocalExecutor::new();
25    fuchsia_trace_provider::trace_provider_create_with_fdio();
26    fuchsia_trace_provider::trace_provider_wait_for_init();
27
28    let mut fs = ServiceFs::new_local();
29    fs.dir("svc").add_fidl_service(move |stream| {
30        fasync::Task::local(async move {
31            start_runner(stream, get_test_server, validate_args)
32                .await
33                .expect("failed to start runner.")
34        })
35        .detach();
36    });
37    fs.take_and_serve_directory_handle()?;
38    executor.run_singlethreaded(fs.collect::<()>());
39    Ok(())
40}
41
42/// Error encountered by runner.
43#[derive(Debug, Error)]
44pub enum RunnerError {
45    #[error("Cannot read request: {:?}", _0)]
46    RequestRead(fidl::Error),
47}
48
49async fn start_runner<F, U, S>(
50    mut stream: fcrunner::ComponentRunnerRequestStream,
51    get_test_server: F,
52    validate_args: U,
53) -> Result<(), RunnerError>
54where
55    F: 'static + Fn() -> S + Send + Copy,
56    U: 'static + Fn(&Vec<String>) -> Result<(), ArgumentError> + Copy,
57    S: SuiteServer,
58{
59    while let Some(event) = stream.try_next().await.map_err(RunnerError::RequestRead)? {
60        match event {
61            fcrunner::ComponentRunnerRequest::Start { start_info, controller, .. } => {
62                let url = start_info.resolved_url.clone().unwrap_or_else(|| "".to_owned());
63                if let Err(e) =
64                    elf::start_component(start_info, controller, get_test_server, validate_args)
65                        .await
66                {
67                    warn!("Cannot start component '{}': {:?}", url, e)
68                };
69            }
70            fcrunner::ComponentRunnerRequest::_UnknownMethod { ordinal, .. } => {
71                warn!(ordinal:%; "Unknown ComponentRunner request");
72            }
73        }
74    }
75    Ok(())
76}