Skip to content

Test suites share fixed files under /tmp, so they fail intermittently when run at the same time #2271

Closed

Description

@don-petry

Problem

tests/dev-lead/unit/test_budget_breaker.bats (and any other suite that drives the real posting functions) writes to two fixed paths, /tmp/dev-lead-rate-limit-reset and /tmp/dev-lead-failure-reason. Any other test session on the same machine writes to them too. When suites run concurrently, one session's value leaks into another's assertion and a test fails for a reason unrelated to the code under test.

Observed 2026-10-11 while several bats sessions ran at once: tests 19, 24 and 30 of that file failed intermittently, on unmodified main as well, and passed every time when run alone. CI runs one session per job, so it has not shown up there, but a retry would hide it rather than fix it.

Scope

Make the sidecar paths overridable through an environment variable with the current paths as the default, so production behaviour is unchanged, and have the test suites point them into $BATS_TEST_TMPDIR.

Acceptance criteria

  1. No test in the repository reads or writes a fixed path under /tmp that another test also uses; a static check lists the paths and fails on a new shared one.
  2. Running the affected suites concurrently, several times, produces no failure.
  3. Production scripts behave exactly as before when the variable is unset.

Activity

  1. github-actions commented on Oct 11, 2026

    @github-actions
    Contributor

    Thanks for the detailed report and for narrowing this down to the shared /tmp sidecar paths. The scope and acceptance criteria are clear. One question to help us confirm the fix: besides tests/dev-lead/unit/test_budget_breaker.bats, which other suites have you seen fail or that you know write to those fixed paths, and what command did you use to run them concurrently?

  2. don-petry commented on Oct 11, 2026

    @don-petry
    CollaboratorAuthor

    Part 1 is up as #2296. The survey behind it found the problem is wider than this issue says, so the scope here should read as follows.

    • Six sidecar files, not two: the rate-limit reset, the failure reason, three timeout files (tier, budget, elapsed) and dev-lead-session-output.txt. The session log is the most exposed: test_fix_reviews.bats seeds it and then asserts on its absence.
    • 19 suites reach the writers, 11 of them without naming a path (found by logging every default-path resolution across a full run of 240 bats files).
    • Five suites use a fixed directory under $BATS_TMPDIR, which is /tmp for every session.
    • Under deliberate interference, tests 18 and 22 of test_budget_breaker.bats fail as well as 19, 24 and 30.

    Answering the triage question: the concurrent command was four bats sessions in four separate clones over 25 suites; the deterministic reproduction is a background loop writing garbage to the default paths while one suite runs (main: 5, 8 and 2 failures in test_budget_breaker, test_engine_fallback, test_engine_writer).

    What stays open after part 1:

    1. Part 2: move dev-lead-session-output.txt under the same variable. Written and tested locally; held until "fix(tests): make every negated bats assertion able to fail" (fix(tests): make every negated bats assertion able to fail, and lint for new ones (#2263) #2264) merges, because it rewrites the same lines of test_engine_writer.bats.
    2. /tmp/cascade in scripts/review-one-pr.sh (57 fixed references). pr-review.yml uploads that directory and a prompt names it to the model, so it needs a change on all three sides, not a variable in the script. It has an exception row marked "NOT isolated yet". This should probably be its own issue once part 2 lands.
  3. don-petry commented on Oct 11, 2026

    @don-petry
    CollaboratorAuthor

    dev-lead is withholding action on this item.

    It is labeled dev-lead:hands-off (deliberately kept off-limits to dev-lead (e.g. changes to the dev-lead automation itself)), so dev-lead will not pick it up while that label is present. This notice is posted once so the withhold is visible rather than looking like a stalled run.

    To re-enable automated pickup: remove the dev-lead:hands-off label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug reportsdev-lead:hands-offExclude from dev-lead agent automation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions