diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..c0395b4 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,61 @@ +# Agent Instructions + +## 1) Understand the purpose + +This project is the **Python SDK for Eclipse Ankaios** — a lightweight workload +orchestrator for automotive embedded devices and HPCs. The SDK gives Python +workloads running inside an Ankaios-managed container access to the Ankaios +Control Interface to manage (start, stop, update) other workloads and read +cluster state. + +The SDK is published on PyPI as `ankaios-sdk`. Current version and compatible +Ankaios version are in `setup.cfg` under `[metadata]`. + +## 2) Non-negotiable rules + +- **Never break existing public API** — must keep semantic alignment with other Ankaios SDKs +- **Tests must cover behavior, not lines** — write tests for what the code is + supposed to do, not to satisfy a coverage metric. Coverage is a reviewer + hint, not a goal; gaming it with shallow assertions is a defect. + Concretely required: + - Every distinct behavior and postcondition gets its own test + - Every error condition is tested in every way it can be triggered + - Every variant of a result type is exercised: both the success and failure + paths of a function, every enum variant that can be returned +- **Pylint score must stay at 10.0/10** — no new lint violations +- **PEP 8 compliance is mandatory** — zero violations +- **Never invent container images** — if an image is needed, ask the user +- **Exclude generated proto files from all checks** — `*_pb2.py` / `*_pb2_grpc.py` are auto-generated; never edit them +- **Keep the solution minimal** — avoid unrelated refactors or speculative features + +## 3) Development reference + +Read [DEVELOPMENT.md](DEVELOPMENT.md) before making changes. It covers setup, +how to run checks, and all code and test conventions. + +## 4) Architecture + +The SDK communicates with the Ankaios agent via a Unix socket at +`/run/ankaios/control_interface` (two FIFOs: `input` and `output`). Messages +are length-delimited protobuf (`_control_api` wrapping `_ank_base`). + +`ControlInterface` runs a background reader thread that deserializes incoming +messages and dispatches them to `Ankaios` via callbacks. `Ankaios` routes +responses to the correct caller using a request-ID queue. + +`Ankaios` is the primary entry point, typically used as a context manager: + +```python +from ankaios_sdk import Ankaios + +with Ankaios() as ankaios: + state = ankaios.get_state(timeout=5) +``` + +Use `_ank_base` (from `ankaios_sdk._protos`) for proto message construction in +tests. Never import `_pb2` files directly from outside the `_protos` package. +User-facing code must not expose proto objects. + +## 5) Exceptions + +All exceptions derive from `AnkaiosException` (see `ankaios_sdk/exceptions.py`). diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index b7580ea..e2e510b 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -14,9 +14,56 @@ pip install -e ".[dev]" ## Commands and Scripts -The project provides a unified check runner ([run_checks.py](./run_checks.py)) for common development workflows. For a complete list of the available checks and actions, run `python3 run_checks.py --help`. +All checks go through [run_checks.py](./run_checks.py) (one flag at a time): -In addition, the [tools](tools/) folder contains helper scripts for specific tasks. Check the tools [readme](tools/README.md) for more info. +```shell +python3 run_checks.py --utest # unit tests +python3 run_checks.py --cov # coverage report (use as a review hint, not a target) +python3 run_checks.py --lint # pylint (enforces 10.0/10) +python3 run_checks.py --pep8 # PEP 8 style (enforces zero violations) +``` + +Extra arguments are forwarded to the underlying tool (pytest / pylint / pycodestyle): + +```shell +python3 run_checks.py --utest tests/test_ankaios.py # single file +python3 run_checks.py --utest -k test_apply_workload # by keyword +``` + +The [tools/](tools/) folder contains helper scripts for specific tasks — see [tools/README.md](tools/README.md) for details. All scripts support `--help`: + +- `fetch_protos.sh` — download proto files from a specific Ankaios branch +- `update_version.sh` — bump SDK, Ankaios, and API versions across the project +- `generate_docs.sh` — build Sphinx HTML docs into `docs/build/` +- `install_ankaios.sh` — install Ankaios runtime (release or CI artifacts) + +## Code and Test Conventions + +- Max line length: 79 chars (pycodestyle default) +- Every module, class, and public method needs a docstring (follow existing style in `_components/*.py`) +- Module-level `__all__` is required for all public modules +- Use `get_logger()` from `utils.py` — not `logging.getLogger` directly +- Apache-2.0 SPDX license header at the top of every new source file +- Tests mirror the `ankaios_sdk/_components/` structure +- Use `unittest.mock.patch` / `MagicMock` for all external dependencies +- Each test module exports a `generate_test_()` helper for fixtures +- Accessing private members in tests (e.g. `ankaios._control_interface`) is normal + +**Typical test setup pattern:** + +```python +from unittest.mock import patch, PropertyMock +from ankaios_sdk import Ankaios, ControlInterfaceState + +def generate_test_ankaios() -> Ankaios: + with patch("ankaios_sdk.ControlInterface.connect"), patch( + "ankaios_sdk.ControlInterface.connected", new_callable=PropertyMock + ) as mock_connected: + mock_connected.return_value = True + ankaios = Ankaios() + ankaios._control_interface._state = ControlInterfaceState.CONNECTED + return ankaios +``` ## Updating Documentation @@ -30,7 +77,15 @@ There are markdown files which are part of the published documentation. Because ### Tests fail with strange errors regarding the protobuf objects -If this is the case, the proto files do not match the local code. The fetching of the proto files is documented in the [setup.py](setup.py) script, in the `extract_the_proto_files` method. It might be the case that the proto files must be fetched again. +The proto files do not match the local code. Re-fetch them: + +```shell +pip install -e . +# or for a specific Ankaios branch: +ANKAIOS_PROTO_BRANCH=my-feature-branch pip install -e . +``` + +The fetching logic is in [setup.py](setup.py) (`extract_the_proto_files`). ## Additional Resources