plesty.server.model.field_test ============================== .. py:module:: plesty.server.model.field_test .. autoapi-nested-parse:: A device's field test: what to run, and what a run published. Every hub device scaffolded with ``plesty init field-test`` carries ``tests/field_test.py`` (the *host* tier — opens the instrument itself) and may carry ``tests/field_test_client.py`` (the *client* tier — talks to a running server). Both are the repository's own scripts, so they exist only in a git checkout, run with the checkout's interpreter, and publish ``reports//field-test.json`` (``field-test-client.json`` for the client tier) — the artifact ``hub.plesty.net`` and ``manager.plesty.net`` read. The markdown and JSONL beside it carry the address and serial and stay on the bench. This module is the data only: :class:`FieldTestRun` turns a request into the script's argument list, :class:`FieldTestReport` reads what a run published. Running it is a job (:mod:`plesty.server.services.jobs`); stopping the device server for a host-tier run and restarting it afterwards is the presenter's choreography. Attributes ---------- .. autoapisummary:: plesty.server.model.field_test.TIER_SCRIPTS plesty.server.model.field_test.TIER_ARTIFACTS plesty.server.model.field_test.REPORT_BASENAME plesty.server.model.field_test.JOB_KIND plesty.server.model.field_test.STANDARD_GATES Exceptions ---------- .. autoapisummary:: plesty.server.model.field_test.FieldTestError Classes ------- .. autoapisummary:: plesty.server.model.field_test.FieldTestRun plesty.server.model.field_test.GateResult plesty.server.model.field_test.FieldTestReport Functions --------- .. autoapisummary:: plesty.server.model.field_test.gates_in_help plesty.server.model.field_test.options_in_help plesty.server.model.field_test.field_test_script plesty.server.model.field_test.find_reports Module Contents --------------- .. py:data:: TIER_SCRIPTS :type: collections.abc.Mapping[str, str] .. py:data:: TIER_ARTIFACTS :type: collections.abc.Mapping[str, str] .. py:data:: REPORT_BASENAME :value: 'reports/field-test-run' .. py:data:: JOB_KIND :value: 'field-test' .. py:data:: STANDARD_GATES :type: tuple[str, Ellipsis] :value: ('discovery', 'connect_lifecycle', 'param_roundtrip', 'param_constraints', 'functions',... .. py:exception:: FieldTestError Bases: :py:obj:`plesty.server.model.errors.FleetError` A field test cannot be set up as asked. Initialize self. See help(type(self)) for accurate signature. .. py:function:: gates_in_help(text: str) -> tuple[str, Ellipsis] The gate names a script's ``--help`` offers for ``--gates``, in its order; empty if none. .. py:function:: options_in_help(text: str) -> set[str] The long options an argparse ``--help`` text mentions (``--address``, ``--mock`` …). .. py:function:: field_test_script(checkout: pathlib.Path, tier: str = 'host') -> pathlib.Path | None The *tier*'s script inside *checkout*, or ``None`` when the module has none. :raises FieldTestError: On an unknown tier. .. py:class:: FieldTestRun One field-test request. :ivar tier: ``host`` (instrument, server must be stopped) or ``client`` (running server). :ivar address: ``--address`` — host tier: instrument address or ``mock``; client tier: ``tcp://…``; ``None`` lets the script use ``.env``. :ivar gates: Run only these gates (``None`` = all). :ivar repetitions: ``--repetitions`` for the timing gates (``None`` = script default). :ivar keep_going: Carry on after a failed gate. :ivar keep_server: Host tier: leave a running server alone (only right for ``mock`` or another instrument). :ivar extra: Further arguments passed to the script unchanged. .. py:attribute:: tier :type: str :value: 'host' .. py:attribute:: address :type: str | None :value: None .. py:attribute:: gates :type: tuple[str, Ellipsis] | None :value: None .. py:attribute:: repetitions :type: int | None :value: None .. py:attribute:: keep_going :type: bool :value: False .. py:attribute:: keep_server :type: bool :value: False .. py:attribute:: extra :type: tuple[str, Ellipsis] :value: () .. py:method:: __post_init__() -> None Validate the request. .. py:property:: script :type: str The script this request runs, relative to the checkout. .. py:property:: artifact :type: str The published file name this tier writes. .. py:property:: needs_instrument :type: bool Whether the run opens the instrument itself (host tier, not ``mock``). .. py:method:: argv(report_base: str | None = REPORT_BASENAME, supports: collections.abc.Collection[str] | None = None) -> list[str] The script's arguments for this request. :param report_base: ``--report`` for the host tier's internal ``.md``/``.jsonl`` pair; ``None`` leaves it to the script. :param supports: The option names the script accepts (from its ``--help``), or ``None`` to assume the current scaffold. Older scaffolds take ``--port PORT`` and ``--mock`` where the current one takes ``--address``; the request is spelled in whichever the script understands, and options it lacks are left out. .. py:method:: command(python: pathlib.Path, checkout: pathlib.Path, supports: collections.abc.Collection[str] | None = None) -> list[str] The full command line: *python* running the tier's script in *checkout*. :param python: The checkout's interpreter. :param checkout: The module checkout. :param supports: The script's option names (see :meth:`argv`). :raises FieldTestError: When the checkout has no script for this tier. .. py:method:: to_dict() -> dict[str, Any] Record form (stored on the job's ``detail``). .. py:method:: from_dict(data: collections.abc.Mapping[str, Any]) -> FieldTestRun :classmethod: Rebuild a request from :meth:`to_dict` output. .. py:class:: GateResult One gate of a published report. .. py:attribute:: name :type: str .. py:attribute:: status :type: str .. py:attribute:: duration_s :type: float .. py:attribute:: reason :type: str .. py:class:: FieldTestReport What a field test published — the summary a bench needs, not the whole document. :ivar path: The ``field-test*.json`` file. :ivar tier: ``host`` or ``client``, from the file name. :ivar instrument: The ``reports//`` directory name. :ivar module: Module name from the document. :ivar version: Module version the run tested. :ivar ok: Overall outcome. :ivar passed: Gates passed. :ivar failed: Gates failed. :ivar skipped: Gates skipped. :ivar gates: Per-gate results, in run order. :ivar findings: Count of findings per severity (``error``/``warning``/``info``). :ivar modified_utc: ISO timestamp of the file — when the run ended. .. py:attribute:: path :type: pathlib.Path .. py:attribute:: tier :type: str .. py:attribute:: instrument :type: str .. py:attribute:: module :type: str .. py:attribute:: version :type: str .. py:attribute:: ok :type: bool .. py:attribute:: passed :type: int .. py:attribute:: failed :type: int .. py:attribute:: skipped :type: int .. py:attribute:: gates :type: tuple[GateResult, Ellipsis] :value: () .. py:attribute:: findings :type: collections.abc.Mapping[str, int] .. py:attribute:: modified_utc :type: str :value: '' .. py:property:: summary :type: str ``pm100d 0.2.1 [host] ok 9/9`` style. :type: One line .. py:method:: from_path(path: pathlib.Path) -> FieldTestReport :classmethod: Read a published report. :raises FieldTestError: When the file is not a field-test document. .. py:function:: find_reports(checkout: pathlib.Path, since_utc: str | None = None) -> list[FieldTestReport] Every published field-test report under ``/reports/``, newest first. :param checkout: The module checkout. :param since_utc: Only reports modified at or after this ISO timestamp — what a run that started then produced.