blob: 2d3e82394502f6c039567eda36246c6b1de2a5be [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 {
argh::{EarlyExit, FromArgs},
fidl_fuchsia_test_manager::HarnessMarker,
};
#[derive(FromArgs, Default, PartialEq, Eq, Debug)]
// TODO(61417): use argh for test_args when the feature is implemented and rolled.
/// Arguments. Use option delimiter(--) to pass arguments to the test suite.
struct Args {
/// test timeout. Exits with -`ZX_ERR_TIMED_OUT` if the test times out.
#[argh(option, short = 't')]
timeout: Option<u32>,
/// test url. Test should implement `fuchsia.test.Suite` protocol.
#[argh(positional)]
test_url: String,
/// test filter. A glob pattern for matching tests.
#[argh(option)]
test_filter: Option<String>,
/// whether to also run tests that have been marked disabled/ignored by the test author.
#[argh(switch)]
also_run_disabled_tests: bool,
/// run test cases in parallel, up to the number provided.
#[argh(option)]
parallel: Option<u16>,
}
// parses args, returns `Args` and everything after '--'.
fn parse_args(cmd: Vec<String>) -> Result<(Args, Option<Vec<String>>), EarlyExit> {
let mut splits = cmd.splitn(2, |s| s == "--");
let s: Vec<&str> = splits.next().unwrap().iter().map(|s| s.as_str()).collect();
let args = Args::from_args(&[s[0]], &s[1..])?;
let rest = splits.next().map(|v| v.to_vec());
Ok((args, rest))
}
#[fuchsia_async::run_singlethreaded]
async fn main() {
let (args, test_args) = parse_args(std::env::args().collect()).unwrap_or_else(|early_exit| {
println!("{}", early_exit.output);
std::process::exit(match early_exit.status {
Ok(()) => 0,
Err(()) => 1,
})
});
let Args { timeout, test_url, test_filter, also_run_disabled_tests, parallel } = args;
let harness = fuchsia_component::client::connect_to_service::<HarnessMarker>()
.expect("connecting to HarnessProxy");
match run_test_suite_lib::run_tests_and_get_outcome(run_test_suite_lib::TestParams {
test_url,
timeout: timeout.and_then(std::num::NonZeroU32::new),
test_filter,
also_run_disabled_tests,
parallel,
test_args: test_args,
harness,
})
.await
{
run_test_suite_lib::Outcome::Passed => {}
run_test_suite_lib::Outcome::Timedout => {
std::process::exit(-fuchsia_zircon::Status::TIMED_OUT.into_raw());
}
run_test_suite_lib::Outcome::Failed
| run_test_suite_lib::Outcome::Inconclusive
| run_test_suite_lib::Outcome::Error => {
std::process::exit(1);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn args_vec(mut args: Vec<&str>) -> Vec<String> {
let mut a = vec!["test_program"];
a.append(&mut args);
a.iter().map(|s| s.to_string()).collect()
}
#[test]
// As we have custom parsing when user passes "--", making sure everything works fine.
fn test_parse_args() {
let url = "foo.cm";
let mut expected_args = Args { test_url: url.to_string(), ..Default::default() };
expected_args.test_url = url.to_string();
let (args, test_args) = parse_args(args_vec(vec![url])).unwrap();
assert_eq!(args, expected_args);
assert_eq!(test_args, None);
let (args, test_args) = parse_args(args_vec(vec![url, "--"])).unwrap();
assert_eq!(args, expected_args);
assert_eq!(test_args, Some(vec![]));
// make sure we can parse --help flag when user passes "--"
let err = parse_args(args_vec(vec![url, "--help", "--"])).unwrap_err();
assert_eq!(err.status, Ok(()));
// make sure we can parse --help flag without "--"
let err = parse_args(args_vec(vec![url, "--help"])).unwrap_err();
assert_eq!(err.status, Ok(()));
// make sure we can catch arg errors when user passes "--"
let err = parse_args(args_vec(vec![url, "--timeout", "a", "--"])).unwrap_err();
assert_eq!(err.status, Err(()));
// make sure we can catch arg errors without "--"
let err = parse_args(args_vec(vec![url, "--timeout", "a"])).unwrap_err();
assert_eq!(err.status, Err(()));
// make sure we can parse args when user passes "--"
let (args, test_args) = parse_args(args_vec(vec![url, "--timeout", "2", "--"])).unwrap();
expected_args.timeout = Some(2);
assert_eq!(args, expected_args);
assert_eq!(test_args, Some(vec![]));
// make sure we can parse args without "--"
let (args, test_args) = parse_args(args_vec(vec![url, "--timeout", "2"])).unwrap();
assert_eq!(args, expected_args);
assert_eq!(test_args, None);
// make sure we can parse args after "--"
let (args, test_args) = parse_args(args_vec(vec![
url,
"--timeout",
"2",
"--",
"--arg1",
"some_random_str",
"-arg2",
]))
.unwrap();
assert_eq!(args, expected_args);
assert_eq!(
test_args,
Some(vec!["--arg1".to_owned(), "some_random_str".to_owned(), "-arg2".to_owned()])
);
// parse_args works with multiple "--"
let (args, test_args) = parse_args(args_vec(vec![
url,
"--timeout",
"2",
"--",
"--",
"--arg1",
"some_random_str",
"--",
"-arg2",
]))
.unwrap();
assert_eq!(args, expected_args);
assert_eq!(
test_args,
Some(vec![
"--".to_owned(),
"--arg1".to_owned(),
"some_random_str".to_owned(),
"--".to_owned(),
"-arg2".to_owned()
])
);
}
}