Source code for simvx.core.testing.selftest
"""Exit codes for the headless self-checks examples run behind ``--test``.
Three outcomes, three codes::
0 the mechanic works
1 the mechanic is broken
2 this environment cannot answer the question
Without the third, an example that needs an optional package (or a device this
machine has not got) either fails as though the mechanic were broken or passes
as though the fallback it measured were the thing under test. Raise
:class:`Unsupported` from inside the check to say so, and let
:func:`run_selftest` turn it into the exit code::
def _selftest() -> bool:
...
if backend != "JoltPhysics":
raise Unsupported("install simvx-physics-jolt to check the Jolt half")
print("SELFTEST:", "PASS" if ok else "FAIL")
return ok
if "--test" in sys.argv:
sys.exit(run_selftest(_selftest))
Report the checks that DID run before raising: a check that ran on a fallback
still says something, and a failure among them is a genuine failure, so raise
only once nothing else has gone wrong.
"""
from collections.abc import Callable
__all__ = ["SELFTEST_FAIL", "SELFTEST_PASS", "SELFTEST_UNSUPPORTED", "Unsupported", "run_selftest"]
#: The self-check ran and every claim held.
SELFTEST_PASS = 0
#: The self-check ran and something it asserts is broken.
SELFTEST_FAIL = 1
#: The self-check could not run here: a capability it needs is absent.
SELFTEST_UNSUPPORTED = 2
[docs]
class Unsupported(Exception):
"""Raised by a self-check whose environment lacks a capability it needs.
The message says which capability, and how to get it where that is
actionable ("install simvx-physics-jolt"). It is not a failure: the
question was never put to the code under test.
"""
[docs]
def run_selftest(check: Callable[[], bool]) -> int:
"""Run *check* and return the process exit code for its outcome.
``SELFTEST_PASS`` when it returns true, ``SELFTEST_FAIL`` when it returns
false, ``SELFTEST_UNSUPPORTED`` when it raises :class:`Unsupported`. Any
other exception propagates: an unexpected traceback is a failure worth
seeing in full, not an exit code.
"""
try:
passed = check()
except Unsupported as exc:
print(f"SELFTEST: UNSUPPORTED ({exc})")
return SELFTEST_UNSUPPORTED
return SELFTEST_PASS if passed else SELFTEST_FAIL