@@ -14,28 +14,44 @@ use std::sync::Mutex;
1414static CARGO_INTEGRATION_TEST_DIR : & str = "cit" ;
1515
1616lazy_static ! {
17- pub static ref GLOBAL_ROOT : PathBuf = {
18- let mut path = t!( env:: current_exe( ) ) ;
19- path. pop( ) ; // chop off exe name
20- path. pop( ) ; // chop off 'debug'
21-
22- // If `cargo test` is run manually then our path looks like
23- // `target/debug/foo`, in which case our `path` is already pointing at
24- // `target`. If, however, `cargo test --target $target` is used then the
25- // output is `target/$target/debug/foo`, so our path is pointing at
26- // `target/$target`. Here we conditionally pop the `$target` name.
27- if path. file_name( ) . and_then( |s| s. to_str( ) ) != Some ( "target" ) {
28- path. pop( ) ;
29- }
30-
31- path. push( CARGO_INTEGRATION_TEST_DIR ) ;
32- path. mkdir_p( ) ;
33- path
34- } ;
17+ // TODO: Use `SyncOnceCell` when stable
18+ static ref GLOBAL_ROOT : Mutex <Option <PathBuf >> = Mutex :: new( None ) ;
3519
3620 static ref TEST_ROOTS : Mutex <HashMap <String , PathBuf >> = Default :: default ( ) ;
3721}
3822
23+ /// This is used when running cargo is pre-CARGO_TARGET_TMPDIR
24+ /// TODO: Remove when CARGO_TARGET_TMPDIR grows old enough.
25+ fn global_root_legacy ( ) -> PathBuf {
26+ let mut path = t ! ( env:: current_exe( ) ) ;
27+ path. pop ( ) ; // chop off exe name
28+ path. pop ( ) ; // chop off "deps"
29+ path. push ( "tmp" ) ;
30+ path. mkdir_p ( ) ;
31+ path
32+ }
33+
34+ fn set_global_root ( tmp_dir : Option < & ' static str > ) {
35+ let mut lock = GLOBAL_ROOT . lock ( ) . unwrap ( ) ;
36+ if lock. is_none ( ) {
37+ let mut root = match tmp_dir {
38+ Some ( tmp_dir) => PathBuf :: from ( tmp_dir) ,
39+ None => global_root_legacy ( ) ,
40+ } ;
41+
42+ root. push ( CARGO_INTEGRATION_TEST_DIR ) ;
43+ * lock = Some ( root) ;
44+ }
45+ }
46+
47+ pub fn global_root ( ) -> PathBuf {
48+ let lock = GLOBAL_ROOT . lock ( ) . unwrap ( ) ;
49+ match lock. as_ref ( ) {
50+ Some ( p) => p. clone ( ) ,
51+ None => unreachable ! ( "GLOBAL_ROOT not set yet" ) ,
52+ }
53+ }
54+
3955// We need to give each test a unique id. The test name could serve this
4056// purpose, but the `test` crate doesn't have a way to obtain the current test
4157// name.[*] Instead, we used the `cargo-test-macro` crate to automatically
@@ -52,14 +68,15 @@ pub struct TestIdGuard {
5268 _private : ( ) ,
5369}
5470
55- pub fn init_root ( ) -> TestIdGuard {
71+ pub fn init_root ( tmp_dir : Option < & ' static str > ) -> TestIdGuard {
5672 static NEXT_ID : AtomicUsize = AtomicUsize :: new ( 0 ) ;
5773
58- let id = NEXT_ID . fetch_add ( 1 , Ordering :: Relaxed ) ;
74+ let id = NEXT_ID . fetch_add ( 1 , Ordering :: SeqCst ) ;
5975 TEST_ID . with ( |n| * n. borrow_mut ( ) = Some ( id) ) ;
6076
6177 let guard = TestIdGuard { _private : ( ) } ;
6278
79+ set_global_root ( tmp_dir) ;
6380 let r = root ( ) ;
6481 r. rm_rf ( ) ;
6582 r. mkdir_p ( ) ;
@@ -80,7 +97,10 @@ pub fn root() -> PathBuf {
8097 order to be able to use the crate root.",
8198 )
8299 } ) ;
83- GLOBAL_ROOT . join ( & format ! ( "t{}" , id) )
100+
101+ let mut root = global_root ( ) ;
102+ root. push ( & format ! ( "t{}" , id) ) ;
103+ root
84104}
85105
86106pub fn home ( ) -> PathBuf {
0 commit comments