22//! tests/cli-v2.rs
33
44use std:: cell:: RefCell ;
5- use std:: collections:: HashMap ;
65use std:: env:: consts:: EXE_SUFFIX ;
76use std:: env;
87use std:: fs:: { self , File } ;
98use std:: io:: { self , Read , Write } ;
109use std:: mem;
1110use std:: path:: { PathBuf , Path } ;
1211use std:: process:: { Command , Stdio } ;
13- use std:: sync:: { Arc , Mutex } ;
12+ use std:: sync:: Arc ;
1413use std:: time:: Duration ;
1514use tempdir:: TempDir ;
1615use { MockInstallerBuilder , MockFile , MockComponentBuilder } ;
@@ -565,10 +564,7 @@ fn build_mock_rustc_installer(target: &str, version: &str, version_hash_: &str)
565564 MockInstallerBuilder {
566565 components : vec ! [ MockComponentBuilder {
567566 name: "rustc" . to_string( ) ,
568- files: vec![
569- MockFile :: new_arc( format!( "bin/rustc{}" , EXE_SUFFIX ) ,
570- mock_bin( "rustc" , version, & version_hash) ) ,
571- ] ,
567+ files: mock_bin( "rustc" , version, & version_hash) ,
572568 } ] ,
573569 }
574570}
@@ -577,10 +573,7 @@ fn build_mock_cargo_installer(version: &str, version_hash: &str) -> MockInstalle
577573 MockInstallerBuilder {
578574 components : vec ! [ MockComponentBuilder {
579575 name: "cargo" . to_string( ) ,
580- files: vec![
581- MockFile :: new_arc( format!( "bin/cargo{}" , EXE_SUFFIX ) ,
582- mock_bin( "cargo" , version, & version_hash) ) ,
583- ] ,
576+ files: mock_bin( "cargo" , version, & version_hash) ,
584577 } ] ,
585578 }
586579}
@@ -589,10 +582,7 @@ fn build_mock_rls_installer(version: &str, version_hash: &str) -> MockInstallerB
589582 MockInstallerBuilder {
590583 components : vec ! [ MockComponentBuilder {
591584 name: "rls" . to_string( ) ,
592- files: vec![
593- MockFile :: new_arc( format!( "bin/rls{}" , EXE_SUFFIX ) ,
594- mock_bin( "rls" , version, & version_hash) ) ,
595- ] ,
585+ files: mock_bin( "rls" , version, version_hash) ,
596586 } ] ,
597587 }
598588}
@@ -640,112 +630,68 @@ fn build_combined_installer(components: &[&MockInstallerBuilder]) -> MockInstall
640630/// prints some version information. These binaries are stuffed into
641631/// the mock installers so we have executables for rustup to run.
642632///
643- /// This does a really crazy thing. Because we need to generate a lot
644- /// of these, and running rustc is slow, it does it once, stuffs the
645- /// bin into memory, then does a string replacement of the version
646- /// information it needs to report to create subsequent bins.
647- fn mock_bin ( _name : & str , version : & str , version_hash : & str ) -> Arc < Vec < u8 > > {
633+ /// To avoid compiling tons of files we globally cache one compiled executable
634+ /// and then we store some associated files next to it which indicate
635+ /// the version/version hash information.
636+ fn mock_bin ( name : & str , version : & str , version_hash : & str ) -> Vec < MockFile > {
648637 lazy_static ! {
649- static ref MOCK_BIN_TEMPLATE : Mutex <HashMap <( String , String ) , Arc <Vec <u8 >>>> =
650- Mutex :: new( HashMap :: new( ) ) ;
651- }
652-
653- let key = ( version. to_string ( ) , version_hash. to_string ( ) ) ;
654- let map = MOCK_BIN_TEMPLATE . lock ( ) . unwrap ( ) ;
655- if let Some ( ret) = map. get ( & key) {
656- return ret. clone ( )
657- }
658- drop ( map) ;
659-
660- struct Stderr ;
661- use std:: fmt:: { self , Write } ;
662-
663- impl fmt:: Write for Stderr {
664- fn write_str ( & mut self , s : & str ) -> fmt:: Result {
665- unsafe {
666- extern {
667- fn write ( a : i32 , b : * const u8 , c : usize ) -> isize ;
668- }
669- write ( 2 , s. as_ptr ( ) , s. len ( ) ) ;
670- Ok ( ( ) )
638+ static ref MOCK_BIN : Arc <Vec <u8 >> = {
639+ // Create a temp directory to hold the source and the output
640+ let ref tempdir = TempDir :: new( "rustup" ) . unwrap( ) ;
641+ let ref source_path = tempdir. path( ) . join( "in.rs" ) ;
642+ let ref dest_path = tempdir. path( ) . join( & format!( "out{}" , EXE_SUFFIX ) ) ;
643+
644+ // Write the source
645+ let source = include_str!( "mock_bin_src.rs" ) ;
646+ File :: create( source_path) . and_then( |mut f| f. write_all( source. as_bytes( ) ) ) . unwrap( ) ;
647+
648+ // Create the executable
649+ let status = Command :: new( "rustc" )
650+ . arg( & source_path)
651+ . arg( "-C" ) . arg( "panic=abort" )
652+ . arg( "-O" )
653+ . arg( "-o" ) . arg( & dest_path)
654+ . status( )
655+ . unwrap( ) ;
656+ assert!( status. success( ) ) ;
657+ assert!( dest_path. exists( ) ) ;
658+
659+ // If we're on unix this will remove debuginfo, otherwise we just ignore
660+ // the return result here
661+ if cfg!( unix) {
662+ drop( Command :: new( "strip" ) . arg( & dest_path) . status( ) ) ;
671663 }
672- }
673- }
674- drop ( write ! ( Stderr , "cache miss {:?}\n " , key) ) ;
675-
676- // Create a temp directory to hold the source and the output
677- let ref tempdir = TempDir :: new ( "rustup" ) . unwrap ( ) ;
678- let ref source_path = tempdir. path ( ) . join ( "in.rs" ) ;
679- let ref dest_path = tempdir. path ( ) . join ( & format ! ( "out{}" , EXE_SUFFIX ) ) ;
680-
681- // Write the source
682- let source = include_str ! ( "mock_bin_src.rs" ) ;
683- File :: create ( source_path) . and_then ( |mut f| f. write_all ( source. as_bytes ( ) ) ) . unwrap ( ) ;
684664
685- // Create the executable
686- let status = Command :: new ( "rustc" )
687- . arg ( & source_path)
688- . arg ( "-C" ) . arg ( "panic=abort" )
689- . arg ( "-O" )
690- . arg ( "-o" ) . arg ( & dest_path)
691- . env ( "EXAMPLE_VERSION" , version)
692- . env ( "EXAMPLE_VERSION_HASH" , version_hash)
693- . status ( )
694- . unwrap ( ) ;
695- assert ! ( status. success( ) ) ;
696- assert ! ( dest_path. exists( ) ) ;
665+ // Now load it into memory
666+ let mut f = File :: open( dest_path) . unwrap( ) ;
667+ let mut buf = Vec :: new( ) ;
668+ f. read_to_end( & mut buf) . unwrap( ) ;
697669
698- // If we're on unix this will remove debuginfo, otherwise we just ignore
699- // the return result here
700- if cfg ! ( unix) {
701- drop ( Command :: new ( "strip" ) . arg ( & dest_path) . status ( ) ) ;
670+ Arc :: new( buf)
671+ } ;
702672 }
703673
704- // Now load it into memory
705- let mut f = File :: open ( dest_path) . unwrap ( ) ;
706- let mut buf = Vec :: new ( ) ;
707- f. read_to_end ( & mut buf) . unwrap ( ) ;
708-
709- let buf = Arc :: new ( buf) ;
710- MOCK_BIN_TEMPLATE . lock ( ) . unwrap ( ) . insert ( key, buf. clone ( ) ) ;
711- return buf
674+ let name = format ! ( "bin/{}{}" , name, EXE_SUFFIX ) ;
675+ vec ! [
676+ MockFile :: new( format!( "{}.version" , name) , version. as_bytes( ) ) ,
677+ MockFile :: new( format!( "{}.version-hash" , name) , version_hash. as_bytes( ) ) ,
678+ MockFile :: new_arc( name, MOCK_BIN . clone( ) ) . executable( true ) ,
679+ ]
712680}
713681
714682// These are toolchains for installation with --link-local and --copy-local
715683fn create_custom_toolchains ( customdir : & Path ) {
716- let ref dir = customdir. join ( "custom-1/bin" ) ;
717- fs:: create_dir_all ( dir) . unwrap ( ) ;
718684 let ref libdir = customdir. join ( "custom-1/lib" ) ;
719685 fs:: create_dir_all ( libdir) . unwrap ( ) ;
720- let rustc = mock_bin ( "rustc" , "1.0.0" , "hash-c-1" ) ;
721- let ref path = customdir. join ( format ! ( "custom-1/bin/rustc{}" , EXE_SUFFIX ) ) ;
722- let mut file = File :: create ( path) . unwrap ( ) ;
723- file. write_all ( & rustc) . unwrap ( ) ;
724- make_exe ( dir, path) ;
725-
726- let ref dir = customdir. join ( "custom-2/bin" ) ;
727- fs:: create_dir_all ( dir) . unwrap ( ) ;
686+ for file in mock_bin ( "rustc" , "1.0.0" , "hash-c-1" ) {
687+ file. build ( & customdir. join ( "custom-1" ) ) ;
688+ }
689+
728690 let ref libdir = customdir. join ( "custom-2/lib" ) ;
729691 fs:: create_dir_all ( libdir) . unwrap ( ) ;
730- let rustc = mock_bin ( "rustc" , "1.0.0" , "hash-c-2" ) ;
731- let ref path = customdir. join ( format ! ( "custom-2/bin/rustc{}" , EXE_SUFFIX ) ) ;
732- let mut file = File :: create ( path) . unwrap ( ) ;
733- file. write_all ( & rustc) . unwrap ( ) ;
734- make_exe ( dir, path) ;
735-
736- #[ cfg( unix) ]
737- fn make_exe ( dir : & Path , bin : & Path ) {
738- use std:: os:: unix:: fs:: PermissionsExt ;
739- let mut perms = fs:: metadata ( dir) . unwrap ( ) . permissions ( ) ;
740- perms. set_mode ( 0o755 ) ;
741- fs:: set_permissions ( dir, perms) . unwrap ( ) ;
742- let mut perms = fs:: metadata ( bin) . unwrap ( ) . permissions ( ) ;
743- perms. set_mode ( 0o755 ) ;
744- fs:: set_permissions ( bin, perms) . unwrap ( ) ;
745- }
746-
747- #[ cfg( windows) ]
748- fn make_exe ( _: & Path , _: & Path ) { }
692+ for file in mock_bin ( "rustc" , "1.0.0" , "hash-c-2" ) {
693+ file. build ( & customdir. join ( "custom-2" ) ) ;
694+ }
749695}
750696
751697pub fn hard_link < A , B > ( a : A , b : B ) -> io:: Result < ( ) >
0 commit comments