mod harness;
use harness::TestRepo;
#[cfg(unix)]
const SECRET: &[u8] = b"api_key = do-not-commit-me\n";
fn configured_repo() -> TestRepo {
let repo = TestRepo::init();
repo.init_xcrypt();
repo.write_xcrypt_config("*.env\nsecrets/\n");
repo
}
#[test]
fn the_filter_is_registered_for_the_long_running_protocol_only() {
let repo = configured_repo();
let process = repo.git_ok(["config", "--get", "filter.git-xcrypt.process"]);
assert!(
!process.stdout.is_empty(),
"filter.git-xcrypt.process is unset, so git runs one process per file — \
measured at 22x slower, which the catch-all construction cannot afford"
);
for per_file in ["filter.git-xcrypt.clean", "filter.git-xcrypt.smudge"] {
let output = repo.git(["config", "--get", per_file]);
assert!(
!output.status.success(),
"{per_file} is set; the product registers the long-running protocol \
and nothing else"
);
}
}
#[cfg(unix)]
#[test]
fn one_filter_process_serves_a_whole_operation() {
use std::os::unix::fs::PermissionsExt as _;
let repo = configured_repo();
let scratch = tempfile::TempDir::new().expect("could not create a temporary directory");
let tally = scratch.path().join("starts");
let wrapper = scratch.path().join("counting-filter");
std::fs::write(
&wrapper,
format!(
"#!/bin/sh\necho started >> {tally}\nexec {binary} process\n",
tally = tally.display(),
binary = env!("CARGO_BIN_EXE_git-xcrypt"),
),
)
.expect("could not write the wrapper");
std::fs::set_permissions(&wrapper, std::fs::Permissions::from_mode(0o755))
.expect("could not make the wrapper executable");
repo.git_ok([
"config",
"filter.git-xcrypt.process",
&wrapper.to_string_lossy(),
]);
const FILES: usize = 25;
for index in 0..FILES {
repo.write_file(&format!("secrets/file{index}.txt"), SECRET);
}
repo.commit_all("add many secrets");
for index in 0..FILES {
assert!(
repo.blob_bytes(&format!("secrets/file{index}.txt"))
.starts_with(b"\0GITXCRYPT\0"),
"file{index} was not encrypted, so the wrapper is not serving the filter"
);
}
let starts = std::fs::read_to_string(&tally)
.expect("the filter never started at all")
.lines()
.count();
assert!(
starts >= 1,
"the wrapper recorded no start, so this test is measuring nothing"
);
assert!(
starts < FILES,
"git started the filter {starts} times for {FILES} files: it is running \
one process per file, which was measured 22x slower and is the reason \
the long-running protocol is a hard requirement"
);
}