libtest: Add --report-time flag to print test execution time
This commit is contained in:
@@ -27,6 +27,7 @@ impl<T: Write> JsonFormatter<T> {
|
|||||||
ty: &str,
|
ty: &str,
|
||||||
name: &str,
|
name: &str,
|
||||||
evt: &str,
|
evt: &str,
|
||||||
|
exec_time: Option<&TestExecTime>,
|
||||||
stdout: Option<Cow<'_, str>>,
|
stdout: Option<Cow<'_, str>>,
|
||||||
extra: Option<&str>,
|
extra: Option<&str>,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
@@ -34,6 +35,12 @@ impl<T: Write> JsonFormatter<T> {
|
|||||||
r#"{{ "type": "{}", "name": "{}", "event": "{}""#,
|
r#"{{ "type": "{}", "name": "{}", "event": "{}""#,
|
||||||
ty, name, evt
|
ty, name, evt
|
||||||
))?;
|
))?;
|
||||||
|
if let Some(exec_time) = exec_time {
|
||||||
|
self.write_message(&*format!(
|
||||||
|
r#", "exec_time": "{}""#,
|
||||||
|
exec_time
|
||||||
|
))?;
|
||||||
|
}
|
||||||
if let Some(stdout) = stdout {
|
if let Some(stdout) = stdout {
|
||||||
self.write_message(&*format!(
|
self.write_message(&*format!(
|
||||||
r#", "stdout": "{}""#,
|
r#", "stdout": "{}""#,
|
||||||
@@ -69,6 +76,7 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
desc: &TestDesc,
|
desc: &TestDesc,
|
||||||
result: &TestResult,
|
result: &TestResult,
|
||||||
|
exec_time: Option<&TestExecTime>,
|
||||||
stdout: &[u8],
|
stdout: &[u8],
|
||||||
state: &ConsoleTestState,
|
state: &ConsoleTestState,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
@@ -78,24 +86,36 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
match *result {
|
match *result {
|
||||||
TrOk => self.write_event("test", desc.name.as_slice(), "ok", stdout, None),
|
TrOk => {
|
||||||
|
self.write_event("test", desc.name.as_slice(), "ok", exec_time, stdout, None)
|
||||||
|
}
|
||||||
|
|
||||||
TrFailed => self.write_event("test", desc.name.as_slice(), "failed", stdout, None),
|
TrFailed => {
|
||||||
|
self.write_event("test", desc.name.as_slice(), "failed", exec_time, stdout, None)
|
||||||
|
}
|
||||||
|
|
||||||
TrFailedMsg(ref m) => self.write_event(
|
TrFailedMsg(ref m) => self.write_event(
|
||||||
"test",
|
"test",
|
||||||
desc.name.as_slice(),
|
desc.name.as_slice(),
|
||||||
"failed",
|
"failed",
|
||||||
|
exec_time,
|
||||||
stdout,
|
stdout,
|
||||||
Some(&*format!(r#""message": "{}""#, EscapedString(m))),
|
Some(&*format!(r#""message": "{}""#, EscapedString(m))),
|
||||||
),
|
),
|
||||||
|
|
||||||
TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", stdout, None),
|
TrIgnored => {
|
||||||
|
self.write_event("test", desc.name.as_slice(), "ignored", exec_time, stdout, None)
|
||||||
TrAllowedFail => {
|
|
||||||
self.write_event("test", desc.name.as_slice(), "allowed_failure", stdout, None)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TrAllowedFail => self.write_event(
|
||||||
|
"test",
|
||||||
|
desc.name.as_slice(),
|
||||||
|
"allowed_failure",
|
||||||
|
exec_time,
|
||||||
|
stdout,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
|
||||||
TrBench(ref bs) => {
|
TrBench(ref bs) => {
|
||||||
let median = bs.ns_iter_summ.median as usize;
|
let median = bs.ns_iter_summ.median as usize;
|
||||||
let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize;
|
let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ pub(crate) trait OutputFormatter {
|
|||||||
&mut self,
|
&mut self,
|
||||||
desc: &TestDesc,
|
desc: &TestDesc,
|
||||||
result: &TestResult,
|
result: &TestResult,
|
||||||
|
exec_time: Option<&TestExecTime>,
|
||||||
stdout: &[u8],
|
stdout: &[u8],
|
||||||
state: &ConsoleTestState,
|
state: &ConsoleTestState,
|
||||||
) -> io::Result<()>;
|
) -> io::Result<()>;
|
||||||
|
|||||||
@@ -30,20 +30,20 @@ impl<T: Write> PrettyFormatter<T> {
|
|||||||
&self.out
|
&self.out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_ok(&mut self) -> io::Result<()> {
|
pub fn write_ok(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
|
||||||
self.write_short_result("ok", term::color::GREEN)
|
self.write_short_result("ok", term::color::GREEN, exec_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_failed(&mut self) -> io::Result<()> {
|
pub fn write_failed(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
|
||||||
self.write_short_result("FAILED", term::color::RED)
|
self.write_short_result("FAILED", term::color::RED, exec_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_ignored(&mut self) -> io::Result<()> {
|
pub fn write_ignored(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
|
||||||
self.write_short_result("ignored", term::color::YELLOW)
|
self.write_short_result("ignored", term::color::YELLOW, exec_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_allowed_fail(&mut self) -> io::Result<()> {
|
pub fn write_allowed_fail(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
|
||||||
self.write_short_result("FAILED (allowed)", term::color::YELLOW)
|
self.write_short_result("FAILED (allowed)", term::color::YELLOW, exec_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_bench(&mut self) -> io::Result<()> {
|
pub fn write_bench(&mut self) -> io::Result<()> {
|
||||||
@@ -54,8 +54,12 @@ impl<T: Write> PrettyFormatter<T> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
result: &str,
|
result: &str,
|
||||||
color: term::color::Color,
|
color: term::color::Color,
|
||||||
|
exec_time: Option<&TestExecTime>,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
self.write_pretty(result, color)?;
|
self.write_pretty(result, color)?;
|
||||||
|
if let Some(exec_time) = exec_time {
|
||||||
|
self.write_plain(format!(" {}", exec_time))?;
|
||||||
|
}
|
||||||
self.write_plain("\n")
|
self.write_plain("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,6 +170,7 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
desc: &TestDesc,
|
desc: &TestDesc,
|
||||||
result: &TestResult,
|
result: &TestResult,
|
||||||
|
exec_time: Option<&TestExecTime>,
|
||||||
_: &[u8],
|
_: &[u8],
|
||||||
_: &ConsoleTestState,
|
_: &ConsoleTestState,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
@@ -174,10 +179,10 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match *result {
|
match *result {
|
||||||
TrOk => self.write_ok(),
|
TrOk => self.write_ok(exec_time),
|
||||||
TrFailed | TrFailedMsg(_) => self.write_failed(),
|
TrFailed | TrFailedMsg(_) => self.write_failed(exec_time),
|
||||||
TrIgnored => self.write_ignored(),
|
TrIgnored => self.write_ignored(exec_time),
|
||||||
TrAllowedFail => self.write_allowed_fail(),
|
TrAllowedFail => self.write_allowed_fail(exec_time),
|
||||||
TrBench(ref bs) => {
|
TrBench(ref bs) => {
|
||||||
self.write_bench()?;
|
self.write_bench()?;
|
||||||
self.write_plain(&format!(": {}\n", fmt_bench_samples(bs)))
|
self.write_plain(&format!(": {}\n", fmt_bench_samples(bs)))
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
desc: &TestDesc,
|
desc: &TestDesc,
|
||||||
result: &TestResult,
|
result: &TestResult,
|
||||||
|
_: Option<&TestExecTime>,
|
||||||
_: &[u8],
|
_: &[u8],
|
||||||
_: &ConsoleTestState,
|
_: &ConsoleTestState,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
|
|||||||
@@ -378,6 +378,7 @@ pub struct TestOpts {
|
|||||||
pub format: OutputFormat,
|
pub format: OutputFormat,
|
||||||
pub test_threads: Option<usize>,
|
pub test_threads: Option<usize>,
|
||||||
pub skip: Vec<String>,
|
pub skip: Vec<String>,
|
||||||
|
pub report_time: bool,
|
||||||
pub options: Options,
|
pub options: Options,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,6 +461,11 @@ fn optgroups() -> getopts::Options {
|
|||||||
"Enable nightly-only flags:
|
"Enable nightly-only flags:
|
||||||
unstable-options = Allow use of experimental features",
|
unstable-options = Allow use of experimental features",
|
||||||
"unstable-options",
|
"unstable-options",
|
||||||
|
)
|
||||||
|
.optflag(
|
||||||
|
"",
|
||||||
|
"report-time",
|
||||||
|
"Show execution time of each test. Not available for --format=terse"
|
||||||
);
|
);
|
||||||
return opts;
|
return opts;
|
||||||
}
|
}
|
||||||
@@ -573,6 +579,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
|
|||||||
let quiet = matches.opt_present("quiet");
|
let quiet = matches.opt_present("quiet");
|
||||||
let exact = matches.opt_present("exact");
|
let exact = matches.opt_present("exact");
|
||||||
let list = matches.opt_present("list");
|
let list = matches.opt_present("list");
|
||||||
|
let report_time = matches.opt_present("report-time");
|
||||||
|
|
||||||
let logfile = matches.opt_str("logfile");
|
let logfile = matches.opt_str("logfile");
|
||||||
let logfile = logfile.map(|s| PathBuf::from(&s));
|
let logfile = logfile.map(|s| PathBuf::from(&s));
|
||||||
@@ -653,6 +660,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
|
|||||||
format,
|
format,
|
||||||
test_threads,
|
test_threads,
|
||||||
skip: matches.opt_strs("skip"),
|
skip: matches.opt_strs("skip"),
|
||||||
|
report_time,
|
||||||
options: Options::new().display_output(matches.opt_present("show-output")),
|
options: Options::new().display_output(matches.opt_present("show-output")),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -677,6 +685,16 @@ pub enum TestResult {
|
|||||||
|
|
||||||
unsafe impl Send for TestResult {}
|
unsafe impl Send for TestResult {}
|
||||||
|
|
||||||
|
/// The meassured execution time of a unit test.
|
||||||
|
#[derive(Clone, PartialEq)]
|
||||||
|
pub struct TestExecTime(Duration);
|
||||||
|
|
||||||
|
impl fmt::Display for TestExecTime {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{:.3}s", self.0.as_secs_f64())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum OutputLocation<T> {
|
enum OutputLocation<T> {
|
||||||
Pretty(Box<term::StdoutTerminal>),
|
Pretty(Box<term::StdoutTerminal>),
|
||||||
Raw(T),
|
Raw(T),
|
||||||
@@ -736,17 +754,30 @@ impl ConsoleTestState {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_log<S: AsRef<str>>(&mut self, msg: S) -> io::Result<()> {
|
pub fn write_log<F, S>(
|
||||||
let msg = msg.as_ref();
|
&mut self,
|
||||||
|
msg: F,
|
||||||
|
) -> io::Result<()>
|
||||||
|
where
|
||||||
|
S: AsRef<str>,
|
||||||
|
F: FnOnce() -> S,
|
||||||
|
{
|
||||||
match self.log_out {
|
match self.log_out {
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
Some(ref mut o) => o.write_all(msg.as_bytes()),
|
Some(ref mut o) => {
|
||||||
|
let msg = msg();
|
||||||
|
let msg = msg.as_ref();
|
||||||
|
o.write_all(msg.as_bytes())
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_log_result(&mut self, test: &TestDesc, result: &TestResult) -> io::Result<()> {
|
pub fn write_log_result(&mut self,test: &TestDesc,
|
||||||
self.write_log(format!(
|
result: &TestResult,
|
||||||
"{} {}\n",
|
exec_time: Option<&TestExecTime>,
|
||||||
|
) -> io::Result<()> {
|
||||||
|
self.write_log(|| format!(
|
||||||
|
"{} {}",
|
||||||
match *result {
|
match *result {
|
||||||
TrOk => "ok".to_owned(),
|
TrOk => "ok".to_owned(),
|
||||||
TrFailed => "failed".to_owned(),
|
TrFailed => "failed".to_owned(),
|
||||||
@@ -755,8 +786,12 @@ impl ConsoleTestState {
|
|||||||
TrAllowedFail => "failed (allowed)".to_owned(),
|
TrAllowedFail => "failed (allowed)".to_owned(),
|
||||||
TrBench(ref bs) => fmt_bench_samples(bs),
|
TrBench(ref bs) => fmt_bench_samples(bs),
|
||||||
},
|
},
|
||||||
test.name
|
test.name,
|
||||||
))
|
))?;
|
||||||
|
if let Some(exec_time) = exec_time {
|
||||||
|
self.write_log(|| format!(" {}", exec_time))?;
|
||||||
|
}
|
||||||
|
self.write_log(|| "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_test_count(&self) -> usize {
|
fn current_test_count(&self) -> usize {
|
||||||
@@ -843,7 +878,7 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Res
|
|||||||
};
|
};
|
||||||
|
|
||||||
writeln!(output, "{}: {}", name, fntype)?;
|
writeln!(output, "{}: {}", name, fntype)?;
|
||||||
st.write_log(format!("{} {}\n", fntype, name))?;
|
st.write_log(|| format!("{} {}\n", fntype, name))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn plural(count: u32, s: &str) -> String {
|
fn plural(count: u32, s: &str) -> String {
|
||||||
@@ -884,9 +919,9 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
|
|||||||
TeFilteredOut(filtered_out) => Ok(st.filtered_out = filtered_out),
|
TeFilteredOut(filtered_out) => Ok(st.filtered_out = filtered_out),
|
||||||
TeWait(ref test) => out.write_test_start(test),
|
TeWait(ref test) => out.write_test_start(test),
|
||||||
TeTimeout(ref test) => out.write_timeout(test),
|
TeTimeout(ref test) => out.write_timeout(test),
|
||||||
TeResult(test, result, stdout) => {
|
TeResult(test, result, exec_time, stdout) => {
|
||||||
st.write_log_result(&test, &result)?;
|
st.write_log_result(&test, &result, exec_time.as_ref())?;
|
||||||
out.write_result(&test, &result, &*stdout, &st)?;
|
out.write_result(&test, &result, exec_time.as_ref(), &*stdout, &st)?;
|
||||||
match result {
|
match result {
|
||||||
TrOk => {
|
TrOk => {
|
||||||
st.passed += 1;
|
st.passed += 1;
|
||||||
@@ -1004,12 +1039,12 @@ fn stdout_isatty() -> bool {
|
|||||||
pub enum TestEvent {
|
pub enum TestEvent {
|
||||||
TeFiltered(Vec<TestDesc>),
|
TeFiltered(Vec<TestDesc>),
|
||||||
TeWait(TestDesc),
|
TeWait(TestDesc),
|
||||||
TeResult(TestDesc, TestResult, Vec<u8>),
|
TeResult(TestDesc, TestResult, Option<TestExecTime>, Vec<u8>),
|
||||||
TeTimeout(TestDesc),
|
TeTimeout(TestDesc),
|
||||||
TeFilteredOut(usize),
|
TeFilteredOut(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type MonitorMsg = (TestDesc, TestResult, Vec<u8>);
|
pub type MonitorMsg = (TestDesc, TestResult, Option<TestExecTime>, Vec<u8>);
|
||||||
|
|
||||||
struct Sink(Arc<Mutex<Vec<u8>>>);
|
struct Sink(Arc<Mutex<Vec<u8>>>);
|
||||||
impl Write for Sink {
|
impl Write for Sink {
|
||||||
@@ -1105,8 +1140,8 @@ where
|
|||||||
let test = remaining.pop().unwrap();
|
let test = remaining.pop().unwrap();
|
||||||
callback(TeWait(test.desc.clone()))?;
|
callback(TeWait(test.desc.clone()))?;
|
||||||
run_test(opts, !opts.run_tests, test, tx.clone(), Concurrent::No);
|
run_test(opts, !opts.run_tests, test, tx.clone(), Concurrent::No);
|
||||||
let (test, result, stdout) = rx.recv().unwrap();
|
let (test, result, exec_time, stdout) = rx.recv().unwrap();
|
||||||
callback(TeResult(test, result, stdout))?;
|
callback(TeResult(test, result, exec_time, stdout))?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while pending > 0 || !remaining.is_empty() {
|
while pending > 0 || !remaining.is_empty() {
|
||||||
@@ -1135,10 +1170,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (desc, result, stdout) = res.unwrap();
|
let (desc, result, exec_time, stdout) = res.unwrap();
|
||||||
running_tests.remove(&desc);
|
running_tests.remove(&desc);
|
||||||
|
|
||||||
callback(TeResult(desc, result, stdout))?;
|
callback(TeResult(desc, result, exec_time, stdout))?;
|
||||||
pending -= 1;
|
pending -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1148,8 +1183,8 @@ where
|
|||||||
for b in filtered_benchs {
|
for b in filtered_benchs {
|
||||||
callback(TeWait(b.desc.clone()))?;
|
callback(TeWait(b.desc.clone()))?;
|
||||||
run_test(opts, false, b, tx.clone(), Concurrent::No);
|
run_test(opts, false, b, tx.clone(), Concurrent::No);
|
||||||
let (test, result, stdout) = rx.recv().unwrap();
|
let (test, result, exec_time, stdout) = rx.recv().unwrap();
|
||||||
callback(TeResult(test, result, stdout))?;
|
callback(TeResult(test, result, exec_time, stdout))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -1384,7 +1419,7 @@ pub fn run_test(
|
|||||||
&& desc.should_panic != ShouldPanic::No;
|
&& desc.should_panic != ShouldPanic::No;
|
||||||
|
|
||||||
if force_ignore || desc.ignore || ignore_because_panic_abort {
|
if force_ignore || desc.ignore || ignore_because_panic_abort {
|
||||||
monitor_ch.send((desc, TrIgnored, Vec::new())).unwrap();
|
monitor_ch.send((desc, TrIgnored, None, Vec::new())).unwrap();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1392,6 +1427,7 @@ pub fn run_test(
|
|||||||
desc: TestDesc,
|
desc: TestDesc,
|
||||||
monitor_ch: Sender<MonitorMsg>,
|
monitor_ch: Sender<MonitorMsg>,
|
||||||
nocapture: bool,
|
nocapture: bool,
|
||||||
|
report_time: bool,
|
||||||
testfn: Box<dyn FnOnce() + Send>,
|
testfn: Box<dyn FnOnce() + Send>,
|
||||||
concurrency: Concurrent,
|
concurrency: Concurrent,
|
||||||
) {
|
) {
|
||||||
@@ -1410,7 +1446,16 @@ pub fn run_test(
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let start = if report_time {
|
||||||
|
Some(Instant::now())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
let result = catch_unwind(AssertUnwindSafe(testfn));
|
let result = catch_unwind(AssertUnwindSafe(testfn));
|
||||||
|
let exec_time = start.map(|start| {
|
||||||
|
let duration = start.elapsed();
|
||||||
|
TestExecTime(duration)
|
||||||
|
});
|
||||||
|
|
||||||
if let Some((printio, panicio)) = oldio {
|
if let Some((printio, panicio)) = oldio {
|
||||||
io::set_print(printio);
|
io::set_print(printio);
|
||||||
@@ -1420,7 +1465,7 @@ pub fn run_test(
|
|||||||
let test_result = calc_result(&desc, result);
|
let test_result = calc_result(&desc, result);
|
||||||
let stdout = data.lock().unwrap().to_vec();
|
let stdout = data.lock().unwrap().to_vec();
|
||||||
monitor_ch
|
monitor_ch
|
||||||
.send((desc.clone(), test_result, stdout))
|
.send((desc.clone(), test_result, exec_time, stdout))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1449,12 +1494,20 @@ pub fn run_test(
|
|||||||
}
|
}
|
||||||
DynTestFn(f) => {
|
DynTestFn(f) => {
|
||||||
let cb = move || __rust_begin_short_backtrace(f);
|
let cb = move || __rust_begin_short_backtrace(f);
|
||||||
run_test_inner(desc, monitor_ch, opts.nocapture, Box::new(cb), concurrency)
|
run_test_inner(
|
||||||
|
desc,
|
||||||
|
monitor_ch,
|
||||||
|
opts.nocapture,
|
||||||
|
opts.report_time,
|
||||||
|
Box::new(cb),
|
||||||
|
concurrency,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
StaticTestFn(f) => run_test_inner(
|
StaticTestFn(f) => run_test_inner(
|
||||||
desc,
|
desc,
|
||||||
monitor_ch,
|
monitor_ch,
|
||||||
opts.nocapture,
|
opts.nocapture,
|
||||||
|
opts.report_time,
|
||||||
Box::new(move || __rust_begin_short_backtrace(f)),
|
Box::new(move || __rust_begin_short_backtrace(f)),
|
||||||
concurrency,
|
concurrency,
|
||||||
),
|
),
|
||||||
@@ -1702,7 +1755,7 @@ pub mod bench {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let stdout = data.lock().unwrap().to_vec();
|
let stdout = data.lock().unwrap().to_vec();
|
||||||
monitor_ch.send((desc, test_result, stdout)).unwrap();
|
monitor_ch.send((desc, test_result, None, stdout)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_once<F>(f: F)
|
pub fn run_once<F>(f: F)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ impl TestOpts {
|
|||||||
format: OutputFormat::Pretty,
|
format: OutputFormat::Pretty,
|
||||||
test_threads: None,
|
test_threads: None,
|
||||||
skip: vec![],
|
skip: vec![],
|
||||||
|
report_time: false,
|
||||||
options: Options::new(),
|
options: Options::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +68,7 @@ pub fn do_not_run_ignored_tests() {
|
|||||||
};
|
};
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
||||||
let (_, res, _) = rx.recv().unwrap();
|
let (_, res, _, _) = rx.recv().unwrap();
|
||||||
assert!(res != TrOk);
|
assert!(res != TrOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +86,7 @@ pub fn ignored_tests_result_in_ignored() {
|
|||||||
};
|
};
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
||||||
let (_, res, _) = rx.recv().unwrap();
|
let (_, res, _, _) = rx.recv().unwrap();
|
||||||
assert!(res == TrIgnored);
|
assert!(res == TrIgnored);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ fn test_should_panic() {
|
|||||||
};
|
};
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
||||||
let (_, res, _) = rx.recv().unwrap();
|
let (_, res, _, _) = rx.recv().unwrap();
|
||||||
assert!(res == TrOk);
|
assert!(res == TrOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +126,7 @@ fn test_should_panic_good_message() {
|
|||||||
};
|
};
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
||||||
let (_, res, _) = rx.recv().unwrap();
|
let (_, res, _, _) = rx.recv().unwrap();
|
||||||
assert!(res == TrOk);
|
assert!(res == TrOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +148,7 @@ fn test_should_panic_bad_message() {
|
|||||||
};
|
};
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
||||||
let (_, res, _) = rx.recv().unwrap();
|
let (_, res, _, _) = rx.recv().unwrap();
|
||||||
assert!(res == TrFailedMsg(format!("{} '{}'", failed_msg, expected)));
|
assert!(res == TrFailedMsg(format!("{} '{}'", failed_msg, expected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,10 +166,43 @@ fn test_should_panic_but_succeeds() {
|
|||||||
};
|
};
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
|
||||||
let (_, res, _) = rx.recv().unwrap();
|
let (_, res, _, _) = rx.recv().unwrap();
|
||||||
assert!(res == TrFailed);
|
assert!(res == TrFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
|
||||||
|
fn f() {}
|
||||||
|
let desc = TestDescAndFn {
|
||||||
|
desc: TestDesc {
|
||||||
|
name: StaticTestName("whatever"),
|
||||||
|
ignore: false,
|
||||||
|
should_panic: ShouldPanic::No,
|
||||||
|
allow_fail: false,
|
||||||
|
},
|
||||||
|
testfn: DynTestFn(Box::new(f)),
|
||||||
|
};
|
||||||
|
let test_opts = TestOpts {
|
||||||
|
report_time,
|
||||||
|
..TestOpts::new()
|
||||||
|
};
|
||||||
|
let (tx, rx) = channel();
|
||||||
|
run_test(&test_opts, false, desc, tx, Concurrent::No);
|
||||||
|
let (_, _, exec_time, _) = rx.recv().unwrap();
|
||||||
|
exec_time
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_should_not_report_time() {
|
||||||
|
let exec_time = report_time_test_template(false);
|
||||||
|
assert!(exec_time.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_should_report_time() {
|
||||||
|
let exec_time = report_time_test_template(true);
|
||||||
|
assert!(exec_time.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_ignored_flag() {
|
fn parse_ignored_flag() {
|
||||||
let args = vec![
|
let args = vec![
|
||||||
|
|||||||
Reference in New Issue
Block a user