Skip to content

test(parser/compact): mark fuzz-heavy + lock-stress tests slow #100

test(parser/compact): mark fuzz-heavy + lock-stress tests slow

test(parser/compact): mark fuzz-heavy + lock-stress tests slow #100

Workflow file for this run

name: CI
on: [push, pull_request]
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
jobs:
lint:
runs-on: windows-2022
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
- run: uv python install 3.13
- run: uv sync --all-extras
- name: Lint
run: uv run ruff check
- name: Type check
run: uv run mypy src
test:
runs-on: windows-2022
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
- run: uv python install 3.13
- run: uv sync --all-extras
- name: Test
# ``-rfE`` prints short tracebacks for failures and errors at the
# end of the run so a CI failure surfaces the actual assertion or
# exception in the log without needing to download artefacts.
# ``--tb=short`` keeps each entry compact (one line per frame) so
# the summary stays readable even when several tests fail at once.
# ``TOKEN_GOAT_NO_WORKER_SPAWN=1`` suppresses the detached worker
# daemon spawn from ``worker.ensure_running()``. Under GitHub
# Actions on Windows the runner tracks every descendant via a
# Win32 job object, so the daemon's infinite loop holds the
# test step open until the global six-hour timeout fires. Tests
# still exercise the watchdog branch by reading the env var; only
# the actual ``subprocess.Popen`` is skipped.
env:
TOKEN_GOAT_NO_WORKER_SPAWN: "1"
# ``-m "not slow"`` excludes the opt-in stress tier (git-integration
# tests, multi-process concurrency tests). The slow tier is racy on
# the Windows runner's tmpdir under heavy IO and CI's already-stressed
# filesystem layer — pytest-rerunfailures only partially masks it.
# The fast tier still exercises the cross-process invariants via the
# threaded variant of each stress test (e.g. test_concurrent_threads
# _100_edits_no_loss covers the same lock-stack as its subprocess
# sibling, just without the subprocess.Popen pressure).
#
# ``-n 0`` forces serial execution, overriding the ``-n auto`` from
# pyproject.toml's addopts. The Windows-2022 GH Actions runner produces
# consistent xdist worker C-extension crashes under the current test-
# suite stress (``Windows fatal exception: access violation`` and
# ``code 0xc000001d`` ILLEGAL_INSTRUCTION) regardless of ``-n auto``
# or ``-n 2``. Serial execution eliminates the cross-worker contention
# that triggers the crashes; cost is ~10-15 min instead of 5, which is
# acceptable for a gating signal. Locally ``-n auto`` is still the
# default for the multi-core dev loop.
run: uv run pytest -n 0 -m "not slow" -rfE --tb=short
- name: Test (slow tier, allow-fail)
# The slow tier runs the multi-process concurrency tests and git
# integration tests. These are racy under Windows-Server-2022 + GitHub
# Actions and we don't want them to gate the build. ``continue-on-error``
# surfaces failures without blocking the run, so we still see what's
# happening but don't lose the entire build to a transient race.
continue-on-error: true
env:
TOKEN_GOAT_NO_WORKER_SPAWN: "1"
run: uv run pytest -m "slow" -rfE --tb=short
- name: Kill leftover detached worker daemons
# Several hook tests trigger ``worker.ensure_running()`` which
# spawns ``pythonw.exe -m token_goat.cli worker --daemon`` as a
# detached background process. ``DETACHED_PROCESS`` is honoured
# by Windows itself but GitHub Actions' Windows runner uses a
# Win32 job object to track every descendant; the daemon's
# infinite loop would otherwise hold the step open until the
# global six-hour timeout. This always-runs step terminates
# any leftover daemon so the runner can finish promptly.
if: always()
run: |
Get-CimInstance Win32_Process |
Where-Object { $_.CommandLine -like '*token_goat*worker*--daemon*' } |
ForEach-Object {
Write-Host "killing leftover worker pid=$($_.ProcessId)"
Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue
}