testing
Provides testing strategies, build decisions, and test execution commands for the PTO Runtime codebase.
Install
mkdir -p .claude/skills/testing-hw-native-sys && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/11977" && unzip -o skill.zip -d .claude/skills/testing-hw-native-sys && rm skill.zipInstalls to .claude/skills/testing-hw-native-sys
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Testing guide and pre-commit testing strategy for PTO Runtime. Use when running tests, adding tests, or deciding what to test before committing.Key capabilities
- →Run Python unit tests with `pytest`
- →Execute C++ unit tests with GoogleTest
- →Discover and run scene tests with `pytest`
- →Determine if runtime binaries need recompilation
- →Detect available hardware platforms for testing
- →Apply pre-commit testing strategy based on changed files
How it works
The skill guides the user through running different types of tests (Python, C++, scene), determining runtime rebuild needs, and applying a pre-commit testing strategy based on changed files and platform availability.
Inputs & outputs
When to use testing
- →Running Python unit tests for the compilation pipeline
- →Executing C++ unit tests with GoogleTest
- →Validating scene tests before committing
- →Checking if runtime binaries require a rebuild
About this skill
Testing
Test Types
- Python unit tests (ut-py) (
tests/ut/): Standard pytest tests for the Python compilation pipeline and nanobind bindings. Run withpytest tests/ut. Tests declaring@pytest.mark.requires_hardware[("<platform>")]auto-skip unless--platformpoints to a matching device. - C++ unit tests (ut-cpp) (
tests/ut/cpp/): GoogleTest-based tests for pure C++ modules. Run withcmake -B tests/ut/cpp/build -S tests/ut/cpp && cmake --build tests/ut/cpp/build && ctest --test-dir tests/ut/cpp/build -LE requires_hardware --output-on-failure. Hardware-required tests carry arequires_hardwareorrequires_hardware_<platform>ctest label and are filtered via-LE. - Scene tests (
examples/{arch}/*/,tests/st/{arch}/*/): End-to-end@scene_testclasses declared insidetest_*.py. Sim variants run cross-platform (Linux/macOS); hardware variants require the CANN toolkit and an Ascend device. Discovery is by pytest (batch) orpython test_*.py(standalone);#591's parallel orchestrator handles device bin-packing and ChipWorker reuse automatically.
Running Tests
Important: Always read .github/workflows/ci.yml first for the current
--pto-session-timeout values. Quarantines are marker-based, so mirror the
a2a3 sweep with -m "not sdma" rather than copying a path list. PTO-ISA
reproducibility comes from the repo-root pto_isa.pin.
CI does not run one flat sweep on a2a3. Marked tests are quarantined out of
the general onboard sweep and run in a step of their own, after it, because
they are only correct in isolation. A5 runs the non-pod corpus, including
SDMA tests, on both x86_64 and ARM64. Reproducing a2a3 CI means reproducing that
shape — a bare pytest examples tests/st --platform a2a3 is not what CI runs
and will report failures that CI never sees:
| Marker | Tests | CI behavior |
|---|---|---|
@pytest.mark.manual / CASES[*]["manual"] | Standalone pytest tests / individual scene-test cases; optionally scoped to a platform list | Per-PR: excluded by default on the selected platforms; daily.yml: full sweep with --manual include |
@pytest.mark.sdma | a2a3: sdma_async_completion_demo, prefetch_async_demo; a5: sdma_async_completion_demo | a2a3: the dedicated SDMA step; a5: included in the non-pod sweep |
The a2a3 SDMA demos provision 48 device-only STARS streams, which makes an
AICore fault take ~306 s to tear down instead of ~0.3 s — so they must not
share a sweep with the aicore_op_timeout fault-injection test
(investigations/2026-07-a2a3-sdma-fault-teardown.md,
issue #1425).
When an onboard test fails, run it alone before calling it a regression.
Alone-passes plus sweep-fails is an isolation requirement, not a defect: check
the test for a quarantine marker such as @pytest.mark.sdma. Do not "fix" such
a test by reordering it earlier — that only moves the pollution onto whatever
now runs after it.
Runtime rebuild decision
Before running tests, determine whether runtime binaries need recompilation:
| What changed | Rebuild needed? | How |
|---|---|---|
Runtime/platform C++ (src/{arch}/runtime/, src/{arch}/platform/) | Yes | Re-run pip install --no-build-isolation -e . (incremental via build/cache/) |
Nanobind bindings (python/bindings/) | Yes | Re-run pip install -e . |
| Python-only code, examples, kernels | No | Just re-run the test |
In CI, pip install . pre-builds all runtimes before tests run.
# Python unit tests (no hardware)
pytest tests/ut
# Python unit tests (a2a3 hardware)
pytest tests/ut --platform a2a3
# C++ unit tests (no hardware)
cmake -B tests/ut/cpp/build -S tests/ut/cpp && cmake --build tests/ut/cpp/build
ctest --test-dir tests/ut/cpp/build -LE requires_hardware --output-on-failure
# C++ unit tests (a2a3 hardware)
ctest --test-dir tests/ut/cpp/build -L "^requires_hardware(_a2a3)?$" --output-on-failure
# All simulation scene tests (extract --pto-session-timeout from ci.yml)
pytest examples tests/st --platform a2a3sim \
--pto-session-timeout <timeout>
# All hardware scene tests — mirror ci.yml: deselect the quarantined marker, or
# those tests fail here and nowhere else
pytest examples tests/st -m "not sdma" --platform a2a3 --device <range> \
--pto-session-timeout <timeout>
# The quarantined tests, the way CI runs them — same corpus, selected by the
# marker, run after the sweep rather than inside it. Never a path list: that is
# what the marker replaced.
pytest examples tests/st -m sdma \
--platform a2a3 --device <2 devs> --pto-session-timeout <timeout>
# A5 runs the non-pod corpus, including SDMA tests, on both host architectures.
pytest examples tests/st -m "not pod" --platform a5 --device <range> \
--pto-session-timeout <timeout>
# Single runtime
pytest examples tests/st --platform a2a3sim --runtime host_build_graph
# Single example (pytest, uses pre-built binaries)
pytest examples/a2a3/host_build_graph/vector_example --platform a2a3sim
# Single example (standalone; re-run `pip install --no-build-isolation -e .` first if runtime C++ changed)
python examples/a2a3/host_build_graph/vector_example/test_vector_example.py \
-p a2a3sim
Pre-Commit Testing Strategy
When changed files require testing (C++, Python, or CMake), follow these steps to decide what to test and how.
Step 1 — Platform Availability and Detection
command -v npu-smi &>/dev/null
| Result | Platforms to test |
|---|---|
| Found | <arch>sim (simulation) and <arch> (hardware) |
| Not found | Simulation only (default a2a3sim) |
When npu-smi is found, detect the platform by parsing chip name from npu-smi info output:
| Chip name contains | Platform |
|---|---|
910B or 910C | a2a3 (sim: a2a3sim) |
950 | a5 (sim: a5sim) |
Use the detected platform for all subsequent --platform flags. If the chip name is unrecognized, warn and default to a2a3.
Step 2 — Test Scope
Run git diff --name-only (or git diff --cached --name-only for staged changes) and match the first applicable rule:
| Changed paths | Scope | Command pattern |
|---|---|---|
src/{arch}/platform/* | Full (all runtimes) | pytest examples tests/st --platform <platform> |
src/{arch}/runtime/<rt>/* | Single runtime | pytest examples tests/st --platform <platform> --runtime <rt> |
examples/{arch}/<rt>/<ex>/* | Single example | python <ex>/test_*.py -p <platform> (or pytest <ex> --platform <platform>) |
tests/ut/* (Python) | Python UT only | pytest tests/ut (add --platform <platform> on a device runner) |
tests/ut/cpp/* | C++ UT only | cmake -B tests/ut/cpp/build -S tests/ut/cpp && cmake --build tests/ut/cpp/build && ctest --test-dir tests/ut/cpp/build -LE requires_hardware |
| Mixed (spans multiple categories) | Escalate to the widest matching scope | — |
Note on runtime C++ changes: When changed paths include
src/{arch}/runtime/orsrc/{arch}/platform/, re-runpip install --no-build-isolation -e .before testing to rebuild the runtime binaries inbuild/lib/(incremental viabuild/cache/). There is no rebuild-on-import —editable.rebuild = false.
Step 3 — Parallel Strategy
Parallelism is handled by the #591 scheduler (simpler_setup/parallel_scheduler.py) based on --device and --max-parallel:
Simulation (a2a3sim): --max-parallel auto = min(nproc, len(--device)). Pass --device 0-15 for a big virtual pool; auto caps in-flight at the CPU count. Override with --max-parallel N on CPU-constrained runners.
Hardware (a2a3): --max-parallel auto = len(--device). One in-flight subprocess per physical device — each device runs a dedicated ChipWorker (see docs/ci.md).
Step 4 — Device Detection (hardware only)
When testing on a2a3, detect idle devices:
npu-smi info
Pick devices whose HBM-Usage is 0 and find the longest consecutive sub-range (at most 4). Pass as --device <start>-<end> (or --device <id> if only one idle device). If no idle device is found, skip hardware testing and warn.
Decision Tree
git diff --name-only
│
├─ Only docs/config? ──→ SKIP tests
│
└─ Code changed?
│
├─ Determine SCOPE (Step 2)
│ ├─ platform → full (pytest --platform ...)
│ ├─ runtime → single runtime (--runtime ...)
│ └─ example → single example (standalone test_*.py or pytest <ex>)
│
├─ Runtime C++ changed (src/{arch}/)? ──→ pip install --no-build-isolation -e . first
│
└─ npu-smi found?
├─ Yes → sim + hardware (idle devs, max 4)
└─ No → sim only
Adding a New Scene Test
- Create a directory under the appropriate arch and runtime:
- Examples:
examples/{arch}/<runtime>/<name>/ - Device-only scene tests:
tests/st/{arch}/<runtime>/<name>/
- Examples:
- Add
test_<name>.pywith a@scene_test-decorated class (see docs/testing.md for the full template:CALLABLE,CASES,generate_args,compute_golden). End withif __name__ == "__main__": SceneTestCase.run_module(__name__)so the file runs standalone. - Add kernel source files under
kernels/aic/,kernels/aiv/, and/orkernels/orchestration/— referenced byCALLABLE["orchestration"]["source"]/CALLABLE["incores"][*]["source"]as paths relative to the test file. - Pytest auto-discovers any
test_*.pyunderexamples/andtests/st/; no registration needed.
Related Skills
git-commit— Complete commit workflow (runs testing as a prerequisite)
When not to use it
- →When testing is not required before committing
- →When the project is not PTO Runtime
- →When specific test types are not applicable
Limitations
- →Specific to PTO Runtime
- →Hardware-required tests need a matching device
- →Runtime rebuild decision is based on specific file changes
How it compares
This skill provides a specific testing guide and pre-commit strategy tailored for PTO Runtime, including platform detection and runtime rebuild decisions, unlike generic testing instructions.
Compared to similar skills
testing side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| testing (this skill) | 0 | 2mo | Review | Advanced |
| dev | 2 | 6mo | Review | Advanced |
| ci-pr-helper | 0 | 6mo | Review | Beginner |
| auto_pr | 0 | 5mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
dev
atopile
LLM-focused workflow for working in this repo: compile Zig, run the orchestrated test runner, consume test-report.json/html artifacts, and discover/debug ConfigFlags.
ci-pr-helper
lance-format
Run local test/style checks and open GitHub PRs for lance-context. Use when asked to run CI-equivalent checks (uv pytest, ruff/pyright, cargo fmt/clippy/test) and then create a PR with a proper title/body.
auto_pr
splendidsummer
auto_pr — an agent skill by splendidsummer.
country-atlas-ci-fix
dimbo1324
Use when GitHub Actions, pre-commit, tests, typing, lint, SQL lint, Docker smoke, or Playwright checks fail.
code-change-verification
openai
Run the mandatory verification stack when changes affect runtime code, tests, or build/test behavior in the OpenAI Agents Python repository.
discovering-make-commands
streamlit
Lists available make commands for Streamlit development. Use for build, test, lint, or format tasks.