@@ -10,8 +10,9 @@ use cargo::{
10
10
use cargo_test_support:: paths:: { root, CargoPathExt } ;
11
11
use cargo_test_support:: registry:: Package ;
12
12
use cargo_test_support:: {
13
- basic_bin_manifest, basic_lib_manifest, basic_manifest, git, is_nightly, lines_match_unordered,
14
- main_file, paths, project, rustc_host, sleep_ms, symlink_supported, t, Execs , ProjectBuilder ,
13
+ basic_bin_manifest, basic_lib_manifest, basic_manifest, cargo_exe, git, is_nightly,
14
+ lines_match_unordered, main_file, paths, process, project, rustc_host, sleep_ms,
15
+ symlink_supported, t, Execs , ProjectBuilder ,
15
16
} ;
16
17
use std:: env;
17
18
use std:: fs;
@@ -5256,6 +5257,85 @@ hello stderr!
5256
5257
lines_match_unordered ( "hello stdout!\n " , & stdout) . unwrap ( ) ;
5257
5258
}
5258
5259
5260
+ #[ cargo_test]
5261
+ fn close_output_during_drain ( ) {
5262
+ // Test to close the output during the build phase (drain_the_queue).
5263
+ // There was a bug where it would hang.
5264
+
5265
+ // Server to know when rustc has spawned.
5266
+ let listener = std:: net:: TcpListener :: bind ( "127.0.0.1:0" ) . unwrap ( ) ;
5267
+ let addr = listener. local_addr ( ) . unwrap ( ) ;
5268
+
5269
+ // Create a wrapper so the test can know when compiling has started.
5270
+ let rustc_wrapper = {
5271
+ let p = project ( )
5272
+ . at ( "compiler" )
5273
+ . file ( "Cargo.toml" , & basic_manifest ( "compiler" , "1.0.0" ) )
5274
+ . file (
5275
+ "src/main.rs" ,
5276
+ & r#"
5277
+ use std::process::Command;
5278
+ use std::env;
5279
+ use std::io::Read;
5280
+
5281
+ fn main() {
5282
+ // Only wait on the first dependency.
5283
+ if matches!(env::var("CARGO_PKG_NAME").as_deref(), Ok("dep")) {
5284
+ let mut socket = std::net::TcpStream::connect("__ADDR__").unwrap();
5285
+ // Wait for the test to tell us to start printing.
5286
+ let mut buf = [0];
5287
+ drop(socket.read_exact(&mut buf));
5288
+ }
5289
+ let mut cmd = Command::new("rustc");
5290
+ for arg in env::args_os().skip(1) {
5291
+ cmd.arg(arg);
5292
+ }
5293
+ std::process::exit(cmd.status().unwrap().code().unwrap());
5294
+ }
5295
+ "#
5296
+ . replace ( "__ADDR__" , & addr. to_string ( ) ) ,
5297
+ )
5298
+ . build ( ) ;
5299
+ p. cargo ( "build" ) . run ( ) ;
5300
+ p. bin ( "compiler" )
5301
+ } ;
5302
+
5303
+ Package :: new ( "dep" , "1.0.0" ) . publish ( ) ;
5304
+ let p = project ( )
5305
+ . file (
5306
+ "Cargo.toml" ,
5307
+ r#"
5308
+ [package]
5309
+ name = "foo"
5310
+ version = "0.1.0"
5311
+
5312
+ [dependencies]
5313
+ dep = "1.0"
5314
+ "# ,
5315
+ )
5316
+ . file ( "src/lib.rs" , "" )
5317
+ . build ( ) ;
5318
+
5319
+ // Spawn cargo, wait for the first rustc to start, and then close stderr.
5320
+ let mut cmd = process ( & cargo_exe ( ) )
5321
+ . arg ( "check" )
5322
+ . cwd ( p. root ( ) )
5323
+ . env ( "RUSTC" , rustc_wrapper)
5324
+ . build_command ( ) ;
5325
+ cmd. stdout ( Stdio :: piped ( ) ) . stderr ( Stdio :: piped ( ) ) ;
5326
+ let mut child = cmd. spawn ( ) . expect ( "cargo should spawn" ) ;
5327
+ // Wait for the rustc wrapper to start.
5328
+ let rustc_conn = listener. accept ( ) . unwrap ( ) . 0 ;
5329
+ // Close stderr to force an error.
5330
+ drop ( child. stderr . take ( ) ) ;
5331
+ // Tell the wrapper to continue.
5332
+ drop ( rustc_conn) ;
5333
+ match child. wait ( ) {
5334
+ Ok ( status) => assert ! ( !status. success( ) ) ,
5335
+ Err ( e) => panic ! ( "child wait failed: {}" , e) ,
5336
+ }
5337
+ }
5338
+
5259
5339
use cargo_test_support:: registry:: Dependency ;
5260
5340
5261
5341
#[ cargo_test]
0 commit comments