Skip to content

Tests write fixed filenames into the shared tempdir, so two suites on - #290

Merged
1-Bart-1 merged 1 commit into
mainfrom
agent/286-tests-write-fixed-filenames-into-the-sha
Sep 11, 2026
Merged

Tests write fixed filenames into the shared tempdir, so two suites on #290
1-Bart-1 merged 1 commit into
mainfrom
agent/286-tests-write-fixed-filenames-into-the-sha

Conversation

@1-Bort-1

@1-Bort-1 1-Bort-1 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

TL;DR

Four test files wrote fixed filenames straight into tempdir()/tmp when TMPDIR is unset, and so shared by every suite running on the box — where a second run's cleanup can land between one run's save and its isfile assertion. Each affected testset now opens its own mktempdir(), and the hand cleanup that existed only to keep that shared directory tidy goes with it.

What was wrong

tempdir() is one directory for the whole machine. The agent box runs several VortexStepMethod worktrees' suites at once, and they were all writing the same names into it: Rectangular_wing_geometry_*_view.png, Rectangular_Wing_Polars.png, test_polar.csv, test_wing.yaml, polars/, subtest/, test.obj, test.dat. Whoever ran second overwrote or deleted the first run's fixture, and the first run's next assertion failed.

The evidence for it being sharing rather than code is in #285's agent ci-local (Plotting (Makie) | 4 passed 1 failed 5 total, the failure being the angled_view.png isfile) plus the same commit passing 58/58 on the next run. GitHub CI never sees it: one suite per runner.

I reproduced the mechanism directly rather than by racing whole suites. Two threads, one writing test_load_polar_data.jl's "Valid CSV File" fixture and reading it straight back, one writing that file's "Empty CSV File" case, 400 rounds:

shared tempdir()  : 395 / 400 reads lost
per-run mktempdir : 0 / 400 reads lost

What changed

test/obj_adapter/, test/surfplan/ and test/airfoil_aero/ already do this, so the fix is to follow them: one mktempdir() per testset, every path built from it. Nothing about what the tests assert changes.

mktempdir() deletes itself at process exit, so every rm that existed only to keep /tmp tidy came out with it, and that is most of the diff:

  • test_plotting.jl's safe_rm helper — a two-attempt retry-and-swallow delete — and its 25 call sites. With no caller left the helper went too.
  • The try/finally around the save_plot tests. Its finally block had accumulated five of the eight tests, which therefore ran as cleanup: if test 3 threw, tests 4–8 ran anyway and the testset reported whatever they found. They are now plain sequential tests.
  • !isdir(nested_dir) && @test !isdir(nested_dir), written that way because the directory might hold a previous run's leftovers, is now the unconditional @test !isdir(nested_dir) it was meant to be.
  • cleanup_test_files() in both yaml_geometry tests, and the trailing rm(test_obj_path) / rm(test_dat_path) in test_kite_geometry.jl.

Two things I found on the way and folded in, both in files already open in this diff. test_kite_geometry.jl built its polar paths as joinpath(tempdir(), test_dat_path[1:end-4] * "_cl_polar.csv")test_dat_path is absolute, so joinpath discarded the prefix and the call did nothing; the path is now written directly. And test_kite_geometry.jl re-declared test_dat_path inside a nested testset with the value it already had.

Three of the four cp calls in test_wing_constructor.jl differed only in which airfoil and which name, so they are one loop over the two airfoils.

Where I would push back

/tmp on this box still holds test_cl_polar.csv, test_cd_polar.csv, test_cm_polar.csv and test_info.bin — files the old code never deleted at all, only overwrote. Their timestamps moved while I was working on this (00:22 → 00:33), and /tmp/test_polar.csv was deleted under me by somebody's cleanup_test_files(), so the collision is not hypothetical on this box. Those leftovers belong to the other worktrees' copies of these tests and will clear as this lands.

Left alone deliberately: test/test_data_utils.jl:164 also writes into tempdir(), but with a randstring(8) in the name, so two runs cannot collide there.

No changelog entry — nothing user-visible changes.

Verification

  • Reproduced first: shared tempdir() : 395 / 400 reads lost against per-run mktempdir : 0 / 400, two threads on the fixed path this suite uses
  • test/yaml_geometry/ + test/ram_geometry/ via runtests.jl (juliaserver): 199 pass, 1 broken (the pre-existing @test_skip), 0 fail, 31.4 s
  • After that run /tmp gained none of the fixed names — the test_c*_polar.csv sitting there belong to another worktree's copy of the unfixed test
  • All four files parse clean
  • agent ci-local: PASS in 7m — that is where test/plotting/test_plotting.jl ran, and where NONLIN misses the tolerances at 26.6° where LOOP converges #285 saw the failure. GitHub CI triggers on pull_request, so it starts when this PR opens
  • The plotting testset could not be run in the juliaserver session itself: it needs CairoMakie, a test/-only dependency, and this worktree has no test/Manifest-v1.12.toml (nor examples/), which §2 forbids me creating by hand
  • jetls check not run — jetls is not on this box
  • Docs: n/a, no public symbol changed · REUSE: n/a, repo has no bin/reuse_lint · up to date with origin/main (3f75701)
  • Risk: the save_plot tests now share one directory with the earlier plot_geometry/plot_polars saves instead of a dedicated one. The names do not overlap, and the xor(isfile(pdf), isfile(png)) check still starts from a directory holding neither test_backend_aware.pdf nor .png, but that assertion is the one to look at first if the plotting testset misbehaves.

Scope

+79 / −170 across 4 files, tests only. The net −91 is the deleted cleanup: safe_rm and its call sites, two cleanup_test_files helpers, and the try/finally that held five tests. No stack.

Closes #286 · task VortexStepMethod.jl-286

Five test files wrote fixed names straight into tempdir(), which is /tmp when
TMPDIR is unset and so shared by every suite on the machine. A second run's
cleanup landing between one run's save and its isfile assertion fails that
assertion. Each affected testset now opens a per-run mktempdir().

mktempdir() removes itself at process exit, so the hand cleanup that existed
only to keep the shared directory tidy goes with it: test_plotting.jl's safe_rm
helper and its call sites, the try/finally whose finally block had accumulated
five of the save_plot tests, and the cleanup_test_files helpers in the
yaml_geometry tests. test_plotting.jl's `!isdir(nested_dir) && @test
!isdir(nested_dir)` becomes an unconditional assertion.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014b7xG7wnJFW2vx2Ji5nwGW
@1-Bort-1 1-Bort-1 added agent:running Agent task state agent:ci Agent task state and removed agent:running Agent task state labels Sep 9, 2026
@1-Bort-1

1-Bort-1 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

Local full suite: PASS (8 min, Julia 1.12.7, one cell of the matrix)

@codecov

codecov Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@1-Bort-1 1-Bort-1 added agent:review Agent task state and removed agent:ci Agent task state labels Sep 9, 2026
@1-Bart-1
1-Bart-1 merged commit a20a27f into main Sep 11, 2026
9 checks passed
@1-Bart-1
1-Bart-1 deleted the agent/286-tests-write-fixed-filenames-into-the-sha branch September 11, 2026 20:40
@1-Bort-1 1-Bort-1 added agent:done Agent task state and removed agent:review Agent task state labels Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent:done Agent task state

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tests write fixed filenames into the shared tempdir, so two suites on

2 participants