Testing locally¶
Everything CI enforces can be run on your machine, and by design it is the same commands - the
make targets below are what the CI jobs execute. This page is the single authoritative
reference for local testing; if you find yourself pushing to CI just to see whether something
passes, something on this page is wrong - file an issue.
One-time setup¶
$ git clone https://gitlab.com/netorca_public/netorca_ansible.git && cd netorca_ansible
$ uv venv && source .venv/bin/activate
$ uv pip install -r test-requirements.txt -r docs-requirements.txt
$ pre-commit install # optional but recommended: lint/format on every commit
Any Python ≥ 3.11 virtualenv works if you do not use uv - install the same two requirements
files with pip.
The map: CI job → local command¶
| CI job | Make target | Direct command |
|---|---|---|
| lint | make lint |
ruff check . && ruff format --check . && ansible-lint --profile production |
| sanity | make sanity |
cd "$(bash scripts/setup-collection-path.sh)" && ansible-test sanity |
| units | make units |
pytest |
| build | make build |
ansible-galaxy collection build --output-path build/ --force |
| docs | make docs-check |
python scripts/generate_module_docs.py --check && mkdocs build --strict |
| integration | make integration |
bash scripts/run-integration.sh |
make format fixes what make lint reports where a fix is mechanical.
Unit tests¶
$ make units # or plain: pytest
$ pytest -k transition # subset by keyword
$ pytest tests/unit/plugins/modules/test_netorca_deployed_item.py -x
The unit suite mocks the NetOrca SDK entirely - no network, no credentials, no NetOrca
instance. Plain pytest from the repo root works because tests/unit/conftest.py builds a
temporary ansible_collections/netautomate/netorca symlink at import time; there is nothing to
set up.
What lives where:
| Path | Covers |
|---|---|
tests/unit/plugins/module_utils/test_netorca.py |
base layer: env fallbacks, exception→failure mapping, pagination/limit, filter building, serialisation |
tests/unit/plugins/modules/test_info_modules.py |
all info modules, table-driven: filters passed through, ID lookups, empty-not-error |
tests/unit/plugins/modules/test_netorca_change_instance.py |
the full 6×6 transition matrix + log/deployed_item/check-mode/diff behaviour |
tests/unit/plugins/modules/test_netorca_deployed_item.py |
create-vs-update detection, deep data compare, absent handling |
When adding a module: info modules usually need only new rows in the table-driven suite; write modules get their own file.
Sanity tests¶
ansible-test requires the collection to live at .../ansible_collections/netautomate/netorca,
so the target first syncs the working tree to /tmp/netorca-ac via
scripts/setup-collection-path.sh (rsync - fast on re-runs) and runs there. The suite that
matters most day-to-day is validate-modules: it fails when a module's DOCUMENTATION block
and its argument spec disagree.
Docs¶
The module reference is generated - never edit it
The pages under docs/modules/ are rendered from the modules' DOCUMENTATION blocks by
scripts/generate_module_docs.py. After any edit to a DOCUMENTATION/EXAMPLES/RETURN
block or a doc fragment, run make docs and commit the regenerated pages together with your
change - otherwise the CI docs job fails its drift gate.
$ make docs # regenerate module pages + build the site into site/
$ make docs-check # what CI runs: drift gate + strict build
$ make docs-serve # live preview at http://127.0.0.1:8000 while writing
Live integration tests¶
The playbooks in tests/integration/ run against a real NetOrca instance. The current suite
(smoke_readonly.yml) is safe by construction: info modules only, plus the write modules in
check mode - it never mutates anything, so it can run against a shared sandbox at any time.
Credentials wiring (the runner checks these in order):
- Environment variables already exported:
NETORCA_API_URL,NETORCA_API_KEY. -
A git-ignored
.envfile in the repo root - the runner sources it automatically: -
In CI: masked GitLab CI/CD variables of the same names (Settings → CI/CD → Variables, Masked, ideally Protected). The integration job is a manual button.
Without credentials the runner prints a notice and skips cleanly with exit 0 - so forks and credential-less environments stay green.
$ make integration # read-only suite
$ RUN_WRITE_TESTS=true make integration # additionally run write-cycle playbooks (future MRs)
RUN_WRITE_TESTS is the opt-in for playbooks that create/mutate real objects; the write-cycle
suite lands later in the v2 series and needs a sandbox service owned by the test key's team.
Keys are secrets
Never put an API key in a playbook, a commit, or a CI file. The modules mark api_key as
no_log; keep it that way end-to-end by using the environment/.env/masked-variable chain
above. See Authentication.