@@ -26,12 +26,11 @@ use stats;
26
26
use time:: precise_time_ns;
27
27
use collections:: TreeMap ;
28
28
29
- use std:: clone:: Clone ;
30
29
use std:: cmp;
31
30
use std:: io;
32
- use std:: io:: File ;
33
- use std:: io:: Writer ;
31
+ use std:: io:: { File , PortReader , ChanWriter } ;
34
32
use std:: io:: stdio:: StdWriter ;
33
+ use std:: str;
35
34
use std:: task;
36
35
use std:: to_str:: ToStr ;
37
36
use std:: f64;
@@ -358,7 +357,7 @@ struct ConsoleTestState<T> {
358
357
ignored : uint ,
359
358
measured : uint ,
360
359
metrics : MetricMap ,
361
- failures : ~[ TestDesc ] ,
360
+ failures : ~[ ( TestDesc , ~ [ u8 ] ) ] ,
362
361
max_name_len : uint , // number of columns to fill when aligning names
363
362
}
364
363
@@ -498,9 +497,23 @@ impl<T: Writer> ConsoleTestState<T> {
498
497
pub fn write_failures(&mut self) -> io::IoResult<()> {
499
498
if_ok!(self.write_plain("\n failures:\n " ) ) ;
500
499
let mut failures = ~[ ] ;
501
- for f in self . failures. iter( ) {
500
+ let mut fail_out = ~"";
501
+ for & ( ref f, ref stdout) in self . failures. iter( ) {
502
502
failures. push( f. name. to_str( ) ) ;
503
+ if stdout. len( ) > 0 {
504
+ fail_out. push_str( format!( "---- {} stdout ----\n \t " ,
505
+ f. name. to_str( ) ) ) ;
506
+ let output = str :: from_utf8_lossy( * stdout) ;
507
+ fail_out. push_str( output. as_slice( ) . replace( "\n " , "\n \t " ) ) ;
508
+ fail_out. push_str( "\n " ) ;
509
+ }
510
+ }
511
+ if fail_out. len( ) > 0 {
512
+ if_ok!( self . write_plain( "\n " ) ) ;
513
+ if_ok!( self . write_plain( fail_out) ) ;
503
514
}
515
+
516
+ if_ok!( self . write_plain( "\n failures:\n " ) ) ;
504
517
failures. sort( ) ;
505
518
for name in failures. iter( ) {
506
519
if_ok!( self . write_plain( format!( " {}\n " , name. to_str( ) ) ) ) ;
@@ -632,7 +645,7 @@ pub fn run_tests_console(opts: &TestOpts,
632
645
match ( * event) . clone( ) {
633
646
TeFiltered ( ref filtered_tests) => st. write_run_start( filtered_tests. len( ) ) ,
634
647
TeWait ( ref test, padding) => st. write_test_start( test, padding) ,
635
- TeResult ( test, result) => {
648
+ TeResult ( test, result, stdout ) => {
636
649
if_ok!( st. write_log( & test, & result) ) ;
637
650
if_ok!( st. write_result( & result) ) ;
638
651
match result {
@@ -655,7 +668,7 @@ pub fn run_tests_console(opts: &TestOpts,
655
668
}
656
669
TrFailed => {
657
670
st. failed += 1 ;
658
- st. failures. push( test) ;
671
+ st. failures. push( ( test, stdout ) ) ;
659
672
}
660
673
}
661
674
Ok ( ( ) )
@@ -717,17 +730,17 @@ fn should_sort_failures_before_printing_them() {
717
730
measured: 0 u,
718
731
max_name_len: 10 u,
719
732
metrics: MetricMap :: new( ) ,
720
- failures: ~[ test_b, test_a]
733
+ failures: ~[ ( test_b, ~ [ ] ) , ( test_a, ~ [ ] ) ]
721
734
} ;
722
735
723
736
st. write_failures( ) . unwrap( ) ;
724
737
let s = match st. out {
725
- Raw ( ref m) => str :: from_utf8 ( m. get_ref( ) ) . unwrap ( ) ,
738
+ Raw ( ref m) => str :: from_utf8_lossy ( m. get_ref( ) ) ,
726
739
Pretty ( _) => unreachable!( )
727
740
} ;
728
741
729
- let apos = s. find_str( "a" ) . unwrap( ) ;
730
- let bpos = s. find_str( "b" ) . unwrap( ) ;
742
+ let apos = s. as_slice ( ) . find_str( "a" ) . unwrap( ) ;
743
+ let bpos = s. as_slice ( ) . find_str( "b" ) . unwrap( ) ;
731
744
assert!( apos < bpos) ;
732
745
}
733
746
@@ -737,11 +750,10 @@ fn use_color() -> bool { return get_concurrency() == 1; }
737
750
enum TestEvent {
738
751
TeFiltered ( ~[ TestDesc ] ) ,
739
752
TeWait ( TestDesc , NamePadding ) ,
740
- TeResult ( TestDesc , TestResult ) ,
753
+ TeResult ( TestDesc , TestResult , ~ [ u8 ] /* stdout */ ) ,
741
754
}
742
755
743
- /// The message sent to the test monitor from the individual runners.
744
- pub type MonitorMsg = ( TestDesc , TestResult ) ;
756
+ pub type MonitorMsg = ( TestDesc , TestResult , ~[ u8 ] /* stdout */ ) ;
745
757
746
758
fn run_tests( opts: & TestOpts ,
747
759
tests: ~[ TestDescAndFn ] ,
@@ -783,11 +795,11 @@ fn run_tests(opts: &TestOpts,
783
795
pending += 1 ;
784
796
}
785
797
786
- let ( desc, result) = p. recv( ) ;
798
+ let ( desc, result, stdout ) = p. recv( ) ;
787
799
if concurrency != 1 {
788
800
if_ok!( callback( TeWait ( desc. clone( ) , PadNone ) ) ) ;
789
801
}
790
- if_ok!( callback( TeResult ( desc, result) ) ) ;
802
+ if_ok!( callback( TeResult ( desc, result, stdout ) ) ) ;
791
803
pending -= 1 ;
792
804
}
793
805
@@ -796,8 +808,8 @@ fn run_tests(opts: &TestOpts,
796
808
for b in filtered_benchs_and_metrics. move_iter( ) {
797
809
if_ok!( callback( TeWait ( b. desc. clone( ) , b. testfn. padding( ) ) ) ) ;
798
810
run_test( !opts. run_benchmarks, b, ch. clone( ) ) ;
799
- let ( test, result) = p. recv( ) ;
800
- if_ok!( callback( TeResult ( test, result) ) ) ;
811
+ let ( test, result, stdout ) = p. recv( ) ;
812
+ if_ok!( callback( TeResult ( test, result, stdout ) ) ) ;
801
813
}
802
814
Ok ( ( ) )
803
815
}
@@ -884,7 +896,7 @@ pub fn run_test(force_ignore: bool,
884
896
let TestDescAndFn { desc, testfn} = test;
885
897
886
898
if force_ignore || desc. ignore {
887
- monitor_ch. send( ( desc, TrIgnored ) ) ;
899
+ monitor_ch. send( ( desc, TrIgnored , ~ [ ] ) ) ;
888
900
return ;
889
901
}
890
902
@@ -893,40 +905,47 @@ pub fn run_test(force_ignore: bool,
893
905
testfn: proc( ) ) {
894
906
spawn( proc( ) {
895
907
let mut task = task:: task( ) ;
896
- task. name( match desc. name {
897
- DynTestName ( ref name) => name. to_owned( ) . into_maybe_owned( ) ,
898
- StaticTestName ( name) => name. into_maybe_owned( )
899
- } ) ;
908
+ let ( p, c) = Chan :: new( ) ;
909
+ let mut reader = PortReader :: new( p) ;
910
+ let stdout = ChanWriter :: new( c. clone( ) ) ;
911
+ let stderr = ChanWriter :: new( c) ;
912
+ match desc. name {
913
+ DynTestName ( ref name) => task. name( name. clone( ) ) ,
914
+ StaticTestName ( name) => task. name( name) ,
915
+ }
916
+ task. opts. stdout = Some ( ~stdout as ~Writer ) ;
917
+ task. opts. stderr = Some ( ~stderr as ~Writer ) ;
900
918
let result_future = task. future_result( ) ;
901
919
task. spawn( testfn) ;
902
920
921
+ let stdout = reader. read_to_end( ) . unwrap( ) ;
903
922
let task_result = result_future. recv( ) ;
904
923
let test_result = calc_result( & desc, task_result. is_ok( ) ) ;
905
- monitor_ch. send( ( desc. clone( ) , test_result) ) ;
906
- } ) ;
924
+ monitor_ch. send( ( desc. clone( ) , test_result, stdout ) ) ;
925
+ } )
907
926
}
908
927
909
928
match testfn {
910
929
DynBenchFn ( bencher) => {
911
930
let bs = :: test:: bench:: benchmark( |harness| bencher. run( harness) ) ;
912
- monitor_ch. send( ( desc, TrBench ( bs) ) ) ;
931
+ monitor_ch. send( ( desc, TrBench ( bs) , ~ [ ] ) ) ;
913
932
return ;
914
933
}
915
934
StaticBenchFn ( benchfn) => {
916
935
let bs = :: test:: bench:: benchmark( |harness| benchfn( harness) ) ;
917
- monitor_ch. send( ( desc, TrBench ( bs) ) ) ;
936
+ monitor_ch. send( ( desc, TrBench ( bs) , ~ [ ] ) ) ;
918
937
return ;
919
938
}
920
939
DynMetricFn ( f) => {
921
940
let mut mm = MetricMap :: new( ) ;
922
941
f( & mut mm) ;
923
- monitor_ch. send( ( desc, TrMetrics ( mm) ) ) ;
942
+ monitor_ch. send( ( desc, TrMetrics ( mm) , ~ [ ] ) ) ;
924
943
return ;
925
944
}
926
945
StaticMetricFn ( f) => {
927
946
let mut mm = MetricMap :: new( ) ;
928
947
f( & mut mm) ;
929
- monitor_ch. send( ( desc, TrMetrics ( mm) ) ) ;
948
+ monitor_ch. send( ( desc, TrMetrics ( mm) , ~ [ ] ) ) ;
930
949
return ;
931
950
}
932
951
DynTestFn ( f) => run_test_inner( desc, monitor_ch, f) ,
@@ -1264,7 +1283,7 @@ mod tests {
1264
1283
};
1265
1284
let (p, ch) = Chan::new();
1266
1285
run_test(false, desc, ch);
1267
- let (_, res) = p.recv();
1286
+ let (_, res, _ ) = p.recv();
1268
1287
assert!(res != TrOk);
1269
1288
}
1270
1289
@@ -1281,7 +1300,7 @@ mod tests {
1281
1300
};
1282
1301
let (p, ch) = Chan::new();
1283
1302
run_test(false, desc, ch);
1284
- let (_, res) = p.recv();
1303
+ let (_, res, _ ) = p.recv();
1285
1304
assert_eq!(res, TrIgnored);
1286
1305
}
1287
1306
@@ -1298,7 +1317,7 @@ mod tests {
1298
1317
};
1299
1318
let (p, ch) = Chan::new();
1300
1319
run_test(false, desc, ch);
1301
- let (_, res) = p.recv();
1320
+ let (_, res, _ ) = p.recv();
1302
1321
assert_eq!(res, TrOk);
1303
1322
}
1304
1323
@@ -1315,7 +1334,7 @@ mod tests {
1315
1334
};
1316
1335
let (p, ch) = Chan::new();
1317
1336
run_test(false, desc, ch);
1318
- let (_, res) = p.recv();
1337
+ let (_, res, _ ) = p.recv();
1319
1338
assert_eq!(res, TrFailed);
1320
1339
}
1321
1340
0 commit comments