Add --verbose flag to cton-util test.

This commit is contained in:
Jakob Stoklund Olesen
2016-09-17 17:11:17 -07:00
parent 23887358dd
commit 67c8ae7f14
3 changed files with 50 additions and 23 deletions

View File

@@ -30,8 +30,8 @@ pub type TestResult = Result<time::Duration, String>;
/// Directories are scanned recursively for test cases ending in `.cton`. These test cases are /// Directories are scanned recursively for test cases ending in `.cton`. These test cases are
/// executed on background threads. /// executed on background threads.
/// ///
pub fn run(files: Vec<String>) -> CommandResult { pub fn run(verbose: bool, files: Vec<String>) -> CommandResult {
let mut runner = TestRunner::new(); let mut runner = TestRunner::new(verbose);
for path in files.iter().map(Path::new) { for path in files.iter().map(Path::new) {
if path.is_file() { if path.is_file() {

View File

@@ -4,6 +4,7 @@
//! scanning directories for tests. //! scanning directories for tests.
use std::error::Error; use std::error::Error;
use std::fmt::{self, Display};
use std::ffi::OsStr; use std::ffi::OsStr;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use filetest::{TestResult, runone}; use filetest::{TestResult, runone};
@@ -35,7 +36,26 @@ impl QueueEntry {
} }
} }
impl Display for QueueEntry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let p = self.path.to_string_lossy();
match self.state {
State::Done(Ok(dur)) => {
write!(f,
"{}.{:03} {}",
dur.as_secs(),
dur.subsec_nanos() / 1000000,
p)
}
State::Done(Err(ref e)) => write!(f, "FAIL {}: {}", p, e),
_ => write!(f, "{}", p),
}
}
}
pub struct TestRunner { pub struct TestRunner {
verbose: bool,
// Directories that have not yet been scanned. // Directories that have not yet been scanned.
dir_stack: Vec<PathBuf>, dir_stack: Vec<PathBuf>,
@@ -45,8 +65,8 @@ pub struct TestRunner {
// Pointer into `tests` where the `New` entries begin. // Pointer into `tests` where the `New` entries begin.
new_tests: usize, new_tests: usize,
// Number of contiguous finished tests at the front of `tests`. // Number of contiguous reported tests at the front of `tests`.
finished_tests: usize, reported_tests: usize,
// Number of errors seen so far. // Number of errors seen so far.
errors: usize, errors: usize,
@@ -59,12 +79,13 @@ pub struct TestRunner {
impl TestRunner { impl TestRunner {
/// Create a new blank TrstRunner. /// Create a new blank TrstRunner.
pub fn new() -> TestRunner { pub fn new(verbose: bool) -> TestRunner {
TestRunner { TestRunner {
verbose: verbose,
dir_stack: Vec::new(), dir_stack: Vec::new(),
tests: Vec::new(), tests: Vec::new(),
new_tests: 0, new_tests: 0,
finished_tests: 0, reported_tests: 0,
errors: 0, errors: 0,
ticks_since_progress: 0, ticks_since_progress: 0,
threads: None, threads: None,
@@ -154,10 +175,17 @@ impl TestRunner {
println!("{}: {}", path.to_string_lossy(), err); println!("{}: {}", path.to_string_lossy(), err);
} }
/// Report an error related to a job. /// Report on the next in-order job, if it's done.
fn job_error(&mut self, jobid: usize, err: &str) { fn report_job(&self) -> bool {
self.errors += 1; let jobid = self.reported_tests;
println!("FAIL {}: {}", self.tests[jobid].path.to_string_lossy(), err); if let Some(&QueueEntry { state: State::Done(ref result), .. }) = self.tests.get(jobid) {
if self.verbose || result.is_err() {
println!("{}", self.tests[jobid]);
}
true
} else {
false
}
} }
/// Schedule any new jobs to run. /// Schedule any new jobs to run.
@@ -186,15 +214,14 @@ impl TestRunner {
/// Report the end of a job. /// Report the end of a job.
fn finish_job(&mut self, jobid: usize, result: TestResult) { fn finish_job(&mut self, jobid: usize, result: TestResult) {
assert_eq!(self.tests[jobid].state, State::Running); assert_eq!(self.tests[jobid].state, State::Running);
if let Err(ref e) = result { if result.is_err() {
self.job_error(jobid, e); self.errors += 1;
} }
self.tests[jobid].state = State::Done(result); self.tests[jobid].state = State::Done(result);
if jobid == self.finished_tests {
while let Some(&QueueEntry { state: State::Done(_), .. }) = self.tests // Rports jobs in order.
.get(self.finished_tests) { while self.report_job() {
self.finished_tests += 1; self.reported_tests += 1;
}
} }
} }
@@ -214,11 +241,11 @@ impl TestRunner {
if self.ticks_since_progress == TIMEOUT_SLOW { if self.ticks_since_progress == TIMEOUT_SLOW {
println!("STALLED for {} seconds with {}/{} tests finished", println!("STALLED for {} seconds with {}/{} tests finished",
self.ticks_since_progress, self.ticks_since_progress,
self.finished_tests, self.reported_tests,
self.tests.len()); self.tests.len());
for jobid in self.finished_tests..self.tests.len() { for jobid in self.reported_tests..self.tests.len() {
if self.tests[jobid].state == State::Running { if self.tests[jobid].state == State::Running {
println!("slow: {}", self.tests[jobid].path.to_string_lossy()); println!("slow: {}", self.tests[jobid]);
} }
} }
} }
@@ -234,7 +261,7 @@ impl TestRunner {
fn drain_threads(&mut self) { fn drain_threads(&mut self) {
if let Some(mut conc) = self.threads.take() { if let Some(mut conc) = self.threads.take() {
conc.shutdown(); conc.shutdown();
while self.finished_tests < self.tests.len() { while self.reported_tests < self.tests.len() {
match conc.get() { match conc.get() {
Some(reply) => self.handle_reply(reply), Some(reply) => self.handle_reply(reply),
None => break, None => break,

View File

@@ -21,7 +21,7 @@ const USAGE: &'static str = "
Cretonne code generator utility Cretonne code generator utility
Usage: Usage:
cton-util test <file>... cton-util test [-v] <file>...
cton-util cat <file>... cton-util cat <file>...
cton-util filecheck [-v] <file> cton-util filecheck [-v] <file>
cton-util print-cfg <file>... cton-util print-cfg <file>...
@@ -60,7 +60,7 @@ fn cton_util() -> CommandResult {
// Find the sub-command to execute. // Find the sub-command to execute.
if args.cmd_test { if args.cmd_test {
filetest::run(args.arg_file) filetest::run(args.flag_verbose, args.arg_file)
} else if args.cmd_cat { } else if args.cmd_cat {
cat::run(args.arg_file) cat::run(args.arg_file)
} else if args.cmd_filecheck { } else if args.cmd_filecheck {