diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 98e031f863e85..7226c6423b82c 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -54,7 +54,7 @@ use self::OutputLocation::*; use stats::Stats; use getopts::{OptGroup, optflag, optopt}; use regex::Regex; -use serialize::{json, Decodable, Encodable}; +use serialize::Encodable; use term::Terminal; use term::color::{Color, RED, YELLOW, GREEN, CYAN}; @@ -62,7 +62,6 @@ use std::any::Any; use std::cmp; use std::collections::BTreeMap; use std::fmt; -use std::io::fs::PathExtensions; use std::io::stdio::StdWriter; use std::io::{File, ChanReader, ChanWriter}; use std::io; @@ -438,9 +437,6 @@ struct ConsoleTestState { log_out: Option, out: OutputLocation, use_color: bool, - show_boxplot: bool, - boxplot_width: uint, - show_all_stats: bool, total: uint, passed: uint, failed: uint, @@ -467,9 +463,6 @@ impl ConsoleTestState { out: out, log_out: log_out, use_color: use_color(opts), - show_boxplot: false, - boxplot_width: 50, - show_all_stats: false, total: 0u, passed: 0u, failed: 0u, @@ -545,33 +538,13 @@ impl ConsoleTestState { TrIgnored => self.write_ignored(), TrMetrics(ref mm) => { try!(self.write_metric()); - self.write_plain(format!(": {}", fmt_metrics(mm)).as_slice()) + self.write_plain(format!(": {}", mm.fmt_metrics()).as_slice()) } TrBench(ref bs) => { try!(self.write_bench()); - if self.show_boxplot { - let mut wr = Vec::new(); - - try!(stats::write_boxplot(&mut wr, &bs.ns_iter_summ, self.boxplot_width)); - - let s = String::from_utf8(wr).unwrap(); - - try!(self.write_plain(format!(": {}", s).as_slice())); - } - - if self.show_all_stats { - let mut wr = Vec::new(); - - try!(stats::write_5_number_summary(&mut wr, &bs.ns_iter_summ)); - - let s = String::from_utf8(wr).unwrap(); - - try!(self.write_plain(format!(": {}", s).as_slice())); - } else { - try!(self.write_plain(format!(": {}", - fmt_bench_samples(bs)).as_slice())); - } + try!(self.write_plain(format!(": {}", + fmt_bench_samples(bs)).as_slice())); Ok(()) } @@ -588,7 +561,7 @@ impl ConsoleTestState { TrOk => "ok".to_string(), TrFailed => "failed".to_string(), TrIgnored => "ignored".to_string(), - TrMetrics(ref mm) => fmt_metrics(mm), + TrMetrics(ref mm) => mm.fmt_metrics(), TrBench(ref bs) => fmt_bench_samples(bs) }, test.name.as_slice()); o.write(s.as_bytes()) @@ -624,34 +597,14 @@ impl ConsoleTestState { Ok(()) } - pub fn write_run_finish(&mut self, - ratchet_metrics: &Option, - ratchet_pct: Option) -> io::IoResult { + pub fn write_run_finish(&mut self) -> io::IoResult { assert!(self.passed + self.failed + self.ignored + self.measured == self.total); - let ratchet_success = match *ratchet_metrics { - None => true, - Some(ref pth) => { - try!(self.write_plain(format!("\nusing metrics ratchet: {:?}\n", - pth.display()).as_slice())); - match ratchet_pct { - None => (), - Some(pct) => - try!(self.write_plain(format!("with noise-tolerance \ - forced to: {}%\n", - pct).as_slice())) - } - true - } - }; - - let test_success = self.failed == 0u; - if !test_success { + let success = self.failed == 0u; + if !success { try!(self.write_failures()); } - let success = ratchet_success && test_success; - try!(self.write_plain("\ntest result: ")); if success { // There's no parallelism at this point so it's safe to use color @@ -666,15 +619,6 @@ impl ConsoleTestState { } } -pub fn fmt_metrics(mm: &MetricMap) -> String { - let MetricMap(ref mm) = *mm; - let v : Vec = mm.iter() - .map(|(k,v)| format!("{}: {} (+/- {})", *k, - v.value as f64, v.noise as f64)) - .collect(); - v.connect(", ") -} - pub fn fmt_bench_samples(bs: &BenchSamples) -> String { if bs.mb_s != 0 { format!("{:>9} ns/iter (+/- {}) = {} MB/s", @@ -745,7 +689,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec ) -> io::IoR None => {} } try!(run_tests(opts, tests, |x| callback(&x, &mut st))); - return st.write_run_finish(&None, None); + return st.write_run_finish(); } #[test] @@ -766,9 +710,6 @@ fn should_sort_failures_before_printing_them() { log_out: None, out: Raw(Vec::new()), use_color: false, - show_boxplot: false, - boxplot_width: 0, - show_all_stats: false, total: 0u, passed: 0u, failed: 0u, @@ -1010,30 +951,6 @@ impl MetricMap { MetricMap(BTreeMap::new()) } - /// Load MetricDiff from a file. - /// - /// # Panics - /// - /// This function will panic if the path does not exist or the path does not - /// contain a valid metric map. - pub fn load(p: &Path) -> MetricMap { - assert!(p.exists()); - let mut f = File::open(p).unwrap(); - let value = json::from_reader(&mut f as &mut io::Reader).unwrap(); - let mut decoder = json::Decoder::new(value); - MetricMap(match Decodable::decode(&mut decoder) { - Ok(t) => t, - Err(e) => panic!("failure decoding JSON: {:?}", e) - }) - } - - /// Write MetricDiff to a file. - pub fn save(&self, p: &Path) -> io::IoResult<()> { - let mut file = try!(File::create(p)); - let MetricMap(ref map) = *self; - write!(&mut file, "{}", json::as_json(map)) - } - /// Insert a named `value` (+/- `noise`) metric into the map. The value /// must be non-negative. The `noise` indicates the uncertainty of the /// metric, which doubles as the "noise range" of acceptable @@ -1055,6 +972,15 @@ impl MetricMap { let MetricMap(ref mut map) = *self; map.insert(name.to_string(), m); } + + pub fn fmt_metrics(&self) -> String { + let MetricMap(ref mm) = *self; + let v : Vec = mm.iter() + .map(|(k,v)| format!("{}: {} (+/- {})", *k, + v.value as f64, v.noise as f64)) + .collect(); + v.connect(", ") + } } diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index cd461cf5766d6..76b85cc10cd89 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -13,9 +13,7 @@ use std::cmp::Ordering::{self, Less, Greater, Equal}; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::{self, Hasher}; -use std::fmt; use std::hash::Hash; -use std::io; use std::mem; use std::num::{Float, FromPrimitive}; @@ -332,111 +330,6 @@ pub fn winsorize(samples: &mut [T], pct: T) { } } -/// Render writes the min, max and quartiles of the provided `Summary` to the provided `Writer`. -pub fn write_5_number_summary(w: &mut W, - s: &Summary) -> io::IoResult<()> { - let (q1,q2,q3) = s.quartiles; - write!(w, "(min={}, q1={}, med={}, q3={}, max={})", - s.min, - q1, - q2, - q3, - s.max) -} - -/// Render a boxplot to the provided writer. The boxplot shows the min, max and quartiles of the -/// provided `Summary` (thus includes the mean) and is scaled to display within the range of the -/// nearest multiple-of-a-power-of-ten above and below the min and max of possible values, and -/// target `width_hint` characters of display (though it will be wider if necessary). -/// -/// As an example, the summary with 5-number-summary `(min=15, q1=17, med=20, q3=24, max=31)` might -/// display as: -/// -/// ```{.ignore} -/// 10 | [--****#******----------] | 40 -/// ``` -pub fn write_boxplot( - w: &mut W, - s: &Summary, - width_hint: uint) - -> io::IoResult<()> { - - let (q1,q2,q3) = s.quartiles; - - // the .abs() handles the case where numbers are negative - let ten: T = FromPrimitive::from_uint(10).unwrap(); - let lomag = ten.powf(s.min.abs().log10().floor()); - let himag = ten.powf(s.max.abs().log10().floor()); - - // need to consider when the limit is zero - let zero: T = Float::zero(); - let lo = if lomag == Float::zero() { - zero - } else { - (s.min / lomag).floor() * lomag - }; - - let hi = if himag == Float::zero() { - zero - } else { - (s.max / himag).ceil() * himag - }; - - let range = hi - lo; - - let lostr = lo.to_string(); - let histr = hi.to_string(); - - let overhead_width = lostr.len() + histr.len() + 4; - let range_width = width_hint - overhead_width; - let range_float = FromPrimitive::from_uint(range_width).unwrap(); - let char_step = range / range_float; - - try!(write!(w, "{} |", lostr)); - - let mut c = 0; - let mut v = lo; - - while c < range_width && v < s.min { - try!(write!(w, " ")); - v = v + char_step; - c += 1; - } - try!(write!(w, "[")); - c += 1; - while c < range_width && v < q1 { - try!(write!(w, "-")); - v = v + char_step; - c += 1; - } - while c < range_width && v < q2 { - try!(write!(w, "*")); - v = v + char_step; - c += 1; - } - try!(write!(w, "#")); - c += 1; - while c < range_width && v < q3 { - try!(write!(w, "*")); - v = v + char_step; - c += 1; - } - while c < range_width && v < s.max { - try!(write!(w, "-")); - v = v + char_step; - c += 1; - } - try!(write!(w, "]")); - while c < range_width { - try!(write!(w, " ")); - v = v + char_step; - c += 1; - } - - try!(write!(w, "| {}", histr)); - Ok(()) -} - /// Returns a HashMap with the number of occurrences of every element in the /// sequence that the iterator exposes. pub fn freq_count(mut iter: T) -> hash_map::HashMap @@ -458,8 +351,6 @@ pub fn freq_count(mut iter: T) -> hash_map::HashMap mod tests { use stats::Stats; use stats::Summary; - use stats::write_5_number_summary; - use stats::write_boxplot; use std::io; use std::f64; @@ -479,10 +370,6 @@ mod tests { let mut w = io::stdout(); let w = &mut w; (write!(w, "\n")).unwrap(); - write_5_number_summary(w, &summ2).unwrap(); - (write!(w, "\n")).unwrap(); - write_boxplot(w, &summ2, 50).unwrap(); - (write!(w, "\n")).unwrap(); assert_eq!(summ.sum, summ2.sum); assert_eq!(summ.min, summ2.min); @@ -1028,23 +915,6 @@ mod tests { check(val, summ); } - #[test] - fn test_boxplot_nonpositive() { - fn t(s: &Summary, expected: String) { - let mut m = Vec::new(); - write_boxplot(&mut m, s, 30).unwrap(); - let out = String::from_utf8(m).unwrap(); - assert_eq!(out, expected); - } - - t(&Summary::new(&[-2.0f64, -1.0f64]), - "-2 |[------******#*****---]| -1".to_string()); - t(&Summary::new(&[0.0f64, 2.0f64]), - "0 |[-------*****#*******---]| 2".to_string()); - t(&Summary::new(&[-2.0f64, 0.0f64]), - "-2 |[------******#******---]| 0".to_string()); - - } #[test] fn test_sum_f64s() { assert_eq!([0.5f64, 3.2321f64, 1.5678f64].sum(), 5.2999);