1 #[macro_use] 2 extern crate log; 3 extern crate env_logger; 4 5 use std::env; 6 use std::process; 7 use std::str; 8 use std::thread; 9 10 struct DropMe; 11 12 impl Drop for DropMe { drop(&mut self)13 fn drop(&mut self) { 14 debug!("Dropping now"); 15 } 16 } 17 run()18fn run() { 19 // Use multiple thread local values to increase the chance that our TLS 20 // value will get destroyed after the FORMATTER key in the library 21 thread_local! { 22 static DROP_ME_0: DropMe = DropMe; 23 static DROP_ME_1: DropMe = DropMe; 24 static DROP_ME_2: DropMe = DropMe; 25 static DROP_ME_3: DropMe = DropMe; 26 static DROP_ME_4: DropMe = DropMe; 27 static DROP_ME_5: DropMe = DropMe; 28 static DROP_ME_6: DropMe = DropMe; 29 static DROP_ME_7: DropMe = DropMe; 30 static DROP_ME_8: DropMe = DropMe; 31 static DROP_ME_9: DropMe = DropMe; 32 } 33 DROP_ME_0.with(|_| {}); 34 DROP_ME_1.with(|_| {}); 35 DROP_ME_2.with(|_| {}); 36 DROP_ME_3.with(|_| {}); 37 DROP_ME_4.with(|_| {}); 38 DROP_ME_5.with(|_| {}); 39 DROP_ME_6.with(|_| {}); 40 DROP_ME_7.with(|_| {}); 41 DROP_ME_8.with(|_| {}); 42 DROP_ME_9.with(|_| {}); 43 } 44 main()45fn main() { 46 env_logger::init(); 47 if env::var("YOU_ARE_TESTING_NOW").is_ok() { 48 // Run on a separate thread because TLS values on the main thread 49 // won't have their destructors run if pthread is used. 50 // https://doc.rust-lang.org/std/thread/struct.LocalKey.html#platform-specific-behavior 51 thread::spawn(run).join().unwrap(); 52 } else { 53 let exe = env::current_exe().unwrap(); 54 let out = process::Command::new(exe) 55 .env("YOU_ARE_TESTING_NOW", "1") 56 .env("RUST_LOG", "debug") 57 .output() 58 .unwrap_or_else(|e| panic!("Unable to start child process: {}", e)); 59 if !out.status.success() { 60 println!("test failed: {}", out.status); 61 println!("--- stdout\n{}", str::from_utf8(&out.stdout).unwrap()); 62 println!("--- stderr\n{}", str::from_utf8(&out.stderr).unwrap()); 63 process::exit(1); 64 } 65 } 66 } 67