fn local_clone_smoke_test()

in focus/operations/src/clone.rs [1163:1352]


    fn local_clone_smoke_test() -> Result<()> {
        init_logging();
        let fixture = RepoPairFixture::new()?;
        configure_ci_for_dense_repo(&fixture)?;

        let git_exe = fixture.app.git_binary();

        // Set up a remote that mimics source so that we can check that the setting of fetch and push URLs.
        git_exe
            .command()
            .arg("remote")
            .arg("add")
            .arg("origin")
            .arg("https://git.twitter.biz/focus-test-repo")
            .current_dir(&fixture.dense_repo_path)
            .assert()
            .success();

        // Make a branch that shouldn't end up in the sparse repo
        fixture
            .dense_repo
            .create_and_switch_to_branch("old_branch")?;
        fixture.dense_repo.make_empty_commit(
            "I'm too old to be in the sparse repo!",
            Some("Sun, Jan 27 22:32:18 2008"),
        )?;

        // Make a branch that should end up in the sparse repo.
        fixture
            .dense_repo
            .create_and_switch_to_branch("branch_two")?;
        fixture
            .dense_repo
            .make_empty_commit("I'm fresh and I should be in the sparse repo!", None)?;

        let app = Arc::new(App::new_for_testing()?);

        fixture.perform_clone().context("Clone failed")?;

        let git_repo = Repository::open(&fixture.sparse_repo_path)?;
        assert!(!git_repo.is_bare());

        // Check `focus.version` gets set
        assert_eq!(
            git_repo.config()?.snapshot()?.get_str("focus.version")?,
            env!("CARGO_PKG_VERSION")
        );

        // Check `twitter.statsenabled` gets set
        assert!(git_repo
            .config()?
            .snapshot()?
            .get_bool("twitter.statsenabled")?);

        // Check `ci.alt.enabled` gets set
        assert!(git_repo.config()?.snapshot()?.get_bool("ci.alt.enabled")?);

        // Check `ci.alt.remote` gets set
        assert_eq!(
            git_repo.config()?.snapshot()?.get_str("ci.alt.remote")?,
            "https://git.twitter.biz/focus-test-repo-ci"
        );

        // Check the remote URLs
        let origin_remote = git_repo.find_remote("origin")?;
        assert_eq!(
            origin_remote.url().unwrap(),
            "https://git.twitter.biz/ro/focus-test-repo"
        );
        assert_eq!(
            origin_remote.pushurl().unwrap(),
            "https://git.twitter.biz/focus-test-repo"
        );

        // Check branches
        let main_branch = git_repo
            .find_branch(MAIN_BRANCH_NAME, git2::BranchType::Local)
            .context("Failed to find main branch")?;
        let main_branch_commit_id = main_branch.get().peel_to_commit()?.id();

        for possible_branch in git_repo.branches(None)? {
            match possible_branch {
                Ok((branch, kind)) => {
                    info!("{:?} branch: {}", kind, branch.name().unwrap().unwrap());
                }
                Err(e) => {
                    bail!("Error enumerating local branches: {}", e);
                }
            }
        }

        git_repo
            .find_branch("branch_two", git2::BranchType::Local)
            .context("Failed to find branch_two")?;

        assert!(
            git_repo
                .find_branch("old_branch", git2::BranchType::Local)
                .is_err(),
            "old_branch was copied to sparse repo, despite being too old for the shallow window"
        );

        // Check post-merge hook
        let focus_exe = &std::env::current_exe().unwrap_or_else(|_| PathBuf::from("focus"));
        let focus_exe_path = focus_exe.file_name().unwrap().to_string_lossy();
        let post_merge_hook_contents =
            std::fs::read_to_string(git_repo.path().join("hooks").join("post-merge"))
                .expect("Something went wrong reading the file");
        assert_eq!(
            post_merge_hook_contents,
            format!("{} event post-merge\n", focus_exe_path)
        );

        // TODO: Test refspecs from remote config
        let model_repo = Repo::open(&fixture.sparse_repo_path, app)?;

        // Check sync point
        let sync_point_oid = model_repo
            .working_tree()
            .unwrap()
            .read_sparse_sync_point_ref()?
            .unwrap();
        assert_eq!(sync_point_oid, main_branch_commit_id);

        // Check tree contents
        {
            let outlining_tree = model_repo.outliner().unwrap();
            let outlining_tree_underlying = outlining_tree.underlying();
            let outlining_tree_path = outlining_tree_underlying.work_dir();
            let walker = walkdir::WalkDir::new(outlining_tree_path).follow_links(false);

            let outlining_tree_paths: HashSet<PathBuf> = walker
                .into_iter()
                .map(|m| {
                    m.unwrap()
                        .path()
                        .strip_prefix(outlining_tree_path)
                        .unwrap()
                        .to_owned()
                })
                .collect();

            assert!(outlining_tree_paths.contains(Path::new("focus")));
            assert!(outlining_tree_paths.contains(Path::new("WORKSPACE")));
            assert!(outlining_tree_paths.contains(Path::new("library_a/BUILD")));
            assert!(outlining_tree_paths.contains(Path::new("library_b/BUILD")));
            assert!(outlining_tree_paths.contains(Path::new(
                "project_a/src/main/java/com/example/cmdline/BUILD"
            )));
            assert!(outlining_tree_paths.contains(Path::new(
                "project_b/src/main/java/com/example/cmdline/BUILD"
            )));
            assert!(outlining_tree_paths.contains(Path::new("mandatory_z/BUILD")));
        }

        {
            let working_tree = model_repo.working_tree().unwrap();
            let working_tree_path = working_tree.work_dir();
            let walker = walkdir::WalkDir::new(working_tree_path).follow_links(false);
            let working_tree_paths: HashSet<PathBuf> = walker
                .into_iter()
                .map(|m| {
                    m.unwrap()
                        .path()
                        .strip_prefix(working_tree_path)
                        .unwrap()
                        .to_owned()
                })
                .collect();

            // N.B. Only the mandatory project is checked out
            assert!(working_tree_paths.contains(Path::new("focus")));
            assert!(working_tree_paths.contains(Path::new("mandatory_z")));
            assert!(working_tree_paths.contains(Path::new("mandatory_z/BUILD")));
            assert!(working_tree_paths.contains(Path::new("mandatory_z/quotes.txt")));

            assert!(!working_tree_paths.contains(Path::new("library_a/BUILD")));
            assert!(!working_tree_paths.contains(Path::new("library_b/BUILD")));
            assert!(!working_tree_paths.contains(Path::new("library_a/BUILD")));
            assert!(!working_tree_paths.contains(Path::new("library_a/BUILD")));
            assert!(!working_tree_paths.contains(Path::new(
                "project_a/src/main/java/com/example/cmdline/BUILD"
            )));
            assert!(!working_tree_paths.contains(Path::new(
                "project_b/src/main/java/com/example/cmdline/BUILD"
            )));
        }

        Ok(())
    }