plesty.lib.test.experiment_pipeline

Standard experiment contract test pipeline for PLESTY experiment modules.

Import ExperimentPipeline in an experiment module’s test suite and call the individual gate methods from pytest test functions, or call run_mock_pipeline() to run all gates in one shot. No hardware is needed: the pipeline never calls run() — it validates the plan/checkpoint contract defined by plesty.lib.experiment.Experiment.

Typical usage in an experiment module:

# tests/test_pipeline.py
from plesty.lib.test.experiment_pipeline import ExperimentPipeline

PIPELINE = ExperimentPipeline(MyExperiment)

def test_experiment_subclass():
    PIPELINE.test_experiment_subclass()

def test_plan_deterministic():
    PIPELINE.test_plan_deterministic()

def test_plan_ops_resolve():
    PIPELINE.test_plan_ops_resolve()

def test_plan_serializable():
    PIPELINE.test_plan_serializable()

def test_lifecycle_hooks():
    PIPELINE.test_lifecycle_hooks()

Gate summary

  • Gate 1 test_experiment_subclass — public Experiment subclass, instantiable without devices.

  • Gate 2 test_plan_deterministicbuild_plan() twice yields an identical content_hash().

  • Gate 3 test_plan_ops_resolve — every Step.op resolves to a public callable.

  • Gate 4 test_plan_serializablePlan.save/load round-trip preserves the hash.

  • Gate 5 test_lifecycle_hookssetup/teardown overrides are async.

Classes

ExperimentPipeline

Standard test pipeline for a PLESTY experiment module.

Module Contents

class plesty.lib.test.experiment_pipeline.ExperimentPipeline(experiment_cls: type, *args: Any, **kwargs: Any)

Standard test pipeline for a PLESTY experiment module.

Parameters:
  • experiment_cls (type) – The experiment class under test. Must be instantiable without a devices argument — plan construction is device-free by contract.

  • *args (Any) – Positional arguments forwarded to experiment_cls.__init__.

  • **kwargs (Any) – Keyword arguments forwarded to experiment_cls.__init__.

  • arguments. (Store the experiment class and its construction)

experiment_cls
args = ()
kwargs
_instantiate() plesty.lib.experiment.Experiment

Construct the experiment under test with the stored arguments.

Return type:

plesty.lib.experiment.Experiment

test_experiment_subclass() None

Gate 1: the class is a public, instantiable Experiment subclass.

Verifies inheritance from plesty.lib.experiment.Experiment, a public class name, and that construction succeeds without hardware or devices (build_plan must therefore be implemented — an abstract subclass cannot be instantiated).

Return type:

None

test_plan_deterministic() None

Gate 2: build_plan() is deterministic and non-empty.

Two consecutive calls must yield plans with the same content_hash() — resume relies on the regenerated plan matching the persisted one. Step ids therefore must not depend on run time or randomness.

Return type:

None

test_plan_ops_resolve() None

Gate 3: every Step.op names an existing public experiment method.

Delegates to the framework’s own pre-run validation, so the gate fails exactly when run() would refuse the plan (plesty.lib.experiment.InvalidOperationError).

Return type:

None

test_plan_serializable() None

Gate 4: params/config are strictly JSON-serializable; save/load is hash-intact.

Plan.save stringifies unknown objects (default=str), which silently loses type information — on resume the regenerated plan would carry the original objects and never match a reloaded one. The gate therefore first requires strict JSON serializability, then verifies the save/load round trip preserves the content hash.

Return type:

None

test_lifecycle_hooks() None

Gate 5: setup/teardown overrides are async coroutine functions.

run() awaits both hooks; a synchronous override would fail at runtime, mid-measurement. Inherited defaults pass trivially.

Return type:

None

run_mock_pipeline() None

Run Gates 1–5 in sequence and raise if any gate fails.

Intended for use in a single pytest test function when individual gates do not need to be reported separately.

Return type:

None