summaryrefslogtreecommitdiffstats
path: root/third_party/rust/jobserver/tests/make-as-a-client.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/jobserver/tests/make-as-a-client.rs')
-rw-r--r--third_party/rust/jobserver/tests/make-as-a-client.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/third_party/rust/jobserver/tests/make-as-a-client.rs b/third_party/rust/jobserver/tests/make-as-a-client.rs
new file mode 100644
index 0000000000..4faac5b880
--- /dev/null
+++ b/third_party/rust/jobserver/tests/make-as-a-client.rs
@@ -0,0 +1,81 @@
+use std::env;
+use std::fs::File;
+use std::io::prelude::*;
+use std::net::{TcpListener, TcpStream};
+use std::process::Command;
+
+use jobserver::Client;
+
+macro_rules! t {
+ ($e:expr) => {
+ match $e {
+ Ok(e) => e,
+ Err(e) => panic!("{} failed with {}", stringify!($e), e),
+ }
+ };
+}
+
+fn main() {
+ if env::var("_DO_THE_TEST").is_ok() {
+ std::process::exit(
+ Command::new(env::var_os("MAKE").unwrap())
+ .env("MAKEFLAGS", env::var_os("CARGO_MAKEFLAGS").unwrap())
+ .env_remove("_DO_THE_TEST")
+ .args(&env::args_os().skip(1).collect::<Vec<_>>())
+ .status()
+ .unwrap()
+ .code()
+ .unwrap_or(1),
+ );
+ }
+
+ if let Ok(s) = env::var("TEST_ADDR") {
+ let mut contents = Vec::new();
+ t!(t!(TcpStream::connect(&s)).read_to_end(&mut contents));
+ return;
+ }
+
+ let c = t!(Client::new(1));
+ let td = tempfile::tempdir().unwrap();
+
+ let prog = env::var("MAKE").unwrap_or_else(|_| "make".to_string());
+
+ let me = t!(env::current_exe());
+ let me = me.to_str().unwrap();
+
+ let mut cmd = Command::new(&me);
+ cmd.current_dir(td.path());
+ cmd.env("MAKE", prog);
+ cmd.env("_DO_THE_TEST", "1");
+
+ t!(t!(File::create(td.path().join("Makefile"))).write_all(
+ format!(
+ "\
+all: foo bar
+foo:
+\t{0}
+bar:
+\t{0}
+",
+ me
+ )
+ .as_bytes()
+ ));
+
+ // We're leaking one extra token to `make` sort of violating the makefile
+ // jobserver protocol. It has the desired effect though.
+ c.configure(&mut cmd);
+
+ let listener = t!(TcpListener::bind("127.0.0.1:0"));
+ let addr = t!(listener.local_addr());
+ cmd.env("TEST_ADDR", addr.to_string());
+ let mut child = t!(cmd.spawn());
+
+ // We should get both connections as the two programs should be run
+ // concurrently.
+ let a = t!(listener.accept());
+ let b = t!(listener.accept());
+ drop((a, b));
+
+ assert!(t!(child.wait()).success());
+}