@@ -64,7 +64,9 @@ impl ToStr for TestName {
6464pub enum TestFn {
6565 StaticTestFn ( extern fn ( ) ) ,
6666 StaticBenchFn ( extern fn ( & mut BenchHarness ) ) ,
67+ StaticMetricFn ( ~fn ( & mut MetricMap ) ) ,
6768 DynTestFn ( ~fn ( ) ) ,
69+ DynMetricFn ( ~fn ( & mut MetricMap ) ) ,
6870 DynBenchFn ( ~fn ( & mut BenchHarness ) )
6971}
7072
@@ -95,6 +97,7 @@ pub struct Metric {
9597 noise : f64
9698}
9799
100+ #[ deriving( Eq ) ]
98101pub struct MetricMap ( TreeMap < ~str , Metric > ) ;
99102
100103/// Analysis of a single change in metric
@@ -218,7 +221,13 @@ pub struct BenchSamples {
218221}
219222
220223#[ deriving( Eq ) ]
221- pub enum TestResult { TrOk , TrFailed , TrIgnored , TrBench ( BenchSamples ) }
224+ pub enum TestResult {
225+ TrOk ,
226+ TrFailed ,
227+ TrIgnored ,
228+ TrMetrics ( MetricMap ) ,
229+ TrBench ( BenchSamples )
230+ }
222231
223232struct ConsoleTestState {
224233 out : @io:: Writer ,
@@ -229,7 +238,7 @@ struct ConsoleTestState {
229238 passed : uint ,
230239 failed : uint ,
231240 ignored : uint ,
232- benchmarked : uint ,
241+ measured : uint ,
233242 metrics : MetricMap ,
234243 failures : ~[ TestDesc ]
235244}
@@ -261,7 +270,7 @@ impl ConsoleTestState {
261270 passed : 0 u,
262271 failed : 0 u,
263272 ignored : 0 u,
264- benchmarked : 0 u,
273+ measured : 0 u,
265274 metrics : MetricMap :: new ( ) ,
266275 failures : ~[ ]
267276 }
@@ -279,11 +288,14 @@ impl ConsoleTestState {
279288 self . write_pretty ( "ignored" , term:: color:: YELLOW ) ;
280289 }
281290
291+ pub fn write_metric ( & self ) {
292+ self . write_pretty ( "metric" , term:: color:: CYAN ) ;
293+ }
294+
282295 pub fn write_bench ( & self ) {
283296 self . write_pretty ( "bench" , term:: color:: CYAN ) ;
284297 }
285298
286-
287299 pub fn write_added ( & self ) {
288300 self . write_pretty ( "added" , term:: color:: GREEN ) ;
289301 }
@@ -332,6 +344,10 @@ impl ConsoleTestState {
332344 TrOk => self . write_ok ( ) ,
333345 TrFailed => self . write_failed ( ) ,
334346 TrIgnored => self . write_ignored ( ) ,
347+ TrMetrics ( ref mm) => {
348+ self . write_metric ( ) ;
349+ self . out . write_str ( ": " + fmt_metrics ( mm) ) ;
350+ }
335351 TrBench ( ref bs) => {
336352 self . write_bench ( ) ;
337353 self . out . write_str ( ": " + fmt_bench_samples ( bs) )
@@ -349,6 +365,7 @@ impl ConsoleTestState {
349365 TrOk => ~"ok",
350366 TrFailed => ~" failed",
351367 TrIgnored => ~" ignored",
368+ TrMetrics(ref mm) => fmt_metrics(mm),
352369 TrBench(ref bs) => fmt_bench_samples(bs)
353370 }, test.name.to_str()));
354371 }
@@ -416,7 +433,7 @@ impl ConsoleTestState {
416433 pub fn write_run_finish(&self,
417434 ratchet_metrics: &Option<Path>,
418435 ratchet_pct: Option<f64>) -> bool {
419- assert!(self.passed + self.failed + self.ignored + self.benchmarked == self.total);
436+ assert!(self.passed + self.failed + self.ignored + self.measured == self.total);
420437
421438 let ratchet_success = match *ratchet_metrics {
422439 None => true,
@@ -448,12 +465,23 @@ impl ConsoleTestState {
448465 } else {
449466 self . write_failed ( ) ;
450467 }
451- self . out . write_str ( fmt ! ( ". %u passed; %u failed; %u ignored, %u benchmarked \n \n " ,
452- self . passed, self . failed, self . ignored, self . benchmarked ) ) ;
468+ self . out . write_str ( fmt ! ( ". %u passed; %u failed; %u ignored; %u measured \n \n " ,
469+ self . passed, self . failed, self . ignored, self . measured ) ) ;
453470 return success;
454471 }
455472}
456473
474+ pub fn fmt_metrics ( mm : & MetricMap ) -> ~str {
475+ use std:: iterator:: IteratorUtil ;
476+ let v : ~[ ~str ] = mm. iter ( )
477+ . transform ( |( k, v) | fmt ! ( "%s: %f (+/- %f)" ,
478+ * k,
479+ v. value as float,
480+ v. noise as float) )
481+ . collect ( ) ;
482+ v. connect ( ", " )
483+ }
484+
457485pub fn fmt_bench_samples ( bs : & BenchSamples ) -> ~str {
458486 if bs. mb_s != 0 {
459487 fmt ! ( "%u ns/iter (+/- %u) = %u MB/s" ,
@@ -481,11 +509,19 @@ pub fn run_tests_console(opts: &TestOpts,
481509 match result {
482510 TrOk => st. passed += 1 ,
483511 TrIgnored => st. ignored += 1 ,
512+ TrMetrics ( mm) => {
513+ let tname = test. name . to_str ( ) ;
514+ for mm. iter( ) . advance( ) |( k, v) | {
515+ st. metrics. insert_metric( tname + "." + * k,
516+ v. value, v. noise) ;
517+ }
518+ st. measured += 1
519+ }
484520 TrBench ( bs) => {
485521 st. metrics. insert_metric( test. name. to_str( ) ,
486522 bs. ns_iter_summ. median,
487523 bs. ns_iter_summ. max - bs. ns_iter_summ. min) ;
488- st. benchmarked += 1
524+ st. measured += 1
489525 }
490526 TrFailed => {
491527 st. failed += 1 ;
@@ -533,7 +569,7 @@ fn should_sort_failures_before_printing_them() {
533569 passed : 0 u,
534570 failed : 0 u,
535571 ignored : 0 u,
536- benchmarked : 0 u,
572+ measured : 0 u,
537573 metrics : MetricMap :: new( ) ,
538574 failures : ~[ test_b, test_a]
539575 } ;
@@ -565,11 +601,11 @@ fn run_tests(opts: &TestOpts,
565601
566602 callback( TeFiltered ( filtered_descs) ) ;
567603
568- let ( filtered_tests, filtered_benchs ) =
604+ let ( filtered_tests, filtered_benchs_and_metrics ) =
569605 do filtered_tests. partition |e| {
570606 match e. testfn {
571607 StaticTestFn ( _) | DynTestFn ( _) => true ,
572- StaticBenchFn ( _ ) | DynBenchFn ( _ ) => false
608+ _ => false
573609 }
574610 } ;
575611
@@ -607,7 +643,8 @@ fn run_tests(opts: &TestOpts,
607643 }
608644
609645 // All benchmarks run at the end, in serial.
610- for filtered_benchs. consume_iter( ) . advance |b| {
646+ // (this includes metric fns)
647+ for filtered_benchs_and_metrics. consume_iter( ) . advance |b| {
611648 callback( TeWait ( copy b. desc) ) ;
612649 run_test( !opts. run_benchmarks, b, ch. clone( ) ) ;
613650 let ( test, result) = p. recv( ) ;
@@ -730,6 +767,18 @@ pub fn run_test(force_ignore: bool,
730767 monitor_ch. send( ( desc, TrBench ( bs) ) ) ;
731768 return ;
732769 }
770+ DynMetricFn ( f) => {
771+ let mut mm = MetricMap :: new( ) ;
772+ f( & mut mm) ;
773+ monitor_ch. send( ( desc, TrMetrics ( mm) ) ) ;
774+ return ;
775+ }
776+ StaticMetricFn ( f) => {
777+ let mut mm = MetricMap :: new( ) ;
778+ f( & mut mm) ;
779+ monitor_ch. send( ( desc, TrMetrics ( mm) ) ) ;
780+ return ;
781+ }
733782 DynTestFn ( f) => run_test_inner( desc, monitor_ch, f) ,
734783 StaticTestFn ( f) => run_test_inner( desc, monitor_ch, || f( ) )
735784 }
@@ -757,12 +806,12 @@ impl ToJson for Metric {
757806
758807impl MetricMap {
759808
760- fn new( ) -> MetricMap {
809+ pub fn new( ) -> MetricMap {
761810 MetricMap ( TreeMap : : new( ) )
762811 }
763812
764813 /// Load MetricDiff from a file.
765- fn load( p: & Path ) -> MetricMap {
814+ pub fn load( p: & Path ) -> MetricMap {
766815 assert!( os:: path_exists( p) ) ;
767816 let f = io:: file_reader( p) . get( ) ;
768817 let mut decoder = json:: Decoder ( json:: from_reader( f) . get( ) ) ;
@@ -793,7 +842,7 @@ impl MetricMap {
793842 None => f64:: max( vold. noise. abs( ) , v. noise. abs( ) ) ,
794843 Some ( pct) => vold. value * pct / 100 . 0
795844 } ;
796- if delta. abs( ) < noise {
845+ if delta. abs( ) <= noise {
797846 LikelyNoise
798847 } else {
799848 let pct = delta. abs( ) / vold. value * 100.0 ;
@@ -1245,10 +1294,14 @@ mod tests {
12451294 assert_eq!(*(diff1.find(&~" in-both-noise").get()), LikelyNoise);
12461295 assert_eq!(*(diff1.find(&~" in-first-noise").get()), MetricRemoved);
12471296 assert_eq!(*(diff1.find(&~" in-second-noise").get()), MetricAdded);
1248- assert_eq!(*(diff1.find(&~" in-both-want-downwards-but-regressed").get()), Regression(100.0));
1249- assert_eq!(*(diff1.find(&~" in-both-want-downwards-and-improved").get()), Improvement(50.0));
1250- assert_eq!(*(diff1.find(&~" in-both-want-upwards-but-regressed").get()), Regression(50.0));
1251- assert_eq!(*(diff1.find(&~" in-both-want-upwards-and-improved").get()), Improvement(100.0));
1297+ assert_eq!(*(diff1.find(&~" in-both-want-downwards-but-regressed").get()),
1298+ Regression(100.0));
1299+ assert_eq!(*(diff1.find(&~" in-both-want-downwards-and-improved").get()),
1300+ Improvement(50.0));
1301+ assert_eq!(*(diff1.find(&~" in-both-want-upwards-but-regressed").get()),
1302+ Regression(50.0));
1303+ assert_eq!(*(diff1.find(&~" in-both-want-upwards-and-improved").get()),
1304+ Improvement(100.0));
12521305 assert_eq!(diff1.len(), 7);
12531306
12541307 let diff2 = m2.compare_to_old(&m1, Some(200.0));
0 commit comments