@@ -11,13 +11,14 @@ use std::io::{self, BufWriter};
1111use  std:: net:: TcpStream ; 
1212use  std:: path:: { Path ,  PathBuf } ; 
1313use  std:: process:: { Command ,  Stdio } ; 
14- use  std:: time:: Duration ; 
14+ use  std:: time:: { Duration ,   Instant } ; 
1515use  std:: { env,  thread} ; 
1616
1717const  REMOTE_ADDR_ENV :  & str  = "TEST_DEVICE_ADDR" ; 
1818const  DEFAULT_ADDR :  & str  = "127.0.0.1:12345" ; 
1919
2020const  CONNECT_TIMEOUT_ENV :  & str  = "TEST_DEVICE_CONNECT_TIMEOUT_SECONDS" ; 
21+ /// The default timeout is high to not break slow CI or slow device starts. 
2122const  DEFAULT_CONNECT_TIMEOUT :  Duration  = Duration :: from_mins ( 30 ) ; 
2223
2324macro_rules!  t { 
@@ -59,6 +60,17 @@ fn main() {
5960    } 
6061} 
6162
63+ fn  connect_timeout ( )  -> Duration  { 
64+     match  env:: var ( CONNECT_TIMEOUT_ENV ) . ok ( )  { 
65+         Some ( timeout)  => timeout. parse ( ) . map ( Duration :: from_secs) . unwrap_or_else ( |e| { 
66+             panic ! ( 
67+                 "error: parsing `{CONNECT_TIMEOUT_ENV}` value \" {timeout}\"  as seconds failed: {e}" 
68+             ) 
69+         } ) , 
70+         None  => DEFAULT_CONNECT_TIMEOUT , 
71+     } 
72+ } 
73+ 
6274fn  spawn_emulator ( target :  & str ,  server :  & Path ,  tmpdir :  & Path ,  rootfs :  Option < PathBuf > )  { 
6375    let  device_address = env:: var ( REMOTE_ADDR_ENV ) . unwrap_or ( DEFAULT_ADDR . to_string ( ) ) ; 
6476
@@ -72,38 +84,27 @@ fn spawn_emulator(target: &str, server: &Path, tmpdir: &Path, rootfs: Option<Pat
7284    } 
7385
7486    // Wait for the emulator to come online 
75-     let  mut  total_dur = Duration :: from_secs ( 0 ) ; 
76-     let  timeout = env:: var ( CONNECT_TIMEOUT_ENV ) . ok ( ) . map_or ( DEFAULT_CONNECT_TIMEOUT ,  |timeout| { 
77-         let  seconds = timeout. parse :: < u64 > ( ) . unwrap_or_else ( |_| { 
78-             panic ! ( "The {CONNECT_TIMEOUT_ENV} env variable is not a valid integer" ) ; 
79-         } ) ; 
80-         Duration :: from_secs ( seconds) 
81-     } ) ; 
82- 
83-     let  mut  timed_out = true ; 
84- 
85-     while  total_dur < timeout { 
87+     let  timeout = connect_timeout ( ) ; 
88+     let  mut  successful_read = false ; 
89+     let  start_time = Instant :: now ( ) ; 
90+     while  start_time. elapsed ( )  < timeout { 
8691        let  dur = Duration :: from_millis ( 2000 ) ; 
8792        if  let  Ok ( mut  client)  = TcpStream :: connect ( & device_address)  { 
8893            t ! ( client. set_read_timeout( Some ( dur) ) ) ; 
8994            t ! ( client. set_write_timeout( Some ( dur) ) ) ; 
9095            if  client. write_all ( b"ping" ) . is_ok ( )  { 
9196                let  mut  b = [ 0 ;  4 ] ; 
9297                if  client. read_exact ( & mut  b) . is_ok ( )  { 
93-                     timed_out  = false ; 
98+                     successful_read  = true ; 
9499                    break ; 
95100                } 
96101            } 
97102        } 
98103        thread:: sleep ( dur) ; 
99-         total_dur += dur; 
100104    } 
101105
102-     if  timed_out { 
103-         panic ! ( 
104-             "Gave up trying to connect to test device at {device_address} after {} seconds" , 
105-             total_dur. as_secs( ) 
106-         ) ; 
106+     if  !successful_read { 
107+         panic ! ( "Gave up trying to connect to test device at {device_address} after {timeout:?}" ) ; 
107108    } 
108109} 
109110
0 commit comments