@@ -61,6 +61,48 @@ pub type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error + Sen
6161/// This is useful for computing values based on the fixture contents.
6262pub type PostResult < T = ( ) > = std:: result:: Result < T , Box < dyn std:: error:: Error + Send + Sync > > ;
6363
64+ /// Build `example` from `package` and copy the executable to this test process' temporary target directory.
65+ ///
66+ /// The returned executable path is stable for the lifetime of the test process and avoids races with other
67+ /// concurrently running tests that may cause Cargo to update the shared example binary in `target/debug/examples`.
68+ pub fn build_example_for_test ( package : & str , example : & str , target_tmpdir : impl Into < PathBuf > ) -> PathBuf {
69+ let mut cargo = std:: process:: Command :: new ( env:: var_os ( "CARGO" ) . unwrap_or_else ( || OsString :: from ( env ! ( "CARGO" ) ) ) ) ;
70+ let res = cargo
71+ . args ( [ "build" , "-p" , package, "--example" , example] )
72+ . status ( )
73+ . expect ( "cargo should run fine" ) ;
74+ assert ! ( res. success( ) , "cargo invocation should be successful" ) ;
75+
76+ let target_tmpdir = target_tmpdir. into ( ) ;
77+ let shared_path = target_tmpdir
78+ . ancestors ( )
79+ . nth ( 1 )
80+ . expect ( "first parent in target dir" )
81+ . join ( "debug" )
82+ . join ( "examples" )
83+ . join ( format ! ( "{example}{}" , std:: env:: consts:: EXE_SUFFIX ) ) ;
84+
85+ let stable_path = target_tmpdir. join ( format ! (
86+ "{example}-{}{}" ,
87+ std:: process:: id( ) ,
88+ std:: env:: consts:: EXE_SUFFIX
89+ ) ) ;
90+ let mut last_err = None ;
91+ for _ in 0 ..10 {
92+ match std:: fs:: copy ( & shared_path, & stable_path) {
93+ Ok ( _) => return stable_path,
94+ Err ( err) => {
95+ last_err = Some ( err) ;
96+ std:: thread:: sleep ( Duration :: from_millis ( 50 ) ) ;
97+ }
98+ }
99+ }
100+ panic ! (
101+ "driver at {} could be copied for stable test execution: {last_err:?}" ,
102+ shared_path. display( )
103+ ) ;
104+ }
105+
64106/// Indicates the state of a fixture when a closure is called.
65107#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
66108pub enum FixtureState < ' a > {
0 commit comments