blob: 9d11d08938c2849c30164bac61381aedaf20af22 [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 {
super::{
data::Data,
puppet, results,
trials::{self, Step},
validate, DiffType,
},
failure::{bail, Error},
};
pub async fn run_all_trials(url: &str, results: &mut results::Results) {
let mut trial_set = trials::real_trials();
for trial in trial_set.iter_mut() {
match puppet::Puppet::connect(url).await {
Ok(mut puppet) => {
let mut data = Data::new();
if let Err(e) = run_trial(&mut puppet, &mut data, trial, results).await {
results.error(format!("Running trial {}, got failure:\n{}", trial.name, e));
} else {
results.log(format!("Trial {} succeeds", trial.name));
}
}
Err(e) => {
results.error(format!(
"Failed to form Puppet - error {:?} - URL may be invalid: {}.",
e, url
));
}
}
}
}
async fn run_trial(
puppet: &mut puppet::Puppet,
data: &mut Data,
trial: &mut trials::Trial,
results: &mut results::Results,
) -> Result<(), Error> {
let trial_name = format!("{}:{}", puppet.name(), trial.name);
try_compare(data, puppet, &trial_name, -1, None, -1, results.diff_type)?;
for (step_index, step) in trial.steps.iter_mut().enumerate() {
let mut actions = match step {
Step::Actions(actions) => actions,
Step::WithMetrics(actions, _) => actions,
};
run_actions(&mut actions, data, puppet, &trial.name, step_index, results).await?;
match step {
Step::WithMetrics(_, step_name) => {
results.remember_metrics(puppet.metrics()?, &trial.name, step_index, step_name)
}
_ => {}
}
}
Ok(())
}
async fn run_actions(
actions: &mut Vec<validate::Action>,
data: &mut Data,
puppet: &mut puppet::Puppet,
trial_name: &str,
step_index: usize,
results: &mut results::Results,
) -> Result<(), Error> {
for (action_number, action) in actions.iter_mut().enumerate() {
if let Err(e) = data.apply(action) {
bail!(
"Local-apply error in trial {}, step {}, action {}: {:?} ",
trial_name,
step_index,
action_number,
e
);
}
match puppet.apply(action).await {
Err(e) => {
bail!(
"Puppet-apply error in trial {}, step {}, action {}: {:?} ",
trial_name,
step_index,
action_number,
e
);
}
Ok(validate::TestResult::Ok) => {}
Ok(validate::TestResult::Unimplemented) => {
results.unimplemented(puppet.name(), action);
return Ok(());
}
Ok(bad_result) => {
bail!(
"In trial {}, puppet {} reported action {:?} was {:?}",
trial_name,
puppet.name(),
action,
bad_result
);
}
}
try_compare(
data,
puppet,
&trial_name,
step_index as i32,
Some(action),
action_number as i32,
results.diff_type,
)?;
}
Ok(())
}
fn try_compare(
data: &Data,
puppet: &puppet::Puppet,
trial_name: &str,
step_index: i32,
action: Option<&validate::Action>,
action_number: i32,
diff_type: DiffType,
) -> Result<(), Error> {
match puppet.read_data() {
Err(e) => {
bail!(
"Puppet-read error in trial {}, step {}, action {} {:?}: {:?} ",
trial_name,
step_index,
action_number,
action,
e
);
}
Ok(puppet_data) => {
if let Err(e) = data.compare(&puppet_data, diff_type) {
bail!(
"Compare error in trial {}, step {}, action {}:\n{:?}:\n{} ",
trial_name,
step_index,
action_number,
action,
e
);
}
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use {
super::*, crate::trials::tests::trial_with_action, crate::*, fidl_test_inspect_validate::*,
fuchsia_async as fasync,
};
#[fasync::run_singlethreaded(test)]
async fn unimplemented_works() -> Result<(), Error> {
let mut int_maker = trial_with_action(
"foo",
create_numeric_property!(
parent: ROOT_ID, id: 1, name: "int", value: Number::IntT(0)),
);
let mut uint_maker = trial_with_action(
"foo",
create_numeric_property!(
parent: ROOT_ID, id: 2, name: "uint", value: Number::UintT(0)),
);
let mut results = results::Results::new();
let mut puppet = puppet::tests::local_incomplete_puppet().await?;
let mut data = Data::new();
// results contains a list of the _un_implemented actions. local_incomplete_puppet()
// implements Int creation, but not Uint. So results should not include Int but should
// include Uint.
run_trial(&mut puppet, &mut data, &mut int_maker, &mut results).await?;
run_trial(&mut puppet, &mut data, &mut uint_maker, &mut results).await?;
assert!(!results.to_json().contains(&format!("{}: CreateProperty(Int)", puppet.name())));
assert!(results.to_json().contains(&format!("{}: CreateProperty(Uint)", puppet.name())));
Ok(())
}
}