]> git.proxmox.com Git - cargo.git/blob - vendor/jobserver/tests/make-as-a-client.rs
New upstream version 0.47.0
[cargo.git] / vendor / jobserver / tests / make-as-a-client.rs
1 extern crate jobserver;
2 extern crate tempdir;
3
4 use std::env;
5 use std::fs::File;
6 use std::io::prelude::*;
7 use std::net::{TcpListener, TcpStream};
8 use std::process::Command;
9
10 use jobserver::Client;
11 use tempdir::TempDir;
12
13 macro_rules! t {
14 ($e:expr) => {
15 match $e {
16 Ok(e) => e,
17 Err(e) => panic!("{} failed with {}", stringify!($e), e),
18 }
19 };
20 }
21
22 fn main() {
23 if env::var("_DO_THE_TEST").is_ok() {
24 std::process::exit(
25 Command::new(env::var_os("MAKE").unwrap())
26 .env("MAKEFLAGS", env::var_os("CARGO_MAKEFLAGS").unwrap())
27 .env_remove("_DO_THE_TEST")
28 .args(&env::args_os().skip(1).collect::<Vec<_>>())
29 .status()
30 .unwrap()
31 .code()
32 .unwrap_or(1),
33 );
34 }
35
36 if let Ok(s) = env::var("TEST_ADDR") {
37 let mut contents = Vec::new();
38 t!(t!(TcpStream::connect(&s)).read_to_end(&mut contents));
39 return;
40 }
41
42 let c = t!(Client::new(1));
43 let td = TempDir::new("foo").unwrap();
44
45 let prog = env::var("MAKE").unwrap_or("make".to_string());
46
47 let me = t!(env::current_exe());
48 let me = me.to_str().unwrap();
49
50 let mut cmd = Command::new(&me);
51 cmd.current_dir(td.path());
52 cmd.env("MAKE", prog);
53 cmd.env("_DO_THE_TEST", "1");
54
55 t!(t!(File::create(td.path().join("Makefile"))).write_all(
56 format!(
57 "\
58 all: foo bar
59 foo:
60 \t{0}
61 bar:
62 \t{0}
63 ",
64 me
65 )
66 .as_bytes()
67 ));
68
69 // We're leaking one extra token to `make` sort of violating the makefile
70 // jobserver protocol. It has the desired effect though.
71 c.configure(&mut cmd);
72
73 let listener = t!(TcpListener::bind("127.0.0.1:0"));
74 let addr = t!(listener.local_addr());
75 cmd.env("TEST_ADDR", addr.to_string());
76 let mut child = t!(cmd.spawn());
77
78 // We should get both connections as the two programs should be run
79 // concurrently.
80 let a = t!(listener.accept());
81 let b = t!(listener.accept());
82 drop((a, b));
83
84 assert!(t!(child.wait()).success());
85 }