Something went wrong. Try again.
atproto git client
Something went wrong. Try again.
Rust
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112//! `ATGC_GIT_LOG` — that it writes where it is pointed, and that `off` means//! off.//!//! Driven through the real binary because that is the only way to set the//! variable at all: `std::env::set_var` is unsafe and this crate forbids//! unsafe, so a unit test cannot put a value in the environment of its own//! process. `Command::env` on a *child* is neither unsafe nor shared, which//! is the same reason `tests/exit_status.rs` redirects `HOME` this way.//!//! What the log records once it is open is covered where it belongs, beside//! the runner that emits it (`clients/git/run.rs`). What is only checkable//! from out here is the switch.
use std::path::Path;use std::process::Command;
use tempfile::TempDir;
/// A git repository with no remote, and the process pointed at it.////// `pr list` in one runs git — `git remote get-url origin`, and the two/// narrowing questions behind the error it produces — and then stops, with/// no session read and no socket opened. That is the cheapest command in the/// tree that certainly spawns git.////// Built under a canonicalized temp root, so the repository's path has no/// symlinks in it and git's own answers about where it is agree with ours./// Deleted when the returned value drops.fn scratch_repo(name: &str) -> TempDir { let root = std::fs::canonicalize(std::env::temp_dir()).expect("a path with no symlinks in it"); let dir = tempfile::Builder::new() .prefix(&format!("atgc-gitlog-{name}-")) .tempdir_in(root) .expect("a temp directory"); let init = Command::new("git") .current_dir(dir.path()) .args(["init", "-q", "-b", "main"]) .status() .expect("git is a hard requirement of this suite"); assert!(init.success()); dir}
fn atgc_in(dir: &Path, log: &str, args: &[&str]) { let out = Command::new(env!("CARGO_BIN_EXE_atgc")) .current_dir(dir) .args(args) // Nothing here may read or write the real config directory. The two // other logs are switched off outright; this one is the subject. .env("HOME", "/nonexistent-atgc-test-home") .env("ATGC_OAUTH_LOG", "off") .env("ATGC_PDS_LOG", "off") .env("ATGC_GIT_LOG", log) .env("ATGC_NO_INPUT", "1") .env("NO_COLOR", "1") .output() .expect("spawn atgc"); // The command itself is expected to fail — there is no remote — and its // status is `exit_status.rs`'s subject, not this file's. let _ = out.status;}
/// Pointed at a path, the log lands there: the invocation head line, and a/// `spawn` for a git subprocess that really ran.#[test]fn the_variable_moves_the_log_and_a_subprocess_is_recorded() { let dir = scratch_repo("on"); let log = dir.path().join("elsewhere.jsonl"); atgc_in(dir.path(), &log.to_string_lossy(), &["pr", "list"]);
let text = std::fs::read_to_string(&log).expect("the log was written where it was pointed"); assert!( text.lines().any(|l| l.contains(r#""event":"invocation""#)), "{text}" ); let spawn = text .lines() .find(|l| l.contains(r#""event":"spawn""#)) .expect("a git subprocess was recorded"); assert!(spawn.contains(r#""event":"spawn""#)); // Every line carries the envelope the other two logs use, which is what // lets the three be read side by side. let parsed: serde_json::Value = serde_json::from_str(spawn).expect("a JSON line"); assert!(parsed["inv"].is_string()); assert!(parsed["ts"].is_string()); assert!(parsed["seq"].is_number()); assert!( text.lines().any(|l| l.contains(r#""event":"exit""#)), "a spawn is paired with an exit: {text}" );}
/// `off` means off: not an empty file, no file.////// The variable is checked before anything is opened, so a machine that has/// switched this log off pays neither the file nor the `HEAD` probes that go/// with it.#[test]fn off_really_disables_it() { let dir = scratch_repo("off"); let log = dir.path().join("elsewhere.jsonl"); for value in ["off", "0", ""] { let _ = std::fs::remove_file(&log); atgc_in(dir.path(), value, &["pr", "list"]); assert!( !log.exists(), "ATGC_GIT_LOG={value:?} still wrote {}", log.display() ); }}