fn main()

in tools/testinfra/runner/src/main.rs [56:143]


fn main() -> Result<()> {
    // parse command line
    let options = Options::from_args();
    if options.ignored.len() > 0 {
        eprintln!(
            "Warning: Unimplemented options were ignored: {:?}\n",
            options.ignored
        );
    }

    // validate and collect tests which are not auto-excluded
    let tests: Vec<Test> = buck_test::read(&options.spec)?
        .into_iter()
        .map(|spec| buck_test::validate(spec).unwrap())
        .flatten()
        .collect();

    // don't run anything when just listing
    if options.list {
        for test in tests {
            println!("{}", test.name);
        }
        exit(0);
    }

    // run tests in parallel (retries share the same thread)
    let total = tests.len();
    eprintln!("Running {} tests...", total);
    let _ = rayon::ThreadPoolBuilder::new()
        .num_threads(options.threads)
        .build_global();
    let mut tests: Vec<TestResult> = tests
        .into_par_iter()
        .map(|test| {
            let test = test.run(options.retries);
            if test.passed {
                print!("[OK] {} ({} ms)", test.name, test.duration.as_millis());
                if test.attempts > 1 {
                    print!(" ({} attempts needed)\n", test.attempts);
                } else {
                    print!("\n");
                }
            } else {
                println!("[FAIL] {} ({} ms)", test.name, test.duration.as_millis());
            }
            return test;
        })
        .collect();

    // collect and print results
    let mut passed = 0;
    let mut errors: Vec<String> = Vec::new();
    for test in tests.iter_mut() {
        if test.passed {
            passed += 1;
        } else {
            let mut message = format!(
                "\nTest {} failed after {} unsuccessful attempts:\n",
                test.name, test.attempts
            );
            for line in test.stderr.split("\n") {
                let line = format!("    {}\n", line);
                message.push_str(&line);
            }
            if test.contacts.len() > 0 {
                let contacts = format!("Please report this to {:?}\n", test.contacts);
                message.push_str(&contacts);
            }
            errors.push(message);
        }
    }
    for error in errors {
        eprintln!("{}", error);
    }
    let failed = total - passed;
    println!(
        "Out of {} tests, {} passed, {} failed",
        total, passed, failed
    );

    // generate test report
    match options.report {
        None => {}
        Some(path) => report(tests, path)?,
    }

    exit(failed as i32);
}