fn test_generate_hash_key()

in src/compiler/rust.rs [3363:3490]


    fn test_generate_hash_key(preprocessor_cache_mode: bool) {
        use ar::{Builder, Header};
        drop(env_logger::try_init());
        let f = TestFixture::new();
        const FAKE_DIGEST: &str = "abcd1234";
        const BAZ_O_SIZE: u64 = 1024;
        // We'll just use empty files for each of these.
        for s in ["foo.rs", "bar.rs", "bar.rlib"].iter() {
            f.touch(s).unwrap();
        }
        // libbaz.a needs to be a valid archive.
        create_file(f.tempdir.path(), "libbaz.a", |f| {
            let mut builder = Builder::new(f);
            let hdr = Header::new(b"baz.o".to_vec(), BAZ_O_SIZE);
            builder.append(&hdr, io::repeat(0).take(BAZ_O_SIZE))?;
            Ok(())
        })
        .unwrap();
        let mut m = Digest::new();
        m.update(b"baz.o");
        m.update(&vec![0; BAZ_O_SIZE as usize]);
        let libbaz_a_digest = m.finish();

        let mut emit = HashSet::new();
        emit.insert("link".to_string());
        emit.insert("metadata".to_string());
        let hasher = Box::new(RustHasher {
            executable: "rustc".into(),
            host: "x86-64-unknown-unknown-unknown".to_owned(),
            version: TEST_RUSTC_VERSION.to_string(),
            sysroot: f.tempdir.path().join("sysroot"),
            compiler_shlibs_digests: vec![FAKE_DIGEST.to_owned()],
            #[cfg(feature = "dist-client")]
            rlib_dep_reader: None,
            parsed_args: ParsedArguments {
                arguments: vec![
                    Argument::Raw("a".into()),
                    Argument::WithValue(
                        "--cfg",
                        ArgData::PassThrough("xyz".into()),
                        ArgDisposition::Separated,
                    ),
                    Argument::Raw("b".into()),
                    Argument::WithValue(
                        "--cfg",
                        ArgData::PassThrough("abc".into()),
                        ArgDisposition::Separated,
                    ),
                ],
                output_dir: "foo/".into(),
                externs: vec!["bar.rlib".into()],
                crate_link_paths: vec![],
                staticlibs: vec![f.tempdir.path().join("libbaz.a")],
                crate_name: "foo".into(),
                crate_types: CrateTypes {
                    rlib: true,
                    staticlib: false,
                },
                dep_info: None,
                emit,
                color_mode: ColorMode::Auto,
                has_json: false,
                profile: None,
                gcno: None,
                target_json: None,
            },
        });
        let creator = new_creator();
        mock_dep_info(&creator, &["foo.rs", "bar.rs"]);
        mock_file_names(&creator, &["foo.rlib", "foo.a"]);
        let runtime = single_threaded_runtime();
        let pool = runtime.handle().clone();
        let res = hasher
            .generate_hash_key(
                &creator,
                f.tempdir.path().to_owned(),
                [
                    (OsString::from("CARGO_PKG_NAME"), OsString::from("foo")),
                    (OsString::from("FOO"), OsString::from("bar")),
                    (OsString::from("CARGO_BLAH"), OsString::from("abc")),
                    (
                        OsString::from("CARGO_REGISTRIES_A_TOKEN"),
                        OsString::from("ignored"),
                    ),
                ]
                .to_vec(),
                false,
                &pool,
                false,
                Arc::new(MockStorage::new(None, preprocessor_cache_mode)),
                CacheControl::Default,
            )
            .wait()
            .unwrap();
        let m = Digest::new();
        let empty_digest = m.finish();

        let mut m = Digest::new();
        // Version.
        m.update(CACHE_VERSION);
        // sysroot shlibs digests.
        m.update(FAKE_DIGEST.as_bytes());
        // Arguments, with cfgs sorted at the end.
        OsStr::new("ab--cfgabc--cfgxyz").hash(&mut HashToDigest { digest: &mut m });
        // bar.rs (source file, from dep-info)
        m.update(empty_digest.as_bytes());
        // foo.rs (source file, from dep-info)
        m.update(empty_digest.as_bytes());
        // bar.rlib (extern crate, from externs)
        m.update(empty_digest.as_bytes());
        // libbaz.a (static library, from staticlibs), containing a single
        // file, baz.o, consisting of 1024 bytes of zeroes.
        m.update(libbaz_a_digest.as_bytes());
        // Env vars
        OsStr::new("CARGO_BLAH").hash(&mut HashToDigest { digest: &mut m });
        m.update(b"=");
        OsStr::new("abc").hash(&mut HashToDigest { digest: &mut m });
        OsStr::new("CARGO_PKG_NAME").hash(&mut HashToDigest { digest: &mut m });
        m.update(b"=");
        OsStr::new("foo").hash(&mut HashToDigest { digest: &mut m });
        f.tempdir.path().hash(&mut HashToDigest { digest: &mut m });
        TEST_RUSTC_VERSION.hash(&mut HashToDigest { digest: &mut m });
        let digest = m.finish();
        assert_eq!(res.key, digest);
        let mut out = res.compilation.outputs().map(|k| k.key).collect::<Vec<_>>();
        out.sort();
        assert_eq!(out, vec!["foo.a", "foo.rlib", "foo.rmeta"]);
    }