@@ -134,7 +134,7 @@ fn test_tls_set() {
134
134
}
135
135
136
136
#[ test]
137
- fn test_pipe ( ) {
137
+ fn test_pipe ( ) -> CmdResult {
138
138
assert ! ( run_cmd!( echo "xx" ) . is_ok( ) ) ;
139
139
assert_eq ! ( run_fun!( echo "xx" ) . unwrap( ) , "xx" ) ;
140
140
assert ! ( run_cmd!( echo xx | wc) . is_ok( ) ) ;
@@ -158,6 +158,64 @@ fn test_pipe() {
158
158
set_pipefail ( false ) ;
159
159
assert ! ( run_fun!( false | true ) . is_ok( ) ) ;
160
160
set_pipefail ( true ) ;
161
+
162
+ // test that illustrates the bugs in wait_with_pipe()
163
+ // FIXME: make set_pipefail() thread safe, then move this to a separate test function
164
+ assert ! ( spawn_with_output!( false ) ?. wait_with_all( ) . 0 . is_err( ) ) ;
165
+ assert ! ( spawn_with_output!( false ) ?. wait_with_output( ) . is_err( ) ) ;
166
+ assert ! ( spawn_with_output!( false ) ?
167
+ . wait_with_raw_output( & mut vec![ ] )
168
+ . is_err( ) ) ;
169
+
170
+ // wait_with_pipe() can’t check the exit status of the last child
171
+ assert ! ( spawn_with_output!( false ) ?
172
+ . wait_with_pipe( & mut |_stdout| { } )
173
+ . is_ok( ) ) ;
174
+
175
+ // wait_with_pipe() kills the last child when the provided function returns
176
+ assert ! ( spawn_with_output!( sh -c "while :; do :; done" ) ?
177
+ . wait_with_pipe( & mut |_stdout| { } )
178
+ . is_ok( ) ) ;
179
+
180
+ // wait_with_pipe_thread() checks the exit status of the last child, even if pipefail is disabled
181
+ set_pipefail ( false ) ;
182
+ assert ! ( spawn_with_output!( true | false ) ?
183
+ . wait_with_pipe_thread( |_stdout| { } )
184
+ . is_err( ) ) ;
185
+ assert ! ( spawn_with_output!( true | true ) ?
186
+ . wait_with_pipe_thread( |_stdout| { } )
187
+ . is_ok( ) ) ;
188
+ assert ! ( spawn_with_output!( false ) ?
189
+ . wait_with_pipe_thread( |_stdout| { } )
190
+ . is_err( ) ) ;
191
+ assert ! ( spawn_with_output!( true ) ?
192
+ . wait_with_pipe_thread( |_stdout| { } )
193
+ . is_ok( ) ) ;
194
+ set_pipefail ( true ) ;
195
+ // wait_with_pipe_thread() checks the exit status of the other children, unless pipefail is disabled
196
+ set_pipefail ( false ) ;
197
+ assert ! ( spawn_with_output!( false | true ) ?
198
+ . wait_with_pipe_thread( |_stdout| { } )
199
+ . is_ok( ) ) ;
200
+ set_pipefail ( true ) ;
201
+ assert ! ( spawn_with_output!( false | true ) ?
202
+ . wait_with_pipe_thread( |_stdout| { } )
203
+ . is_err( ) ) ;
204
+ assert ! ( spawn_with_output!( true | true ) ?
205
+ . wait_with_pipe_thread( |_stdout| { } )
206
+ . is_ok( ) ) ;
207
+ // wait_with_pipe_thread() handles `ignore`
208
+ assert ! ( spawn_with_output!( ignore false | true ) ?
209
+ . wait_with_pipe_thread( |_stdout| { } )
210
+ . is_ok( ) ) ;
211
+ assert ! ( spawn_with_output!( ignore true | false ) ?
212
+ . wait_with_pipe_thread( |_stdout| { } )
213
+ . is_ok( ) ) ;
214
+ assert ! ( spawn_with_output!( ignore false ) ?
215
+ . wait_with_pipe_thread( |_stdout| { } )
216
+ . is_ok( ) ) ;
217
+
218
+ Ok ( ( ) )
161
219
}
162
220
163
221
#[ test]
0 commit comments