diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8a3dd7fe..5010cd8a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -62,16 +62,8 @@ concurrency: cancel-in-progress: true jobs: - # ubuntu-24.04, NOT ubuntu-latest (#1096). The Ubuntu 26.04 that - # `ubuntu-latest` now gives out runs this suite out of disk: #1092's run of - # this job (job 119050702775, image `ubuntu-26.04` version 20261012.163.1) - # ended `2436 failed, 11382 passed, 380 skipped, 5579 errors in 3048.23s`, - # with 28325 lines of `[Errno 122] Disk quota exceeded`, and later `No space - # left on device`, all under pytest's basetemp in /tmp, - # `/tmp/pytest-of-runner/pytest-0`. The same job passed on 24.04. It stays - # on 24.04 until the suite runs on 26.04, which #1096 tracks. tests: - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest steps: # PINNED BY COMMIT, not by tag — the rule this repository spends a # whole README section on. A tag can be moved and a commit cannot. @@ -126,8 +118,37 @@ jobs: echo "GIT_COMMITTER_EMAIL=ci@openreposhape.invalid" } >> "$GITHUB_ENV" + # THE SUITE'S TEMPORARY FILES GO ON THE RUNNER'S DISK, NOT IN /tmp + # (#1096). On the Ubuntu 26.04 that `ubuntu-latest` now gives out, /tmp + # is a tmpfs of 7.9G, and the suite writes about 25G. #1092's run of + # this job (job 119050702775, image `ubuntu-26.04` 20261012.163.1) + # filled /tmp under pytest's default basetemp and ended `2436 failed, + # 11382 passed, 380 skipped, 5579 errors`, with 28325 lines of `Disk + # quota exceeded` and then `No space left on device`, all under + # `/tmp/pytest-of-runner/pytest-0`. With the basetemp below, #1097's + # round 3 (job 119263572144, `ubuntu-latest`, that same image) passed, + # and the `df` lines showed /tmp at 38M used before and after, and the + # runner's disk at 57G used before the suite and 83G after. + # + # So the basetemp is `$RUNNER_TEMP/pytest`, and `TMPDIR` is + # `runner.temp` for everything this step starts: `tests/conftest.py` + # points `TMPDIR` at `/tmpdir` once the session starts, and + # this one holds what is written before then and after, such as + # pytest's own capture files. `runner.temp` and NOT the workspace: + # the workspace is this checkout, a git work tree, and a test's folder + # inside it would be inside this repository for every git that looks + # upward from it. The `df` lines put the two filesystems' room in the + # log, before the suite and after it. - name: tests - run: python3 -m pytest tests -q + env: + TMPDIR: ${{ runner.temp }} + run: | + df -hT /tmp "$RUNNER_TEMP" + status=0 + python3 -m pytest tests -q \ + --basetemp="$RUNNER_TEMP/pytest" || status=$? + df -hT /tmp "$RUNNER_TEMP" + exit "$status" # PINNED, checksum-verified, no `go install`/`pip` package exists for # this: a static release binary downloaded straight from the tag this @@ -282,9 +303,9 @@ jobs: # build for setup-python: its manifest lists 3.10 to 3.15 there, and 3.8 to # 3.15 for 24.04. A run that landed on a 26.04 runner failed in setup-python # with `The version '3.9' with architecture 'x64' was not found for Ubuntu - # 26.04.` The `tests` job above is on ubuntu-24.04 too, for a reason of its - # own (#1096), and `tests-git-bash` runs on windows-latest. In release.yml, - # `build` asks for `3.12` on ubuntu-latest, which 26.04 has. + # 26.04.` The other jobs keep their runners: `tests` here asks for `3.x` + # and release.yml's `build` for `3.12` on ubuntu-latest, both of which + # 26.04 has, and `tests-git-bash` runs on windows-latest. package: runs-on: ubuntu-24.04 steps: diff --git a/tests/test_doctor_legs_members_next.py b/tests/test_doctor_legs_members_next.py index bd3749c8..f58480dd 100644 --- a/tests/test_doctor_legs_members_next.py +++ b/tests/test_doctor_legs_members_next.py @@ -34,7 +34,7 @@ ask `quote_arg` for it (`platform="nt"`, from any host) and compare the string; no test here pastes a line into `powershell`. A Windows-only test would not change that, because no job runs this file on Windows: `tests.yml` -runs the suite on ubuntu-24.04 alone (the macOS and Windows jobs were +runs the suite on ubuntu-latest alone (the macOS and Windows jobs were dropped, #597), and its one Windows job, `tests-git-bash`, runs three files of the launcher's and the installer's suites and no other. A `skipif(os.name != "nt")` test added here would be skipped by every runner diff --git a/tests/test_release_workflow.py b/tests/test_release_workflow.py index 956f613c..4606097a 100644 --- a/tests/test_release_workflow.py +++ b/tests/test_release_workflow.py @@ -596,18 +596,6 @@ def test_the_package_job_runs_its_python_3_9_on_ubuntu_24_04(): assert pythons == ["3.9"] -def test_the_tests_job_runs_the_suite_on_ubuntu_24_04(): - """#1096: `tests.yml`'s `tests` job runs the whole suite, and on the - Ubuntu 26.04 that `ubuntu-latest` now gives out it ended `2436 failed, - 11382 passed, 380 skipped, 5579 errors`, with `[Errno 122] Disk quota - exceeded` under pytest's basetemp in `/tmp` and `No space left on - device` after it. The job is pinned to 24.04, where it passed, until - the suite runs on 26.04; the change that moves it back takes this test - with it.""" - jobs = load_yaml(WORKFLOWS / "tests.yml")["jobs"] - assert jobs["tests"]["runs-on"] == "ubuntu-24.04" - - def setup_python_pairs(): """Every (file, job, runner, Python) a setup-python step of `tests.yml` or `release.yml` asks for, as text. A job with an `include` matrix @@ -658,6 +646,29 @@ def test_no_setup_python_on_ubuntu_latest_asks_for_a_python_26_04_lacks(): assert ("release.yml", "install", "ubuntu-24.04", "3.9") in pairs +def test_the_suite_keeps_its_temporary_files_on_the_runners_disk(): + """#1096: on the Ubuntu 26.04 that `ubuntu-latest` now gives out, the + whole suite filled `/tmp` under pytest's default basetemp (`Disk quota + exceeded`, then `No space left on device`) and ended `2436 failed, + 11382 passed, 380 skipped, 5579 errors`. `tests.yml`'s `tests` step + gives pytest a basetemp under `$RUNNER_TEMP`, on the runner's disk, and + sets `TMPDIR` to `runner.temp` for everything it starts, so nothing the + suite writes goes to `/tmp`. The step prints the room on both + filesystems after the suite as well, and still ends with the suite's + own exit status.""" + steps = load_yaml(WORKFLOWS / "tests.yml")["jobs"]["tests"]["steps"] + [step] = [step for step in steps if step.get("name") == "tests"] + assert step["env"] == {"TMPDIR": "${{ runner.temp }}"} + lines = commands(step["run"]) + assert lines == [ + 'df -hT /tmp "$RUNNER_TEMP"', + "status=0", + 'python3 -m pytest tests -q --basetemp="$RUNNER_TEMP/pytest" ' + "|| status=$?", + 'df -hT /tmp "$RUNNER_TEMP"', + 'exit "$status"'] + + def test_the_header_says_how_to_release(workflow): """The release notes (`docs/release-notes/v1.1.0.md` and `v1.1.1.md`) point at this header for the steps, so it carries them: Brett Heap's