Merge the wilm delivery work into main
Ben Baker's installed-software collection, software delivery (run_script and
update_app), agentless adoption tool and command-queue hardening, with his
authorship preserved.
Reviewed before promotion. Fixed: the endpoints plugin tests were never collected
by pytest, the SBOM snapshot table's key would exhaust on MySQL, ingest did not
truncate two columns strict MySQL would reject, and update_app's version branch
pinned a digest for a file that route never serves. Agent packaging moved off
require_role('admin') onto a new endpoints.agentpackage permission.
Contract 0.27.0. Full suite 2231, frontend 314.
This commit is contained in:
50
tests/test_no_hidden_tests.py
Normal file
50
tests/test_no_hidden_tests.py
Normal file
@@ -0,0 +1,50 @@
|
||||
"""No test file may sit where pytest will not collect it.
|
||||
|
||||
pytest.ini sets `testpaths = tests`, so a test file anywhere else is never run
|
||||
by `pytest` and never run in CI. It still passes review, still gets maintained,
|
||||
and still reports nothing.
|
||||
|
||||
That is not hypothetical. plugins/endpoints/tests/test_plugin.py arrived with a
|
||||
merge carrying 55 lines of delivery assertions and was collected ZERO times; run
|
||||
directly, five of its tests failed. plugins/printedparts/tests/test_plugin.py had
|
||||
been sitting uncollected for longer. Both are now under tests/.
|
||||
|
||||
The failure mode is the worst kind: the suite is green, the coverage is imaginary,
|
||||
and the authorisation on a route can be deleted without anything going red.
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
REPO = Path(__file__).resolve().parents[1]
|
||||
|
||||
# Where pytest actually looks (pytest.ini: testpaths = tests).
|
||||
COLLECTED = REPO / 'tests'
|
||||
|
||||
# Trees that legitimately hold test-shaped files pytest must not collect:
|
||||
# vendored dependencies, build output, and the frontend's own vitest specs.
|
||||
IGNORED = ('node_modules', 'venv', '.git', 'dist', '__pycache__',
|
||||
'site-packages', '.plugins-staged', 'frontend')
|
||||
|
||||
# The Windows installer stages a whole copy of the app under here. It is build
|
||||
# output, not source, and the export excludes it - caught by this test on its
|
||||
# first run, which is the sort of thing the ignore list exists for.
|
||||
IGNORED_TREES = ('deploy/windows/installer/bundle',)
|
||||
|
||||
|
||||
def test_every_test_file_lives_where_pytest_looks():
|
||||
stray = []
|
||||
for path in REPO.rglob('test_*.py'):
|
||||
if any(part in IGNORED for part in path.parts):
|
||||
continue
|
||||
relative = path.relative_to(REPO).as_posix()
|
||||
if any(relative.startswith(tree) for tree in IGNORED_TREES):
|
||||
continue
|
||||
if COLLECTED in path.parents:
|
||||
continue
|
||||
stray.append(path.relative_to(REPO))
|
||||
|
||||
assert not stray, (
|
||||
'These test files are never collected, because pytest.ini limits\n'
|
||||
'collection to tests/. They pass review and report nothing:\n '
|
||||
+ '\n '.join(str(p) for p in sorted(stray))
|
||||
+ '\n\nMove them under tests/ (tests/test_plugins/ for plugin tests).'
|
||||
)
|
||||
Reference in New Issue
Block a user