blob: 5137f19bdb26ee976458afff6ea0dad2260d7216 [file] [log] [blame]
// Copyright 2022 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 _, Error},
fidl_fuchsia_test_manager as ftest_manager,
fidl_fuchsia_test_manager::RunOptions,
ftest_manager::{CaseStatus, SuiteStatus},
fuchsia_async as fasync,
maplit::hashset,
pretty_assertions::assert_eq,
std::collections::{HashMap, HashSet},
test_manager_test_lib::{GroupRunEventByTestCase, GroupedRunEvents, RunEvent},
};
/*
The only difference between inputs to gunit and gtest framework are the name of the flags.
The output format from both frameworks is same. So we will just test that we can launch a
simulated gunit test and get correct output. Exhaustive testing can be found at
//src/sys/test_runners/gtest/tests.
*/
pub async fn run_test(
test_url: &str,
run_options: RunOptions,
) -> Result<(Vec<RunEvent>, Vec<String>), Error> {
let run_builder = test_runners_test_lib::connect_to_test_manager().await?;
let builder = test_manager_test_lib::TestBuilder::new(run_builder);
let suite_instance =
builder.add_suite(test_url, run_options).await.context("Cannot create suite instance")?;
let builder_run = fasync::Task::spawn(async move { builder.run().await });
let ret = test_runners_test_lib::process_events(suite_instance, false).await;
builder_run.await.context("builder execution failed")?;
ret.map(|(mut events, logs)| {
let () = events.retain(|event| match event {
RunEvent::CaseStdout { name: _, stdout_message } => {
// gunit produces this line when tests are randomized. As of
// this writing, our gunit_main binary *always* randomizes.
!stdout_message.contains("Note: Randomizing tests' orders with a seed of")
}
_ => true,
});
(events, logs)
})
}
/// Helper for comparing grouped test events. Produces more readable diffs than diffing the entire
/// two maps.
pub fn assert_events_eq(
a: &HashMap<Option<String>, GroupedRunEvents>,
b: &HashMap<Option<String>, GroupedRunEvents>,
) {
let a_keys: HashSet<Option<String>> = b.keys().cloned().collect();
let b_keys: HashSet<Option<String>> = a.keys().cloned().collect();
assert_eq!(a_keys, b_keys);
for key in b.keys() {
assert_eq!(b.get(key).unwrap(), a.get(key).unwrap())
}
}
fn default_options() -> ftest_manager::RunOptions {
ftest_manager::RunOptions {
run_disabled_tests: Some(false),
parallel: Some(10),
arguments: None,
timeout: None,
case_filters_to_run: None,
log_iterator: None,
..Default::default()
}
}
#[fuchsia_async::run_singlethreaded(test)]
async fn launch_and_run_sample_test() {
let test_url = "fuchsia-pkg://fuchsia.com/gunit-runner-example-tests#meta/sample_tests.cm";
let (events, _logs) = run_test(test_url, default_options()).await.unwrap();
let events = events.into_iter().group_by_test_case_unordered();
let expected_events = include!("../../gtest/test_data/sample_tests_golden_events.rsf")
.into_iter()
.group_by_test_case_unordered();
assert_events_eq(&events, &expected_events);
}
#[fuchsia_async::run_singlethreaded(test)]
async fn launch_and_run_test_with_custom_args() {
let test_url =
"fuchsia-pkg://fuchsia.com/gunit-runner-example-tests#meta/test_with_custom_args.cm";
let mut run_options = default_options();
run_options.arguments = Some(vec!["--my_custom_arg2".to_owned()]);
let (events, _logs) = run_test(test_url, run_options).await.unwrap();
let expected_events = vec![
RunEvent::suite_started(),
RunEvent::case_found("TestArg.TestArg"),
RunEvent::case_started("TestArg.TestArg"),
RunEvent::case_stopped("TestArg.TestArg", CaseStatus::Passed),
RunEvent::case_finished("TestArg.TestArg"),
RunEvent::suite_stopped(SuiteStatus::Passed),
];
assert_eq!(expected_events, events);
}
#[fuchsia_async::run_singlethreaded(test)]
async fn launch_and_run_test_with_environ() {
let test_url = "fuchsia-pkg://fuchsia.com/gunit-runner-example-tests#meta/test_with_environ.cm";
let (events, _logs) = run_test(test_url, default_options()).await.unwrap();
let expected_events = vec![
RunEvent::suite_started(),
RunEvent::case_found("TestEnviron.TestEnviron"),
RunEvent::case_started("TestEnviron.TestEnviron"),
RunEvent::case_stopped("TestEnviron.TestEnviron", CaseStatus::Passed),
RunEvent::case_finished("TestEnviron.TestEnviron"),
RunEvent::suite_stopped(SuiteStatus::Passed),
];
assert_eq!(expected_events, events);
}
#[fuchsia_async::run_singlethreaded(test)]
async fn launch_and_run_sample_test_include_disabled() {
const TEST_URL: &str =
"fuchsia-pkg://fuchsia.com/gunit-runner-example-tests#meta/sample_tests.cm";
let mut run_options = default_options();
run_options.run_disabled_tests = Some(true);
let (events, _logs) = run_test(TEST_URL, run_options).await.unwrap();
let events = events.into_iter().group_by_test_case_unordered();
let expected_pass_events = vec![
RunEvent::case_found("SampleDisabled.DISABLED_TestPass"),
RunEvent::case_started("SampleDisabled.DISABLED_TestPass"),
RunEvent::case_stopped("SampleDisabled.DISABLED_TestPass", CaseStatus::Passed),
RunEvent::case_finished("SampleDisabled.DISABLED_TestPass"),
]
.into_iter()
.group();
let expected_fail_events = hashset![
RunEvent::case_found("SampleDisabled.DISABLED_TestFail"),
RunEvent::case_started("SampleDisabled.DISABLED_TestFail"),
RunEvent::case_stopped("SampleDisabled.DISABLED_TestFail", CaseStatus::Failed),
RunEvent::case_finished("SampleDisabled.DISABLED_TestFail"),
];
let expected_skip_events = vec![
RunEvent::case_found("SampleDisabled.DynamicSkip"),
RunEvent::case_started("SampleDisabled.DynamicSkip"),
RunEvent::case_stdout(
"SampleDisabled.DynamicSkip",
"../../src/sys/test_runners/gtest/test_data/sample_tests.cc:25: Skipped",
),
RunEvent::case_stdout("SampleDisabled.DynamicSkip", ""),
RunEvent::case_stdout("SampleDisabled.DynamicSkip", ""),
// gunit does not force run test skipped with `GTEST_SKIP()`
// https://github.com/google/googletest/issues/3831
RunEvent::case_stopped("SampleDisabled.DynamicSkip", CaseStatus::Skipped),
RunEvent::case_finished("SampleDisabled.DynamicSkip"),
]
.into_iter()
.group();
let actual_pass_events =
events.get(&Some("SampleDisabled.DISABLED_TestPass".to_string())).unwrap();
assert_eq!(actual_pass_events, &expected_pass_events);
// Not going to check all of the exact log events.
let actual_fail_events = HashSet::from_iter(
events
.get(&Some("SampleDisabled.DISABLED_TestFail".to_string()))
.unwrap()
.non_artifact_events
.clone(),
);
assert!(
actual_fail_events.is_superset(&expected_fail_events),
"actual_fail_events: {:?}",
&actual_fail_events
);
let actual_skip_events = events.get(&Some("SampleDisabled.DynamicSkip".to_string())).unwrap();
assert_eq!(actual_skip_events, &expected_skip_events);
}
#[fuchsia_async::run_singlethreaded(test)]
async fn launch_and_run_empty_test() {
let test_url = "fuchsia-pkg://fuchsia.com/gunit-runner-example-tests#meta/empty_test.cm";
let (events, _logs) = run_test(test_url, default_options()).await.unwrap();
let expected_events =
vec![RunEvent::suite_started(), RunEvent::suite_stopped(SuiteStatus::Passed)];
assert_eq!(expected_events, events);
}