//! Module providing interface for running tests in the console.
use std::fs::File;
-use std::io::prelude::Write;
use std::io;
-
-use term;
+use std::io::prelude::Write;
+use std::time::Instant;
use super::{
bench::fmt_bench_samples,
cli::TestOpts,
- event::{TestEvent, CompletedTest},
+ event::{CompletedTest, TestEvent},
+ filter_tests,
formatters::{JsonFormatter, OutputFormatter, PrettyFormatter, TerseFormatter},
- helpers::{
- concurrency::get_concurrency,
- metrics::MetricMap,
- },
- types::{TestDesc, TestDescAndFn, NamePadding},
+ helpers::{concurrency::get_concurrency, metrics::MetricMap},
options::{Options, OutputFormat},
- test_result::TestResult,
- time::TestExecTime,
run_tests,
- filter_tests,
+ test_result::TestResult,
+ time::{TestExecTime, TestSuiteExecTime},
+ types::{NamePadding, TestDesc, TestDescAndFn},
};
/// Generic wrapper over stdout.
pub allowed_fail: usize,
pub filtered_out: usize,
pub measured: usize,
+ pub exec_time: Option<TestSuiteExecTime>,
pub metrics: MetricMap,
pub failures: Vec<(TestDesc, Vec<u8>)>,
pub not_failures: Vec<(TestDesc, Vec<u8>)>,
allowed_fail: 0,
filtered_out: 0,
measured: 0,
+ exec_time: None,
metrics: MetricMap::new(),
failures: Vec::new(),
not_failures: Vec::new(),
})
}
- pub fn write_log<F, S>(
- &mut self,
- msg: F,
- ) -> io::Result<()>
+ pub fn write_log<F, S>(&mut self, msg: F) -> io::Result<()>
where
S: AsRef<str>,
F: FnOnce() -> S,
let msg = msg();
let msg = msg.as_ref();
o.write_all(msg.as_bytes())
- },
+ }
}
}
- pub fn write_log_result(&mut self,test: &TestDesc,
+ pub fn write_log_result(
+ &mut self,
+ test: &TestDesc,
result: &TestResult,
exec_time: Option<&TestExecTime>,
) -> io::Result<()> {
- self.write_log(|| format!(
- "{} {}",
- match *result {
- TestResult::TrOk => "ok".to_owned(),
- TestResult::TrFailed => "failed".to_owned(),
- TestResult::TrFailedMsg(ref msg) => format!("failed: {}", msg),
- TestResult::TrIgnored => "ignored".to_owned(),
- TestResult::TrAllowedFail => "failed (allowed)".to_owned(),
- TestResult::TrBench(ref bs) => fmt_bench_samples(bs),
- TestResult::TrTimedFail => "failed (time limit exceeded)".to_owned(),
- },
- test.name,
- ))?;
+ self.write_log(|| {
+ format!(
+ "{} {}",
+ match *result {
+ TestResult::TrOk => "ok".to_owned(),
+ TestResult::TrFailed => "failed".to_owned(),
+ TestResult::TrFailedMsg(ref msg) => format!("failed: {}", msg),
+ TestResult::TrIgnored => "ignored".to_owned(),
+ TestResult::TrAllowedFail => "failed (allowed)".to_owned(),
+ TestResult::TrBench(ref bs) => fmt_bench_samples(bs),
+ TestResult::TrTimedFail => "failed (time limit exceeded)".to_owned(),
+ },
+ test.name,
+ )
+ })?;
if let Some(exec_time) = exec_time {
self.write_log(|| format!(" <{}>", exec_time))?;
}
for test in filter_tests(&opts, tests) {
use crate::TestFn::*;
- let TestDescAndFn {
- desc: TestDesc { name, .. },
- testfn,
- } = test;
+ let TestDescAndFn { desc: TestDesc { name, .. }, testfn } = test;
let fntype = match testfn {
StaticTestFn(..) | DynTestFn(..) => {
if !quiet {
if ntest != 0 || nbench != 0 {
- writeln!(output, "")?;
+ writeln!(output)?;
}
- writeln!(
- output,
- "{}, {}",
- plural(ntest, "test"),
- plural(nbench, "benchmark")
- )?;
+ writeln!(output, "{}, {}", plural(ntest, "test"), plural(nbench, "benchmark"))?;
}
Ok(())
is_multithreaded,
opts.time_options,
)),
- OutputFormat::Terse => Box::new(TerseFormatter::new(
- output,
- opts.use_color(),
- max_name_len,
- is_multithreaded,
- )),
+ OutputFormat::Terse => {
+ Box::new(TerseFormatter::new(output, opts.use_color(), max_name_len, is_multithreaded))
+ }
OutputFormat::Json => Box::new(JsonFormatter::new(output)),
};
let mut st = ConsoleTestState::new(opts)?;
+ // Prevent the usage of `Instant` in some cases:
+ // - It's currently not supported for wasm targets.
+ // - We disable it for miri because it's not available when isolation is enabled.
+ let is_instant_supported = !cfg!(target_arch = "wasm32") && !cfg!(miri);
+
+ let start_time = if is_instant_supported { Some(Instant::now()) } else { None };
run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?;
+ st.exec_time = start_time.map(|t| TestSuiteExecTime(t.elapsed()));
assert!(st.current_test_count() == st.total);