2 extern crate jobserver
;
5 extern crate tokio_core
;
6 extern crate tokio_process
;
11 use std
::process
::Command
;
13 use std
::sync
::atomic
::{AtomicBool, Ordering}
;
17 use futures
::future
::{self, Future}
;
18 use futures
::stream
::{self, Stream}
;
19 use jobserver
::Client
;
21 use tokio_core
::reactor
::Core
;
22 use tokio_process
::CommandExt
;
25 ($e
:expr
) => (match $e
{
27 Err(e
) => panic
!("{} failed with {}", stringify
!($e
), e
),
34 make_args
: &'
static [&'
static str],
35 rule
: &'
static Fn(&str) -> String
,
38 const TESTS
: &[Test
] = &[
42 rule
: &|me
| format
!("{}", me
),
44 assert
!(unsafe { Client::from_env().is_none() }
);
48 name
: "no j args with plus",
50 rule
: &|me
| format
!("+{}", me
),
52 assert
!(unsafe { Client::from_env().is_none() }
);
56 name
: "j args with plus",
58 rule
: &|me
| format
!("+{}", me
),
60 assert
!(unsafe { Client::from_env().is_some() }
);
66 rule
: &|me
| format
!("+{}", me
),
68 let c
= unsafe { Client::from_env().unwrap() }
;
69 drop(c
.acquire().unwrap());
70 drop(c
.acquire().unwrap());
76 rule
: &|me
| format
!("+{}", me
),
78 let c
= unsafe { Client::from_env().unwrap() }
;
79 let a
= c
.acquire().unwrap();
80 let b
= c
.acquire().unwrap();
85 name
: "acquire blocks",
87 rule
: &|me
| format
!("+{}", me
),
89 let c
= unsafe { Client::from_env().unwrap() }
;
90 let a
= c
.acquire().unwrap();
91 let hit
= Arc
::new(AtomicBool
::new(false));
92 let hit2
= hit
.clone();
93 let (tx
, rx
) = mpsc
::channel();
94 let t
= thread
::spawn(move || {
96 let _b
= c
.acquire().unwrap();
97 hit2
.store(true, Ordering
::SeqCst
);
100 assert
!(!hit
.load(Ordering
::SeqCst
));
103 assert
!(hit
.load(Ordering
::SeqCst
));
109 if let Ok(test
) = env
::var("TEST_TO_RUN") {
110 return (TESTS
.iter().find(|t
| t
.name
== test
).unwrap().f
)()
113 let me
= t
!(env
::current_exe());
114 let me
= me
.to_str().unwrap();
115 let filter
= env
::args().skip(1).next();
117 let mut core
= t
!(Core
::new());
118 let ref handle
= core
.handle();
120 let futures
= TESTS
.iter().filter(|test
| {
122 Some(ref s
) => test
.name
.contains(s
),
126 let td
= t
!(TempDir
::new("foo"));
127 let makefile
= format
!("\
128 all: export TEST_TO_RUN={}
131 ", test
.name
, (test
.rule
)(me
));
132 t
!(t
!(File
::create(td
.path().join("Makefile")))
133 .write_all(makefile
.as_bytes()));
134 let prog
= env
::var("MAKE").unwrap_or("make".to_string());
135 let mut cmd
= Command
::new(prog
);
136 cmd
.args(test
.make_args
);
137 cmd
.current_dir(td
.path());
138 future
::lazy(move || {
139 cmd
.output_async(&handle
).map(move |e
| {
144 }).collect
::<Vec
<_
>>();
146 println
!("\nrunning {} tests\n", futures
.len());
148 let stream
= stream
::iter(futures
.into_iter().map(Ok
))
149 .buffer_unordered(num_cpus
::get());
151 let mut failures
= Vec
::new();
152 t
!(core
.run(stream
.for_each(|(test
, output
)| {
153 if output
.status
.success() {
154 println
!("test {} ... ok", test
.name
);
156 println
!("test {} ... FAIL", test
.name
);
157 failures
.push((test
, output
));
162 if failures
.len() == 0 {
163 println
!("\ntest result: ok\n");
167 println
!("\n----------- failures");
169 for (test
, output
) in failures
{
170 println
!("test {}", test
.name
);
171 let stdout
= String
::from_utf8_lossy(&output
.stdout
);
172 let stderr
= String
::from_utf8_lossy(&output
.stderr
);
174 println
!("\texit status: {}", output
.status
);
175 if !stdout
.is_empty() {
176 println
!("\tstdout ===");
177 for line
in stdout
.lines() {
178 println
!("\t\t{}", line
);
182 if !stderr
.is_empty() {
183 println
!("\tstderr ===");
184 for line
in stderr
.lines() {
185 println
!("\t\t{}", line
);
190 std
::process
::exit(4);