Shorter output for rustc --test
binaries.
A program created with `rustc --test` prints at least one line per test. This can be very verbose, especially with [data-driven tests]( https://internals.rust-lang.org/t/test-and-external-test-harnesses/3145) when hundreds or thousands of tests is not rare. This adds a `-q` or `--quiet` option that changes the output to one character instead of one line per test (except metrics and benchmarks results which have additional data to show): ``` Running target/debug/wpt-75c594dc1e6e6187 running 314 tests .............................................................................. .............................................................................. .............................................................................. .............................................................................. .. test result: ok. 314 passed; 0 failed; 0 ignored; 0 measured ``` This is a breaking change since the `test::TestOpts` struct now has one more field.
This commit is contained in:
parent
c116ae35cf
commit
bbb45c41df
3 changed files with 42 additions and 17 deletions
|
@ -155,5 +155,8 @@ pub struct Config {
|
||||||
pub lldb_python_dir: Option<String>,
|
pub lldb_python_dir: Option<String>,
|
||||||
|
|
||||||
// Explain what's going on
|
// Explain what's going on
|
||||||
pub verbose: bool
|
pub verbose: bool,
|
||||||
|
|
||||||
|
// Print one character per test instead of one line
|
||||||
|
pub quiet: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
|
||||||
optopt("", "host-rustcflags", "flags to pass to rustc for host", "FLAGS"),
|
optopt("", "host-rustcflags", "flags to pass to rustc for host", "FLAGS"),
|
||||||
optopt("", "target-rustcflags", "flags to pass to rustc for target", "FLAGS"),
|
optopt("", "target-rustcflags", "flags to pass to rustc for target", "FLAGS"),
|
||||||
optflag("", "verbose", "run tests verbosely, showing all output"),
|
optflag("", "verbose", "run tests verbosely, showing all output"),
|
||||||
|
optflag("", "quiet", "print one character per test instead of one line"),
|
||||||
optopt("", "logfile", "file to log test execution to", "FILE"),
|
optopt("", "logfile", "file to log test execution to", "FILE"),
|
||||||
optopt("", "target", "the target to build for", "TARGET"),
|
optopt("", "target", "the target to build for", "TARGET"),
|
||||||
optopt("", "host", "the host to build for", "HOST"),
|
optopt("", "host", "the host to build for", "HOST"),
|
||||||
|
@ -158,6 +159,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
|
||||||
!opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
|
!opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
|
||||||
lldb_python_dir: matches.opt_str("lldb-python-dir"),
|
lldb_python_dir: matches.opt_str("lldb-python-dir"),
|
||||||
verbose: matches.opt_present("verbose"),
|
verbose: matches.opt_present("verbose"),
|
||||||
|
quiet: matches.opt_present("quiet"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +193,7 @@ pub fn log_config(config: &Config) {
|
||||||
logv(c, format!("adb_device_status: {}",
|
logv(c, format!("adb_device_status: {}",
|
||||||
config.adb_device_status));
|
config.adb_device_status));
|
||||||
logv(c, format!("verbose: {}", config.verbose));
|
logv(c, format!("verbose: {}", config.verbose));
|
||||||
|
logv(c, format!("quiet: {}", config.quiet));
|
||||||
logv(c, format!("\n"));
|
logv(c, format!("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,6 +260,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
|
||||||
Some(ref filter) => Some(filter.clone()),
|
Some(ref filter) => Some(filter.clone()),
|
||||||
},
|
},
|
||||||
run_ignored: config.run_ignored,
|
run_ignored: config.run_ignored,
|
||||||
|
quiet: config.quiet,
|
||||||
logfile: config.logfile.clone(),
|
logfile: config.logfile.clone(),
|
||||||
run_tests: true,
|
run_tests: true,
|
||||||
bench_benchmarks: true,
|
bench_benchmarks: true,
|
||||||
|
|
|
@ -109,7 +109,7 @@ impl fmt::Display for TestName {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
enum NamePadding {
|
enum NamePadding {
|
||||||
PadNone,
|
PadNone,
|
||||||
PadOnRight,
|
PadOnRight,
|
||||||
|
@ -301,6 +301,7 @@ pub struct TestOpts {
|
||||||
pub logfile: Option<PathBuf>,
|
pub logfile: Option<PathBuf>,
|
||||||
pub nocapture: bool,
|
pub nocapture: bool,
|
||||||
pub color: ColorConfig,
|
pub color: ColorConfig,
|
||||||
|
pub quiet: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestOpts {
|
impl TestOpts {
|
||||||
|
@ -314,6 +315,7 @@ impl TestOpts {
|
||||||
logfile: None,
|
logfile: None,
|
||||||
nocapture: false,
|
nocapture: false,
|
||||||
color: AutoColor,
|
color: AutoColor,
|
||||||
|
quiet: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,6 +333,7 @@ fn optgroups() -> Vec<getopts::OptGroup> {
|
||||||
of stdout", "PATH"),
|
of stdout", "PATH"),
|
||||||
getopts::optflag("", "nocapture", "don't capture stdout/stderr of each \
|
getopts::optflag("", "nocapture", "don't capture stdout/stderr of each \
|
||||||
task, allow printing directly"),
|
task, allow printing directly"),
|
||||||
|
getopts::optflag("q", "quiet", "Display one character per test instead of one line"),
|
||||||
getopts::optopt("", "color", "Configure coloring of output:
|
getopts::optopt("", "color", "Configure coloring of output:
|
||||||
auto = colorize if stdout is a tty and tests are run on serially (default);
|
auto = colorize if stdout is a tty and tests are run on serially (default);
|
||||||
always = always colorize output;
|
always = always colorize output;
|
||||||
|
@ -388,6 +391,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let run_ignored = matches.opt_present("ignored");
|
let run_ignored = matches.opt_present("ignored");
|
||||||
|
let quiet = matches.opt_present("quiet");
|
||||||
|
|
||||||
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));
|
||||||
|
@ -420,6 +424,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
|
||||||
logfile: logfile,
|
logfile: logfile,
|
||||||
nocapture: nocapture,
|
nocapture: nocapture,
|
||||||
color: color,
|
color: color,
|
||||||
|
quiet: quiet,
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(Ok(test_opts))
|
Some(Ok(test_opts))
|
||||||
|
@ -451,6 +456,7 @@ struct ConsoleTestState<T> {
|
||||||
log_out: Option<File>,
|
log_out: Option<File>,
|
||||||
out: OutputLocation<T>,
|
out: OutputLocation<T>,
|
||||||
use_color: bool,
|
use_color: bool,
|
||||||
|
quiet: bool,
|
||||||
total: usize,
|
total: usize,
|
||||||
passed: usize,
|
passed: usize,
|
||||||
failed: usize,
|
failed: usize,
|
||||||
|
@ -476,6 +482,7 @@ impl<T: Write> ConsoleTestState<T> {
|
||||||
out: out,
|
out: out,
|
||||||
log_out: log_out,
|
log_out: log_out,
|
||||||
use_color: use_color(opts),
|
use_color: use_color(opts),
|
||||||
|
quiet: opts.quiet,
|
||||||
total: 0,
|
total: 0,
|
||||||
passed: 0,
|
passed: 0,
|
||||||
failed: 0,
|
failed: 0,
|
||||||
|
@ -488,15 +495,15 @@ impl<T: Write> ConsoleTestState<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_ok(&mut self) -> io::Result<()> {
|
pub fn write_ok(&mut self) -> io::Result<()> {
|
||||||
self.write_pretty("ok", term::color::GREEN)
|
self.write_short_result("ok", ".", term::color::GREEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_failed(&mut self) -> io::Result<()> {
|
pub fn write_failed(&mut self) -> io::Result<()> {
|
||||||
self.write_pretty("FAILED", term::color::RED)
|
self.write_short_result("FAILED", "F", term::color::RED)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_ignored(&mut self) -> io::Result<()> {
|
pub fn write_ignored(&mut self) -> io::Result<()> {
|
||||||
self.write_pretty("ignored", term::color::YELLOW)
|
self.write_short_result("ignored", "i", term::color::YELLOW)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_metric(&mut self) -> io::Result<()> {
|
pub fn write_metric(&mut self) -> io::Result<()> {
|
||||||
|
@ -507,6 +514,16 @@ impl<T: Write> ConsoleTestState<T> {
|
||||||
self.write_pretty("bench", term::color::CYAN)
|
self.write_pretty("bench", term::color::CYAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn write_short_result(&mut self, verbose: &str, quiet: &str, color: term::color::Color)
|
||||||
|
-> io::Result<()> {
|
||||||
|
if self.quiet {
|
||||||
|
self.write_pretty(quiet, color)
|
||||||
|
} else {
|
||||||
|
try!(self.write_pretty(verbose, color));
|
||||||
|
self.write_plain("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write_pretty(&mut self, word: &str, color: term::color::Color) -> io::Result<()> {
|
pub fn write_pretty(&mut self, word: &str, color: term::color::Color) -> io::Result<()> {
|
||||||
match self.out {
|
match self.out {
|
||||||
Pretty(ref mut term) => {
|
Pretty(ref mut term) => {
|
||||||
|
@ -550,28 +567,28 @@ impl<T: Write> ConsoleTestState<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_test_start(&mut self, test: &TestDesc, align: NamePadding) -> io::Result<()> {
|
pub fn write_test_start(&mut self, test: &TestDesc, align: NamePadding) -> io::Result<()> {
|
||||||
let name = test.padded_name(self.max_name_len, align);
|
if self.quiet && align != PadOnRight {
|
||||||
self.write_plain(&format!("test {} ... ", name))
|
Ok(())
|
||||||
|
} else {
|
||||||
|
let name = test.padded_name(self.max_name_len, align);
|
||||||
|
self.write_plain(&format!("test {} ... ", name))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_result(&mut self, result: &TestResult) -> io::Result<()> {
|
pub fn write_result(&mut self, result: &TestResult) -> io::Result<()> {
|
||||||
try!(match *result {
|
match *result {
|
||||||
TrOk => self.write_ok(),
|
TrOk => self.write_ok(),
|
||||||
TrFailed => self.write_failed(),
|
TrFailed => self.write_failed(),
|
||||||
TrIgnored => self.write_ignored(),
|
TrIgnored => self.write_ignored(),
|
||||||
TrMetrics(ref mm) => {
|
TrMetrics(ref mm) => {
|
||||||
try!(self.write_metric());
|
try!(self.write_metric());
|
||||||
self.write_plain(&format!(": {}", mm.fmt_metrics()))
|
self.write_plain(&format!(": {}\n", mm.fmt_metrics()))
|
||||||
}
|
}
|
||||||
TrBench(ref bs) => {
|
TrBench(ref bs) => {
|
||||||
try!(self.write_bench());
|
try!(self.write_bench());
|
||||||
|
self.write_plain(&format!(": {}\n", fmt_bench_samples(bs)))
|
||||||
try!(self.write_plain(&format!(": {}", fmt_bench_samples(bs))));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
self.write_plain("\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_log(&mut self, test: &TestDesc, result: &TestResult) -> io::Result<()> {
|
pub fn write_log(&mut self, test: &TestDesc, result: &TestResult) -> io::Result<()> {
|
||||||
|
@ -629,9 +646,9 @@ impl<T: Write> ConsoleTestState<T> {
|
||||||
try!(self.write_plain("\ntest result: "));
|
try!(self.write_plain("\ntest result: "));
|
||||||
if success {
|
if success {
|
||||||
// There's no parallelism at this point so it's safe to use color
|
// There's no parallelism at this point so it's safe to use color
|
||||||
try!(self.write_ok());
|
try!(self.write_pretty("ok", term::color::GREEN));
|
||||||
} else {
|
} else {
|
||||||
try!(self.write_failed());
|
try!(self.write_pretty("FAILED", term::color::RED));
|
||||||
}
|
}
|
||||||
let s = format!(". {} passed; {} failed; {} ignored; {} measured\n\n",
|
let s = format!(". {} passed; {} failed; {} ignored; {} measured\n\n",
|
||||||
self.passed,
|
self.passed,
|
||||||
|
@ -758,6 +775,7 @@ fn should_sort_failures_before_printing_them() {
|
||||||
log_out: None,
|
log_out: None,
|
||||||
out: Raw(Vec::new()),
|
out: Raw(Vec::new()),
|
||||||
use_color: false,
|
use_color: false,
|
||||||
|
quiet: false,
|
||||||
total: 0,
|
total: 0,
|
||||||
passed: 0,
|
passed: 0,
|
||||||
failed: 0,
|
failed: 0,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue