rtest 0.2.2

integration test building framework
Documentation
use super::ExecutionStrategy;
use crate::{
    context::ResourceId,
    runner::{result_map::ExecutionResultMap, test_repo::TestRepo, Runner},
};

#[derive(Default)]
pub struct SimpleStrategy {}

impl ExecutionStrategy for SimpleStrategy {
    fn run(&self, repo: &mut TestRepo, _: &[ResourceId]) -> ExecutionResultMap {
        let mut result_map = ExecutionResultMap::default();
        for _ in 0..50 {
            let (mut ok, mut missing) = (true, Vec::new());
            while ok {
                (ok, missing) = Self::run_all_possible(repo, &mut result_map)
            }
            missing.dedup();
            for m in missing {
                if Self::recreate_resource(repo, &mut result_map, m) {
                    break;
                }
            }
        }
        result_map
    }
}

impl SimpleStrategy {
    /// will run all testcases that work without any modifications
    /// returns if some progress was done
    fn run_all_possible(repo: &mut TestRepo, results: &mut ExecutionResultMap) -> (bool, Vec<ResourceId>) {
        let mut at_least_once = false;
        let mut at_least_one_finished = false;
        let mut missing = Vec::new();
        let params = repo.runner_params();
        for tc in repo.cases_mut().values_mut() {
            if results.did_execute(tc.test_id()) {
                at_least_one_finished = true;
                continue;
            }
            match Runner::exec_testcase(tc, &params) {
                Ok(res) => {
                    results.record(tc.test_id(), res);
                    at_least_once = true;
                },
                Err(m) => missing.push(m),
            }
        }
        (at_least_once && at_least_one_finished, missing)
    }

    /// try to recreate a resource
    fn recreate_resource(repo: &mut TestRepo, results: &mut ExecutionResultMap, wanted: ResourceId) -> bool {
        let params = repo.runner_params();
        for tc in repo.cases_mut().values_mut() {
            if results.did_execute(tc.test_id()) && tc.info.output_resources.contains(&wanted) {
                if let Ok(res) = Runner::exec_testcase(tc, &params) {
                    results.record(tc.test_id(), res);
                    return true;
                }
            }
        }
        false
    }
}