mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
run.sh drives every suite with -n auto and no scope, so xdist hands out single
test METHODS. Each worker is its own process, so setUpClass runs once per worker
the class happens to be scattered over, and an expensive fixture is paid as many
times as the scheduler split its methods.
The integration report shows the shape without interpretation:
TestMcpEnvRender's nine methods came back as six at 277-287s and three at
0.003s. The fast three landed on workers that had already paid. That is 1776 of
the suite's 2282 CPU-seconds spent computing one identical result six times,
twenty Ansible templar renders of the MCP providers each time.
--dist loadscope groups by class, so a class occupies one worker and its
fixture runs once.
1a908a6e5b introduced -n auto and hoisted fixtures in the same commit, so the
hoisting was undercut from the start: work moved from per-method to per-class,
and the scheduler it arrived with promptly charged it per worker instead. This
finishes that commit rather than correcting it.
Measured against the same tree, four suites, before and after:
integration 296.83s -> 219.32s
lint 105.64s -> 84.27s
unit 65.74s -> 53.02s
external 75.69s -> 71.99s
Phase 1's critical path drops from 4m57s to 3m40s. That unit and lint move too
says the pattern was not unique to the MCP class.
Coverage is unchanged, which is the point of the change rather than a side note.
All four suites report identical counts: unit 5857 passed / 9 skipped / 2301
subtests, external 19 / 2, lint 521 / 1 / 374, integration 328 / 2 / 1562.
A second effect is worth naming because it cuts the right way. Several sweeps
keep their non-empty guard in a separate method, e.g. test_fragments.py:139
proving the corpus is not empty before the sweep asserts over it. Under
--dist load those two ran in different processes with separate caches, so the
guard proved nothing about the process the sweep ran in. loadscope puts them
back together.
Residual: loadscope trades balance for locality, and here one class sets the
floor. TestMcpEnvRender holds a worker for ~250s on its own, so the suite cannot
go below that until the ~12s per render is addressed. That cost is the render
guard in utils/cache/applications.py:415 returning the merged map without
caching it, which is production config resolution and deliberately left alone.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
48 lines
2.1 KiB
Bash
Executable File
48 lines
2.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Runs the test suite picked by INFINITO_TEST_TYPE / INFINITO_TEST_PATTERN:
|
|
# parallel via pytest-xdist when pytest and xdist are importable, serial
|
|
# unittest discover otherwise. Invoked either directly on the host or
|
|
# inside the infinito compose container by scripts/tests/code/wrapper.sh
|
|
# -- the body is identical for both runners.
|
|
set -euo pipefail
|
|
|
|
_run_sh_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck source=scripts/meta/env/load.sh
|
|
source "${_run_sh_dir}/../../meta/env/load.sh"
|
|
unset _run_sh_dir
|
|
|
|
: "${INFINITO_TEST_PATTERN:?INFINITO_TEST_PATTERN must be set}"
|
|
: "${INFINITO_TEST_TYPE:?INFINITO_TEST_TYPE must be set}" # nocheck: makefile-supplied
|
|
|
|
echo "PWD=$(pwd)"
|
|
echo "PYTHON=${PYTHON:-<unset>}"
|
|
|
|
if [ -n "${PYTHON:-}" ]; then
|
|
PATH="$(dirname "$PYTHON"):$PATH"
|
|
export PATH
|
|
fi
|
|
|
|
make setup
|
|
bash "$(dirname "${BASH_SOURCE[0]}")/../../install/dev-extras.sh" || echo "dev extras install failed; running serial" >&2
|
|
_suite_dir="tests/${INFINITO_TEST_TYPE}" # nocheck: makefile-supplied
|
|
_junit_report="build/test-reports/${INFINITO_TEST_TYPE}.xml" # nocheck: makefile-supplied
|
|
if "${PYTHON}" -c 'import pytest, xdist' >/dev/null 2>&1; then
|
|
# Exception: consider_namespace_packages + importlib import mode are
|
|
# required for hyphenated tests/unit/python/roles/<role>/ dirs; pytest's default
|
|
# identifier walk-up collapses every role's filter_plugins/files package
|
|
# onto one top-level name and cross-imports the wrong module.
|
|
# python_functions= pins collection to unittest-style TestCase methods,
|
|
# the exact set `unittest discover` runs. PYTHONDONTWRITEBYTECODE keeps
|
|
# namespace probing from dropping __pycache__ into roles/.
|
|
mkdir -p build/test-reports
|
|
PYTHONDONTWRITEBYTECODE=1 "${PYTHON}" -m pytest "${_suite_dir}" -q -n auto --dist loadscope -rP -p no:cacheprovider \
|
|
--import-mode=importlib \
|
|
--junitxml="${_junit_report}" \
|
|
-o consider_namespace_packages=true \
|
|
-o "norecursedirs=.* *.egg dist node_modules venv" \
|
|
-o python_functions= \
|
|
-o "python_files=${INFINITO_TEST_PATTERN}"
|
|
else
|
|
"${PYTHON}" -m unittest discover -s "${_suite_dir}" -t . -p "${INFINITO_TEST_PATTERN}"
|
|
fi
|