From f59be3bf85076ab7e7c4e94a978b16fd1b626b48 Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Wed, 2 Oct 2024 11:50:44 +0100 Subject: [PATCH] Add system tests --- doc/dev/manual_system_testing.md | 37 ++++++++++++++++++ doc/dev/set_up_dev_environment.md | 39 ++----------------- .../dae_scan.py | 34 +++++++++++----- manual_system_tests/interruption.py | 28 +++++++++++++ pyproject.toml | 3 -- 5 files changed, 93 insertions(+), 48 deletions(-) create mode 100644 doc/dev/manual_system_testing.md rename src/ibex_bluesky_core/demo_plan.py => manual_system_tests/dae_scan.py (66%) create mode 100644 manual_system_tests/interruption.py diff --git a/doc/dev/manual_system_testing.md b/doc/dev/manual_system_testing.md new file mode 100644 index 0000000..7c4fd08 --- /dev/null +++ b/doc/dev/manual_system_testing.md @@ -0,0 +1,37 @@ +# Manual system testing + +Manual system tests are stored in the `manual_system_tests` directory. + +Each manual system test should be run both in the PyDEV console in the GUI, and in a standalone +python window, unless the test itself says otherwise. + +The tests will detail any prerequisites in it's docstrings, and will print out any checks +or expected results which you should manually verify. + +## Running the tests from PyDEV in the GUI + +In the PyDEV console in the GUI, type: + +``` +# Should print that it has loaded a named plan +g.load_script(r"c:\instrument\dev\ibex_bluesky_core\manual_system_tests\the_test.py") +# The RE object should already be defined in the PyDEV console +RE(dae_scan()) +``` + +If the plan uses plotting, it should plot using matplotlib embedded in the IBEX GUI. + +## Running from a standalone python session + +- Set the following environment variables in your `cmd` session +``` +set MYPVPREFIX=TE:NDWXXXX: +set "EPICS_CA_ADDR_LIST=127.255.255.255 130.246.51.255" +set "EPICS_CA_AUTO_ADDR_LIST=NO" +``` +- Run the test using: +``` +python c:\instrument\dev\ibex_bluesky_core\manual_system_tests\the_test.py +``` + +If the plan uses plotting, it should spawn a Qt matplotlib window. diff --git a/doc/dev/set_up_dev_environment.md b/doc/dev/set_up_dev_environment.md index 4de931c..deedd36 100644 --- a/doc/dev/set_up_dev_environment.md +++ b/doc/dev/set_up_dev_environment.md @@ -7,7 +7,7 @@ cd c:\Instrument\Dev git clone https://github.com/ISISComputingGroup/ibex_bluesky_core.git ``` -## Create & activate a python virtual environment (windows): +## Create & activate a virtual environment (windows) ``` cd c:\Instrument\Dev\ibex_bluesky_core @@ -15,56 +15,25 @@ python -m venv .venv .venv\Scripts\activate ``` -## Install the library & dev dependencies in editable mode: +## Install the library & dev dependencies in editable mode ``` python -m pip install -e .[dev] ``` -## Run the unit tests: +## Unit tests ``` python -m pytest ``` > [!TIP] > To debug the tests in pycharm, use `--no-cov` as an additional option to your run configuration. There is a conflict [issue](https://youtrack.jetbrains.com/issue/PY-20186/debugging-of-py.test-does-not-stop-on-breakpoints-if-coverage-plugin-enabled) with the pytest-cov module which breaks the debugger. -## Run lints: +## Run lints ``` ruff format --check ruff check pyright ``` -## Run the 'demo' plan - -Option 1: from a terminal: - -``` -python src\ibex_bluesky_core\demo_plan.py -``` - -Option 2: from an interactive shell (e.g. PyDEV in the GUI): - -```python -from ibex_bluesky_core.run_engine import get_run_engine -from ibex_bluesky_core.demo_plan import demo_plan -RE = get_run_engine() -RE(demo_plan()) -``` - -**If PVs for the demo plan don't connect, ensure that:** -- Set MYPVPREFIX -``` -set MYPVPREFIX=TE:NDWXXXX: -``` -- You have set an `EPICS_CA_ADDR_LIST`: -``` -set "EPICS_CA_ADDR_LIST=127.255.255.255 130.246.51.255" -set "EPICS_CA_AUTO_ADDR_LIST=NO" -``` -- You have an IBEX server running with a DAE in setup state, which can begin a simulated run -- You have a readable & writable block named "mot" in the current configuration pointing at -the type of block expected by `demo_plan` - ## Build docs locally To build the sphinx documentation locally run `sphinx-build doc _build` from the root of the repo. The generated output will be in the _build directory. diff --git a/src/ibex_bluesky_core/demo_plan.py b/manual_system_tests/dae_scan.py similarity index 66% rename from src/ibex_bluesky_core/demo_plan.py rename to manual_system_tests/dae_scan.py index ca950ea..d26cc6c 100644 --- a/src/ibex_bluesky_core/demo_plan.py +++ b/manual_system_tests/dae_scan.py @@ -1,5 +1,6 @@ """Demonstration plan showing basic bluesky functionality.""" +import os from typing import Generator import bluesky.plan_stubs as bps @@ -24,11 +25,25 @@ from ibex_bluesky_core.devices.simpledae.waiters import GoodFramesWaiter from ibex_bluesky_core.run_engine import get_run_engine -__all__ = ["demo_plan"] +def dae_scan_plan() -> Generator[Msg, None, None]: + """Manual system test which moves a block and reads the DAE. -def demo_plan() -> Generator[Msg, None, None]: - """Demonstration plan which moves a block and reads the DAE.""" + Prerequisites: + - A block named "mot" pointing at MOT:MTR0101.RBV + - A galil IOC in RECSIM mode with MTRCTRL=1 so that the above PV is available + - A DAE in a setup which can begin and end simulated runs. + + Expected result: + - A sensible-looking LiveTable has been displayed + * Shows mot stepping from 0 to 10 in 3 evenly-spaced steps + - A plot has been displayed (in IBEX if running in the IBEX gui, in a QT window otherwise) + * Should plot "noise" on the Y axis from the simulated DAE + * Y axis should be named "normalized counts" + * X axis should be named "mot" + - The DAE was started and ended once per point + - The DAE waited for at least 500 good frames at each point + """ prefix = get_pv_prefix() block = block_rw_rbv(float, "mot") @@ -67,17 +82,16 @@ def demo_plan() -> Generator[Msg, None, None]: ] ) def _inner() -> Generator[Msg, None, None]: - num_points = 20 + num_points = 3 yield from bps.mv(dae.number_of_periods, num_points) yield from bp.scan([dae], block, 0, 10, num=num_points) yield from _inner() -if __name__ == "__main__": - if "genie_python" not in matplotlib.get_backend(): - matplotlib.use("qtagg") - plt.ion() +if __name__ == "__main__" and not os.environ.get("FROM_IBEX") == "True": + matplotlib.use("qtagg") + plt.ion() RE = get_run_engine() - RE(demo_plan()) - input("plan complete, press return to continue.") + RE(dae_scan_plan()) + input("Plan complete, press return to close plot and exit") diff --git a/manual_system_tests/interruption.py b/manual_system_tests/interruption.py new file mode 100644 index 0000000..152a42a --- /dev/null +++ b/manual_system_tests/interruption.py @@ -0,0 +1,28 @@ +"""Demonstration plan showing basic bluesky functionality.""" + +import os +from typing import Generator + +import bluesky.plan_stubs as bps +from bluesky.utils import Msg + + +def interruption_manual_test_plan() -> Generator[Msg, None, None]: + """Manual system test that checks ctrl-c interruption of a plan. + + This test can only be usefully run from an interactive session. + + Expected result: + - After ctrl-c twice: + * A bluesky.utils.RunEngineInterrupted error should be raised + * Useful text describing options (RE.halt(), RE.abort(), RE.resume()) should be printed + - After RE.abort(): + * A RunEngineResult should be returned, with exit_status="abort" + * A bluesky.utils.RequestAbort error should be raised + """ + print("About to sleep - press ctrl-C twice to interrupt, then use RE.abort() to abort.") + yield from bps.sleep(999999999) + + +if __name__ == "__main__" and not os.environ.get("FROM_IBEX") == "True": + print("This system test should only be run from an interactive session.") diff --git a/pyproject.toml b/pyproject.toml index 5076ba8..17dfb9a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,9 +78,6 @@ addopts = "--cov --cov-report=html -vv" [tool.coverage.run] branch = true source = ["src"] -omit = [ - "src/ibex_bluesky_core/demo_plan.py" # Demo code only -] [tool.coverage.report] fail_under = 100