use super::*;
#[cfg(unix)]
fn shell(script: &str) -> Command {
let mut command: Command = Command::new("sh");
command.arg("-c").arg(script);
return command;
}
#[test]
fn the_query_deadline_follows_the_push_deadline_up_to_the_ceiling() {
let set = |value: &str| -> Vec<(OsString, OsString)> {
return vec![(
OsString::from(crate::bounded_push::PUSH_DEADLINE_VARIABLE),
OsString::from(value),
)];
};
assert_eq!(query_deadline(&[]), QUERY_CEILING);
assert_eq!(query_deadline(&set("7")), Duration::from_secs(7));
assert_eq!(query_deadline(&set("120")), Duration::from_secs(120));
assert_eq!(query_deadline(&set("3600")), QUERY_CEILING);
}
#[cfg(unix)]
#[test]
fn a_finished_query_keeps_code_and_streams_apart() {
let output: QueryOutput = run_bounded_query(
shell("echo out; echo err >&2; exit 3"),
"fixture",
Duration::from_secs(60),
Duration::from_secs(1),
)
.expect("runs");
assert_eq!(
output,
QueryOutput {
code: Some(3),
stdout: b"out\n".to_vec(),
stderr: b"err\n".to_vec(),
}
);
}
#[cfg(unix)]
#[test]
fn a_query_ended_by_a_signal_has_no_code() {
let output: QueryOutput = run_bounded_query(
shell("kill -9 $$"),
"fixture",
Duration::from_secs(60),
Duration::from_secs(1),
)
.expect("runs");
assert_eq!(output.code, None);
}
#[cfg(unix)]
#[test]
fn a_stalled_query_is_stopped_and_reported() {
let started = std::time::Instant::now();
let failure: SingleFlightError = run_bounded_query(
shell("exec sleep 8"),
"rev-parse HEAD",
Duration::from_millis(300),
Duration::from_secs(5),
)
.expect_err("stalls");
assert!(started.elapsed() >= Duration::from_millis(300), "{:?}", started.elapsed());
assert!(started.elapsed() < Duration::from_secs(7), "{:?}", started.elapsed());
match &failure {
SingleFlightError::TimedOut { arguments, seconds } => {
assert_eq!(arguments, "rev-parse HEAD");
assert_eq!(*seconds, 0);
}
other => panic!("expected a timeout, got {other}"),
}
assert!(
failure
.to_string()
.starts_with("git rev-parse HEAD did not finish within 0 seconds and was stopped; CLI_GIT_PUSH_DEADLINE_SECONDS"),
"{failure}"
);
}
#[cfg(unix)]
#[test]
fn a_flooding_query_is_stopped() {
for script in [
"head -c 20000000 /dev/zero; exec sleep 8",
"head -c 20000000 /dev/zero >&2; exec sleep 8",
] {
let failure: SingleFlightError = run_bounded_query(
shell(script),
"log",
Duration::from_secs(60),
Duration::from_secs(5),
)
.expect_err("floods");
match &failure {
SingleFlightError::Git { arguments, code, stderr } => {
assert_eq!(arguments, "log");
assert_eq!(*code, None);
assert!(stderr.contains("bytes and was stopped"), "{stderr}");
}
other => panic!("expected a Git failure, got {other}"),
}
}
}
#[test]
fn a_program_that_cannot_start_is_a_start_failure() {
let failure: SingleFlightError = run_bounded_query(
Command::new("/nonexistent/cli-git-query-fixture"),
"x",
Duration::from_secs(5),
Duration::from_secs(1),
)
.expect_err("no such program");
assert!(matches!(failure, SingleFlightError::Start(_)), "{failure}");
}