Add --verbose flag to cton-util test.
This commit is contained in:
@@ -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() {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user