docs,test: record the fourth managed_retry occurrence, and unblock the nested suite
**The gate's own run reproduced a REGISTERED signature**, and it is recorded as a fourth occurrence rather than waved through: same selector, same `gpu`-step flavor, all three required fragments verified against the durable log. Three isolated re-runs were green, which this file's rule says establishes intermittence only. **This lane is code-neutral for `pmacs-gpu` but NOT environment-neutral**, and that distinction is the entry's point. Occurrence 3 excluded "the added GPU test is the mechanism"; this occurrence adds nothing to that binary at all, which corroborates the exclusion independently. But the lane moves `TMPDIR` off `/tmp`, taking every `tempfile::tempdir()` in the run from **tmpfs to btrfs** --- and the failing test runs a handshake against a **one-second deadline**. A slower filesystem under a timing-bounded test is a plausible mechanism that did not exist in occurrences 1-3. Booking this as "the usual flake" when the observing lane changed the conditions the flake is sensitive to is exactly the reasoning this registry exists to prevent. Also: the suite's own roots move to a short base. Rooting them under the ambient `TMPDIR` put a NESTED gate's TMPDIR near 70 bytes, which legitimately tripped its own SUN_LEN guard --- the suite failing on a configuration it created rather than on the behaviour under test. And the marker row's `.then(..).unwrap_or_else(..)` chain is gone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai
This commit is contained in:
parent
1bd52b7f0d
commit
30e976ae1e
|
|
@ -496,7 +496,7 @@ Stage 4; the lane touches no `pmacs-gpu` code at all.
|
||||||
| **selector** | `-p pmacs-gpu attach::tests::managed_retry_survives_transients_and_uses_the_successful_stream` |
|
| **selector** | `-p pmacs-gpu attach::tests::managed_retry_survives_transients_and_uses_the_successful_stream` |
|
||||||
| **job / flavor** | local (Linux), `cargo test --workspace --features crdt --no-fail-fast`, i.e. under full-sweep load |
|
| **job / flavor** | local (Linux), `cargo test --workspace --features crdt --no-fail-fast`, i.e. under full-sweep load |
|
||||||
| **required fragments** | `transient sequence must attach` + `Handshake(Io(` + `BrokenPipe` (or `code: 32`) |
|
| **required fragments** | `transient sequence must attach` + `Handshake(Io(` + `BrokenPipe` (or `code: 32`) |
|
||||||
| **status** | **THIRD OCCURRENCE 2026-08-09 — causal status still UNRESOLVED, but one candidate mechanism is now EXCLUDED** |
|
| **status** | **FOURTH OCCURRENCE 2026-08-13 — causal status still UNRESOLVED. A NEW candidate mechanism is introduced by the observing lane and is NOT excluded (see below)** |
|
||||||
| **what IS established** | **three** occurrences at `pmacs-gpu/src/attach.rs:1680`, the second and third with all three fragments **verified** rather than inferred; the test drives a scripted transient-then-success sequence over a real socket pair. **The added GPU test is not the mechanism** — see the third-occurrence control below |
|
| **what IS established** | **three** occurrences at `pmacs-gpu/src/attach.rs:1680`, the second and third with all three fragments **verified** rather than inferred; the test drives a scripted transient-then-success sequence over a real socket pair. **The added GPU test is not the mechanism** — see the third-occurrence control below |
|
||||||
| **what is NOT** | whether the broken pipe is the *fixture's* writer closing early or a real retry-path defect. **This row is not a claim that it is harmless** |
|
| **what is NOT** | whether the broken pipe is the *fixture's* writer closing early or a real retry-path defect. **This row is not a claim that it is harmless** |
|
||||||
| **rerun evidence** | occurrence 1: 6 isolated runs green, plus a full `--workspace --features crdt` sweep green (113 targets). Occurrence 2: **30 green on the observing branch** (15 isolated selector, 15 full `-p pmacs-gpu`) **plus a 15-run merge-base control, also green**. Occurrence 3: 5 isolated selector runs green, 10 full `-p pmacs-gpu` runs green **with** the added test, and **1 failure in 10 with the added test `#[ignore]`d** — the first rerun in this row's history that reproduced anything. Per the rerun rule the green runs establish intermittence only; the red control run is what carries the exclusion |
|
| **rerun evidence** | occurrence 1: 6 isolated runs green, plus a full `--workspace --features crdt` sweep green (113 targets). Occurrence 2: **30 green on the observing branch** (15 isolated selector, 15 full `-p pmacs-gpu`) **plus a 15-run merge-base control, also green**. Occurrence 3: 5 isolated selector runs green, 10 full `-p pmacs-gpu` runs green **with** the added test, and **1 failure in 10 with the added test `#[ignore]`d** — the first rerun in this row's history that reproduced anything. Per the rerun rule the green runs establish intermittence only; the red control run is what carries the exclusion |
|
||||||
|
|
@ -537,6 +537,43 @@ one-second deadline. Contention is a plausible mechanism for a
|
||||||
lands, **run the control with the added test removed** rather than at the
|
lands, **run the control with the added test removed** rather than at the
|
||||||
merge base — that is the discriminating comparison this one was not.
|
merge base — that is the discriminating comparison this one was not.
|
||||||
|
|
||||||
|
**Fourth occurrence — the `scripts/gate` TMPDIR isolation lane,
|
||||||
|
2026-08-13, local (Linux). Same selector, same `gpu`-step flavor
|
||||||
|
(`PMACS_REQUIRE_GPU=1 cargo test -p pmacs-gpu`), all three fragments
|
||||||
|
verified** against the durable gate log
|
||||||
|
(`20260813T143421Z-708100/07-gpu.log`): `transient sequence must
|
||||||
|
attach: Attach(Handshake(Io(Os { code: 32, kind: BrokenPipe, message:
|
||||||
|
"Broken pipe" })))`.
|
||||||
|
|
||||||
|
**One thing this occurrence ESTABLISHES.** The observing lane touches
|
||||||
|
**no `pmacs-gpu` file at all** (`git diff ca92796..HEAD -- pmacs-gpu/`
|
||||||
|
is empty) and adds **no test to that binary**. Occurrence 3 excluded
|
||||||
|
"the added GPU test is the mechanism" by a control; this occurrence
|
||||||
|
reproduces the signature with *nothing added to the binary*, which is
|
||||||
|
independent corroboration rather than a repeat of the same argument.
|
||||||
|
|
||||||
|
**AND ONE THING IT INTRODUCES, NAMED RATHER THAN DISMISSED — the
|
||||||
|
observing lane is not environmentally neutral even though it is
|
||||||
|
code-neutral.** That lane moves the gate's `TMPDIR` off `/tmp`, which
|
||||||
|
on this machine changes the filesystem underneath every
|
||||||
|
`tempfile::tempdir()` in the run **from tmpfs to btrfs**. This test
|
||||||
|
creates a tempdir and runs a handshake against a **one-second
|
||||||
|
deadline** (`pmacs-gpu/src/attach.rs`). A slower filesystem under a
|
||||||
|
timing-bounded test, under full-sweep load, is a plausible mechanism
|
||||||
|
and **it did not exist in occurrences 1–3**.
|
||||||
|
|
||||||
|
It is not established either: the failing I/O is on a `UnixStream::pair`,
|
||||||
|
not on the tempdir path, and the tempdir is created but never bound.
|
||||||
|
**What this row must not do is book the occurrence as "the usual flake"
|
||||||
|
when the observing lane changed the very conditions the flake is
|
||||||
|
sensitive to.**
|
||||||
|
|
||||||
|
**The discriminating comparison for a fifth occurrence** is therefore
|
||||||
|
the same lane's gate run with `TMPDIR` pointed back at a tmpfs — the
|
||||||
|
one variable this lane moves — rather than another merge-base control.
|
||||||
|
Three isolated re-runs on the current tree were green, which by this
|
||||||
|
file's own rule establishes intermittence only.
|
||||||
|
|
||||||
**Third occurrence — worker identity Stage 1 review round 2,
|
**Third occurrence — worker identity Stage 1 review round 2,
|
||||||
2026-08-09, local (Linux). Same selector, same `gpu`-step flavor, all
|
2026-08-09, local (Linux). Same selector, same `gpu`-step flavor, all
|
||||||
three fragments verified** against the durable gate log
|
three fragments verified** against the durable gate log
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,26 @@ fn gate() -> PathBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run `scripts/gate` with an isolated managed root, from `cwd`.
|
/// Run `scripts/gate` with an isolated managed root, from `cwd`.
|
||||||
|
/// A SHORT base for the roots these tests hand the gate, independent of
|
||||||
|
/// the ambient `TMPDIR`.
|
||||||
|
///
|
||||||
|
/// **Not `tempfile::tempdir()`'s default, and the reason is the socket
|
||||||
|
/// budget rather than taste.** When this suite runs inside a gate, the
|
||||||
|
/// ambient `TMPDIR` is already that gate's own (~47 bytes); rooting a
|
||||||
|
/// nested gate under it pushes the nested `TMPDIR` to ~70 bytes and
|
||||||
|
/// legitimately trips its own `SUN_LEN` guard. The suite would then
|
||||||
|
/// fail on a configuration it created rather than on the behaviour
|
||||||
|
/// under test — which is exactly how it failed once.
|
||||||
|
///
|
||||||
|
/// `/tmp` is named explicitly because it is short and this suite
|
||||||
|
/// already requires a Unix environment. These roots hold synthetic
|
||||||
|
/// plans and never fixtures, so `/tmp`'s contents are irrelevant to
|
||||||
|
/// them; the rows set `PMACS_GATE_ALLOW_ANCESTOR_MARKER` for that
|
||||||
|
/// reason.
|
||||||
|
fn short_root_base() -> PathBuf {
|
||||||
|
PathBuf::from("/tmp")
|
||||||
|
}
|
||||||
|
|
||||||
fn run_in(cwd: &Path, root: &Path, args: &[&str]) -> (String, String, bool) {
|
fn run_in(cwd: &Path, root: &Path, args: &[&str]) -> (String, String, bool) {
|
||||||
let out = Command::new(gate())
|
let out = Command::new(gate())
|
||||||
.args(args)
|
.args(args)
|
||||||
|
|
@ -74,7 +94,10 @@ fn run(root: &Path, args: &[&str]) -> (String, String, bool) {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn the_plan_sweeps_the_workspace_and_never_only_the_tests() {
|
fn the_plan_sweeps_the_workspace_and_never_only_the_tests() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (plan, _, ok) = run(root.path(), &["--print-plan"]);
|
let (plan, _, ok) = run(root.path(), &["--print-plan"]);
|
||||||
assert!(ok, "--print-plan must succeed");
|
assert!(ok, "--print-plan must succeed");
|
||||||
|
|
||||||
|
|
@ -100,7 +123,10 @@ fn the_plan_sweeps_the_workspace_and_never_only_the_tests() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn the_plan_runs_the_library_tests_in_both_feature_configurations() {
|
fn the_plan_runs_the_library_tests_in_both_feature_configurations() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (plan, _, _) = run(root.path(), &["--print-plan"]);
|
let (plan, _, _) = run(root.path(), &["--print-plan"]);
|
||||||
assert!(plan.contains("cargo test --lib\n"), "plan was:\n{plan}");
|
assert!(plan.contains("cargo test --lib\n"), "plan was:\n{plan}");
|
||||||
assert!(
|
assert!(
|
||||||
|
|
@ -115,7 +141,10 @@ fn the_plan_runs_the_library_tests_in_both_feature_configurations() {
|
||||||
/// default one in place — and the default run must not carry it.
|
/// default one in place — and the default run must not carry it.
|
||||||
#[test]
|
#[test]
|
||||||
fn the_crdt_workspace_sweep_is_added_by_protocol_and_absent_without_it() {
|
fn the_crdt_workspace_sweep_is_added_by_protocol_and_absent_without_it() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let crdt_sweep = "cargo test --workspace --features crdt --no-fail-fast";
|
let crdt_sweep = "cargo test --workspace --features crdt --no-fail-fast";
|
||||||
|
|
||||||
let (default_plan, _, _) = run(root.path(), &["--print-plan"]);
|
let (default_plan, _, _) = run(root.path(), &["--print-plan"]);
|
||||||
|
|
@ -163,7 +192,10 @@ fn the_crdt_workspace_sweep_is_added_by_protocol_and_absent_without_it() {
|
||||||
/// below, which reads the plan in the form the runner reads it.
|
/// below, which reads the plan in the form the runner reads it.
|
||||||
#[test]
|
#[test]
|
||||||
fn the_crdt_sweep_is_immediately_preceded_by_the_build_that_produces_its_binary() {
|
fn the_crdt_sweep_is_immediately_preceded_by_the_build_that_produces_its_binary() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let build = "cargo build --workspace --no-default-features --features luajit,crdt";
|
let build = "cargo build --workspace --no-default-features --features luajit,crdt";
|
||||||
let crdt_sweep = "cargo test --workspace --features crdt --no-fail-fast -- --skip basedpyright";
|
let crdt_sweep = "cargo test --workspace --features crdt --no-fail-fast -- --skip basedpyright";
|
||||||
|
|
||||||
|
|
@ -230,7 +262,10 @@ fn the_crdt_sweep_is_immediately_preceded_by_the_build_that_produces_its_binary(
|
||||||
/// `--acceptance` refusal below exists to prevent.
|
/// `--acceptance` refusal below exists to prevent.
|
||||||
#[test]
|
#[test]
|
||||||
fn the_crdt_build_step_carries_its_own_name_and_its_exact_command() {
|
fn the_crdt_build_step_carries_its_own_name_and_its_exact_command() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let build = "build-crdt\tcargo build --workspace --no-default-features --features luajit,crdt";
|
let build = "build-crdt\tcargo build --workspace --no-default-features --features luajit,crdt";
|
||||||
let sweep =
|
let sweep =
|
||||||
"sweep-crdt\tcargo test --workspace --features crdt --no-fail-fast -- --skip basedpyright";
|
"sweep-crdt\tcargo test --workspace --features crdt --no-fail-fast -- --skip basedpyright";
|
||||||
|
|
@ -294,7 +329,10 @@ fn the_crdt_build_step_carries_its_own_name_and_its_exact_command() {
|
||||||
/// tab would silently run under an empty command.
|
/// tab would silently run under an empty command.
|
||||||
#[test]
|
#[test]
|
||||||
fn the_named_plan_is_the_printed_plan_with_its_names_removed() {
|
fn the_named_plan_is_the_printed_plan_with_its_names_removed() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
|
|
||||||
for flags in [
|
for flags in [
|
||||||
vec![],
|
vec![],
|
||||||
|
|
@ -346,7 +384,10 @@ fn the_named_plan_is_the_printed_plan_with_its_names_removed() {
|
||||||
/// every ordinary lane.
|
/// every ordinary lane.
|
||||||
#[test]
|
#[test]
|
||||||
fn the_crdt_build_is_absent_without_protocol() {
|
fn the_crdt_build_is_absent_without_protocol() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (plan, _, ok) = run(root.path(), &["--print-plan"]);
|
let (plan, _, ok) = run(root.path(), &["--print-plan"]);
|
||||||
assert!(ok, "--print-plan must succeed");
|
assert!(ok, "--print-plan must succeed");
|
||||||
assert!(
|
assert!(
|
||||||
|
|
@ -383,7 +424,10 @@ fn the_crdt_build_is_absent_without_protocol() {
|
||||||
/// the same defect the `--acceptance` refusal above exists to prevent.
|
/// the same defect the `--acceptance` refusal above exists to prevent.
|
||||||
#[test]
|
#[test]
|
||||||
fn self_test_names_the_failing_gate_and_the_suite_continues_past_it() {
|
fn self_test_names_the_failing_gate_and_the_suite_continues_past_it() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (out, err, ok) = run(root.path(), &["--self-test"]);
|
let (out, err, ok) = run(root.path(), &["--self-test"]);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
|
|
@ -455,7 +499,10 @@ fn self_test_names_the_failing_gate_and_the_suite_continues_past_it() {
|
||||||
/// reads a real child's environment out of a real gate log.
|
/// reads a real child's environment out of a real gate log.
|
||||||
#[test]
|
#[test]
|
||||||
fn the_isolated_tmpdir_reaches_a_spawned_child_under_the_managed_root() {
|
fn the_isolated_tmpdir_reaches_a_spawned_child_under_the_managed_root() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (out, err, _ok) = run(root.path(), &["--self-test"]);
|
let (out, err, _ok) = run(root.path(), &["--self-test"]);
|
||||||
|
|
||||||
let announced = out
|
let announced = out
|
||||||
|
|
@ -518,7 +565,10 @@ fn the_isolated_tmpdir_reaches_a_spawned_child_under_the_managed_root() {
|
||||||
/// created by the tool itself and on every single run.
|
/// created by the tool itself and on every single run.
|
||||||
#[test]
|
#[test]
|
||||||
fn the_isolated_tmpdir_is_reaped_when_the_run_ends() {
|
fn the_isolated_tmpdir_is_reaped_when_the_run_ends() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (out, _err, _ok) = run(root.path(), &["--self-test"]);
|
let (out, _err, _ok) = run(root.path(), &["--self-test"]);
|
||||||
|
|
||||||
let announced = out
|
let announced = out
|
||||||
|
|
@ -565,14 +615,8 @@ fn a_project_marker_above_the_gate_tmpdir_is_refused() {
|
||||||
// control what sits above the root, and `/tmp` may already carry a
|
// control what sits above the root, and `/tmp` may already carry a
|
||||||
// marker — which would make the row pass for the wrong reason.
|
// marker — which would make the row pass for the wrong reason.
|
||||||
let base = tempfile::Builder::new()
|
let base = tempfile::Builder::new()
|
||||||
.prefix("gate-marker-")
|
.prefix("gm-")
|
||||||
.tempdir_in(
|
.tempdir_in(short_root_base())
|
||||||
repo_root()
|
|
||||||
.join("target")
|
|
||||||
.exists()
|
|
||||||
.then(|| repo_root().join("target"))
|
|
||||||
.unwrap_or_else(std::env::temp_dir),
|
|
||||||
)
|
|
||||||
.expect("base");
|
.expect("base");
|
||||||
let root = base.path().join("inner");
|
let root = base.path().join("inner");
|
||||||
std::fs::create_dir_all(&root).expect("root");
|
std::fs::create_dir_all(&root).expect("root");
|
||||||
|
|
@ -607,7 +651,10 @@ fn a_project_marker_above_the_gate_tmpdir_is_refused() {
|
||||||
/// handed — each one, in order.
|
/// handed — each one, in order.
|
||||||
#[test]
|
#[test]
|
||||||
fn acceptance_suites_reach_the_plan_in_the_order_given() {
|
fn acceptance_suites_reach_the_plan_in_the_order_given() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (plan, _, _) = run(
|
let (plan, _, _) = run(
|
||||||
root.path(),
|
root.path(),
|
||||||
&[
|
&[
|
||||||
|
|
@ -634,7 +681,10 @@ fn acceptance_suites_reach_the_plan_in_the_order_given() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn printing_the_target_dir_creates_nothing() {
|
fn printing_the_target_dir_creates_nothing() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (dir, _, ok) = run(root.path(), &["--print-target-dir"]);
|
let (dir, _, ok) = run(root.path(), &["--print-target-dir"]);
|
||||||
assert!(ok, "--print-target-dir must succeed");
|
assert!(ok, "--print-target-dir must succeed");
|
||||||
assert!(!dir.trim().is_empty(), "it must print a path");
|
assert!(!dir.trim().is_empty(), "it must print a path");
|
||||||
|
|
@ -646,7 +696,10 @@ fn printing_the_target_dir_creates_nothing() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn init_writes_the_ownership_marker_and_is_idempotent() {
|
fn init_writes_the_ownership_marker_and_is_idempotent() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (dir, _, ok) = run(root.path(), &["--init"]);
|
let (dir, _, ok) = run(root.path(), &["--init"]);
|
||||||
assert!(ok, "--init must succeed");
|
assert!(ok, "--init must succeed");
|
||||||
let dir = PathBuf::from(dir.trim());
|
let dir = PathBuf::from(dir.trim());
|
||||||
|
|
@ -686,8 +739,14 @@ fn init_writes_the_ownership_marker_and_is_idempotent() {
|
||||||
/// belt-and-braces against git's behaviour not being contractual.
|
/// belt-and-braces against git's behaviour not being contractual.
|
||||||
#[test]
|
#[test]
|
||||||
fn a_symlinked_spelling_of_a_worktree_derives_the_same_directory() {
|
fn a_symlinked_spelling_of_a_worktree_derives_the_same_directory() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
let link_home = tempfile::tempdir().expect("tempdir");
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
|
let link_home = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let link = link_home.path().join("via-symlink");
|
let link = link_home.path().join("via-symlink");
|
||||||
if std::os::unix::fs::symlink(repo_root(), &link).is_err() {
|
if std::os::unix::fs::symlink(repo_root(), &link).is_err() {
|
||||||
return; // no symlink support; nothing to assert
|
return; // no symlink support; nothing to assert
|
||||||
|
|
@ -724,7 +783,10 @@ fn prune_fixture(root: &Path) -> (PathBuf, PathBuf, PathBuf) {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prune_is_a_dry_run_by_default_and_deletes_nothing() {
|
fn prune_is_a_dry_run_by_default_and_deletes_nothing() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (orphan, lookalike, live) = prune_fixture(root.path());
|
let (orphan, lookalike, live) = prune_fixture(root.path());
|
||||||
|
|
||||||
let (out, _, ok) = run(root.path(), &["--prune"]);
|
let (out, _, ok) = run(root.path(), &["--prune"]);
|
||||||
|
|
@ -741,7 +803,10 @@ fn prune_is_a_dry_run_by_default_and_deletes_nothing() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn force_deletes_only_the_orphan() {
|
fn force_deletes_only_the_orphan() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (orphan, lookalike, live) = prune_fixture(root.path());
|
let (orphan, lookalike, live) = prune_fixture(root.path());
|
||||||
|
|
||||||
let (out, _, ok) = run(root.path(), &["--prune", "--force"]);
|
let (out, _, ok) = run(root.path(), &["--prune", "--force"]);
|
||||||
|
|
@ -789,8 +854,14 @@ impl Drop for WorktreePruneGuard {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn a_registered_worktree_whose_directory_was_deleted_is_prunable() {
|
fn a_registered_worktree_whose_directory_was_deleted_is_prunable() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
let home = tempfile::tempdir().expect("tempdir");
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
|
let home = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let wt = home.path().join("gate-prunable-probe");
|
let wt = home.path().join("gate-prunable-probe");
|
||||||
|
|
||||||
let added = Command::new("git")
|
let added = Command::new("git")
|
||||||
|
|
@ -847,9 +918,15 @@ fn a_registered_worktree_whose_directory_was_deleted_is_prunable() {
|
||||||
/// grounds that no test noticed.
|
/// grounds that no test noticed.
|
||||||
#[test]
|
#[test]
|
||||||
fn prune_outside_a_repository_refuses_and_every_directory_survives() {
|
fn prune_outside_a_repository_refuses_and_every_directory_survives() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (orphan, lookalike, live) = prune_fixture(root.path());
|
let (orphan, lookalike, live) = prune_fixture(root.path());
|
||||||
let outside = tempfile::tempdir().expect("tempdir");
|
let outside = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
|
|
||||||
// Sanity: the fixture's orphan really is eligible from inside a repo.
|
// Sanity: the fixture's orphan really is eligible from inside a repo.
|
||||||
let (inside, _, _) = run(root.path(), &["--prune"]);
|
let (inside, _, _) = run(root.path(), &["--prune"]);
|
||||||
|
|
@ -879,7 +956,10 @@ fn prune_outside_a_repository_refuses_and_every_directory_survives() {
|
||||||
/// gate runs.
|
/// gate runs.
|
||||||
#[test]
|
#[test]
|
||||||
fn acceptance_names_with_shell_metacharacters_are_refused() {
|
fn acceptance_names_with_shell_metacharacters_are_refused() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let canary = root.path().join("canary");
|
let canary = root.path().join("canary");
|
||||||
std::fs::write(&canary, "intact").expect("write canary");
|
std::fs::write(&canary, "intact").expect("write canary");
|
||||||
|
|
||||||
|
|
@ -920,7 +1000,10 @@ fn acceptance_names_with_shell_metacharacters_are_refused() {
|
||||||
/// the test above by rejecting everything.
|
/// the test above by rejecting everything.
|
||||||
#[test]
|
#[test]
|
||||||
fn ordinary_acceptance_names_are_accepted() {
|
fn ordinary_acceptance_names_are_accepted() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
for name in ["m4_acceptance", "gate-script", "abc123_x"] {
|
for name in ["m4_acceptance", "gate-script", "abc123_x"] {
|
||||||
let (plan, err, ok) = run(root.path(), &["--acceptance", name, "--print-plan"]);
|
let (plan, err, ok) = run(root.path(), &["--acceptance", name, "--print-plan"]);
|
||||||
assert!(ok, "{name} must be accepted; stderr was:\n{err}");
|
assert!(ok, "{name} must be accepted; stderr was:\n{err}");
|
||||||
|
|
@ -936,7 +1019,10 @@ fn ordinary_acceptance_names_are_accepted() {
|
||||||
/// directory on the strength of a file the script did not understand.
|
/// directory on the strength of a file the script did not understand.
|
||||||
#[test]
|
#[test]
|
||||||
fn a_multi_line_marker_is_refused_rather_than_read_head_first() {
|
fn a_multi_line_marker_is_refused_rather_than_read_head_first() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let bad = root.path().join("bad-00000000");
|
let bad = root.path().join("bad-00000000");
|
||||||
std::fs::create_dir_all(&bad).expect("mkdir");
|
std::fs::create_dir_all(&bad).expect("mkdir");
|
||||||
std::fs::write(
|
std::fs::write(
|
||||||
|
|
@ -964,7 +1050,10 @@ fn a_multi_line_marker_is_refused_rather_than_read_head_first() {
|
||||||
/// is how one learns too late that the marker was never written.
|
/// is how one learns too late that the marker was never written.
|
||||||
#[test]
|
#[test]
|
||||||
fn skipped_directories_are_reported_with_a_reason() {
|
fn skipped_directories_are_reported_with_a_reason() {
|
||||||
let root = tempfile::tempdir().expect("tempdir");
|
let root = tempfile::Builder::new()
|
||||||
|
.prefix("g-")
|
||||||
|
.tempdir_in(short_root_base())
|
||||||
|
.expect("tempdir");
|
||||||
let (_, lookalike, _) = prune_fixture(root.path());
|
let (_, lookalike, _) = prune_fixture(root.path());
|
||||||
|
|
||||||
let (out, _, _) = run(root.path(), &["--prune"]);
|
let (out, _, _) = run(root.path(), &["--prune"]);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue