1
1
use std:: any:: Any ;
2
+ use std:: process:: ExitStatus ;
3
+
4
+ #[ cfg( unix) ]
5
+ use std:: os:: unix:: process:: ExitStatusExt ;
2
6
3
7
use super :: bench:: BenchSamples ;
4
8
use super :: options:: ShouldPanic ;
@@ -7,11 +11,15 @@ use super::types::TestDesc;
7
11
8
12
pub use self :: TestResult :: * ;
9
13
10
- // Return codes for secondary process.
14
+ // Return code for secondary process.
11
15
// Start somewhere other than 0 so we know the return code means what we think
12
16
// it means.
13
17
pub const TR_OK : i32 = 50 ;
14
- pub const TR_FAILED : i32 = 51 ;
18
+
19
+ // On Windows we use __fastfail to abort, which is documented to use this
20
+ // exception code.
21
+ #[ cfg( windows) ]
22
+ const STATUS_ABORTED : i32 = 0xC0000409u32 as i32 ;
15
23
16
24
#[ derive( Debug , Clone , PartialEq ) ]
17
25
pub enum TestResult {
@@ -81,14 +89,28 @@ pub fn calc_result<'a>(
81
89
/// Creates a `TestResult` depending on the exit code of test subprocess.
82
90
pub fn get_result_from_exit_code (
83
91
desc : & TestDesc ,
84
- code : i32 ,
92
+ status : ExitStatus ,
85
93
time_opts : & Option < time:: TestTimeOptions > ,
86
94
exec_time : & Option < time:: TestExecTime > ,
87
95
) -> TestResult {
88
- let result = match code {
89
- TR_OK => TestResult :: TrOk ,
90
- TR_FAILED => TestResult :: TrFailed ,
91
- _ => TestResult :: TrFailedMsg ( format ! ( "got unexpected return code {code}" ) ) ,
96
+ let result = match status. code ( ) {
97
+ Some ( TR_OK ) => TestResult :: TrOk ,
98
+ #[ cfg( windows) ]
99
+ Some ( STATUS_ABORTED ) => TestResult :: TrFailed ,
100
+ #[ cfg( unix) ]
101
+ None => match status. signal ( ) {
102
+ Some ( libc:: SIGABRT ) => TestResult :: TrFailed ,
103
+ Some ( signal) => {
104
+ TestResult :: TrFailedMsg ( format ! ( "child process exited with signal {signal}" ) )
105
+ }
106
+ None => unreachable ! ( "status.code() returned None but status.signal() was None" ) ,
107
+ } ,
108
+ #[ cfg( not( unix) ) ]
109
+ None => TestResult :: TrFailedMsg ( format ! ( "unknown return code" ) ) ,
110
+ #[ cfg( any( windows, unix) ) ]
111
+ Some ( code) => TestResult :: TrFailedMsg ( format ! ( "got unexpected return code {code}" ) ) ,
112
+ #[ cfg( not( any( windows, unix) ) ) ]
113
+ Some ( _) => TestResult :: TrFailed ,
92
114
} ;
93
115
94
116
// If test is already failed (or allowed to fail), do not change the result.
0 commit comments