You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Foundation work for #232. The osism/netbox-manager repository currently has no unit tests at all:
No tests/ directory exists
No pytest configuration (existing pyproject.toml only configures mypy, setuptools, and setuptools-git-versioning)
No test dependencies (Pipfile[dev-packages] only lists python-gilt; requirements.txt is runtime-only)
The Zuul check/periodic-daily pipelines (see .zuul.yaml) only run flake8, mypy, python-black, yamllint — no Python tests are executed
The goal of this issue is to establish the foundation so that unit tests for netbox_manager/main.py and netbox_manager/dtl.py can be written and automatically executed in Zuul CI. Actual test coverage of the function groups (settings/role helpers, task / playbook builders, autoconf, validation, DTL, …) is tracked in the follow-up sub-issues under #232.
Repo specifics worth noting
The package is properly installable: pyproject.toml declares setuptools build-backend, entry point netbox-manager = "netbox_manager.main:main", and tool.setuptools.packages = ["netbox_manager"]. Tests can from netbox_manager import main, dtl directly — no sys.path munging needed.
Lint config in place today: .flake8, [tool.mypy] (exclude = ["doc"]) in pyproject.toml, .yamllint.yml. Tests must comply with the same rules.
pyproject.toml declares requires-python = ">=3.8" and classifies 3.8–3.14, but CI today only runs the default Zuul Python. Pinning the test job's Python version is part of this issue (see Open questions).
settings.toml is loaded at import time by dynaconf in netbox_manager/main.py:53. Tests must either provide a stub settings.toml (via tmp_path + monkeypatch.chdir) or set the relevant NETBOX_MANAGER_* env vars in conftest.py before importing netbox_manager.main. Document the chosen approach in conftest.py.
Scope
In scope (foundation only):
Set up the test framework (pytest)
Establish directory structure and configuration
One or two minimal smoke tests so the CI pipeline passes and the infrastructure is validated
Zuul integration: new job netbox-manager-unit-tests running in check and periodic-daily
tests/conftest.py configures dynaconf so importing netbox_manager.main does not require a real settings.toml (set NETBOX_MANAGER_URL / NETBOX_MANAGER_TOKEN / etc. via monkeypatch.setenv in an autouse fixture, or chdir to a tmp_path containing a stub settings.toml). Placeholder for shared mocks (pynetbox device / interface / IP / VRF / cluster / config-context / prefix shapes; ansible_runner.run; git.Repo) to be filled in by the per-module sub-issues.
tests/unit/netbox_manager/test_smoke.py contains a trivial test (e.g. from netbox_manager.main import deep_merge; assert deep_merge({\"a\": 1}, {\"b\": 2}) == {\"a\": 1, \"b\": 2}) so a failure in the test infrastructure is immediately visible.
3. pytest configuration
Extend the existing top-level pyproject.toml with a [tool.pytest.ini_options] section:
pytest tests/unit/netbox_manager/test_smoke.py to run a single test
Update CLAUDE.md to add the test command alongside the existing flake8 / mypy block.
6. Verification
pytest tests/unit runs green locally
The new Zuul job appears in check / periodic-daily and succeeds
flake8, mypy, python-black, yamllint remain green (new files must comply with the rules in .flake8 and .yamllint.yml; tests under tests/ are inside mypy's scan unless pyproject.toml excludes them — decide explicitly)
tests/ is excluded from the built sdist/wheel (verify via python -m build && tar -tf dist/*.tar.gz | grep tests returns nothing); add to MANIFEST.in or [tool.setuptools] exclude list if needed
Open questions for review
Test directory at repo root in tests/ (recommended above) or under netbox_manager/tests/? Recommendation: repo root, keeps tests out of the installed package automatically and matches the convention used by osism/python-osism.
Test dependencies as a separate test-requirements.txtor under [dev-packages] in Pipfile only? Recommendation: both — test-requirements.txt for the Zuul job (independent of pipenv), mirrored into Pipfile for local development convenience.
Should tests/ be in mypy's scan? Recommendation: yes, but with disable_error_code = [\"no-untyped-def\"] for the test tree so test functions don't need return-type annotations.
Definition of Done
All tasks in sections 1–5 implemented
Zuul check / periodic-daily pipelines contain and pass the new netbox-manager-unit-tests job
A minimal smoke test runs successfully in CI
Developers can run tests locally with two commands (pip install -r ..., pytest tests/unit)
Background
Foundation work for #232. The
osism/netbox-managerrepository currently has no unit tests at all:tests/directory existspyproject.tomlonly configuresmypy,setuptools, andsetuptools-git-versioning)Pipfile[dev-packages]only listspython-gilt;requirements.txtis runtime-only)check/periodic-dailypipelines (see.zuul.yaml) only runflake8,mypy,python-black,yamllint— no Python tests are executedThe goal of this issue is to establish the foundation so that unit tests for
netbox_manager/main.pyandnetbox_manager/dtl.pycan be written and automatically executed in Zuul CI. Actual test coverage of the function groups (settings/role helpers, task / playbook builders, autoconf, validation, DTL, …) is tracked in the follow-up sub-issues under #232.Repo specifics worth noting
pyproject.tomldeclaressetuptoolsbuild-backend, entry pointnetbox-manager = "netbox_manager.main:main", andtool.setuptools.packages = ["netbox_manager"]. Tests canfrom netbox_manager import main, dtldirectly — nosys.pathmunging needed..flake8,[tool.mypy](exclude = ["doc"]) inpyproject.toml,.yamllint.yml. Tests must comply with the same rules.pyproject.tomldeclaresrequires-python = ">=3.8"and classifies 3.8–3.14, but CI today only runs the default Zuul Python. Pinning the test job's Python version is part of this issue (see Open questions).settings.tomlis loaded at import time bydynaconfinnetbox_manager/main.py:53. Tests must either provide a stubsettings.toml(viatmp_path+monkeypatch.chdir) or set the relevantNETBOX_MANAGER_*env vars inconftest.pybefore importingnetbox_manager.main. Document the chosen approach inconftest.py.Scope
In scope (foundation only):
netbox-manager-unit-testsrunning incheckandperiodic-dailyOut of scope:
ansible_runnerTasks
1. Test dependencies
Add a new top-level
test-requirements.txt(separate from runtimerequirements.txt):pytestpytest-covpytest-mockPin versions, consistent with the existing style. Mirror the same entries under
[dev-packages]inPipfilesopipenv install --devpicks them up.2. Directory structure
tests/conftest.pyconfigures dynaconf so importingnetbox_manager.maindoes not require a realsettings.toml(setNETBOX_MANAGER_URL/NETBOX_MANAGER_TOKEN/ etc. viamonkeypatch.setenvin an autouse fixture, orchdirto atmp_pathcontaining a stubsettings.toml). Placeholder for shared mocks (pynetbox device / interface / IP / VRF / cluster / config-context / prefix shapes;ansible_runner.run;git.Repo) to be filled in by the per-module sub-issues.tests/unit/netbox_manager/test_smoke.pycontains a trivial test (e.g.from netbox_manager.main import deep_merge; assert deep_merge({\"a\": 1}, {\"b\": 2}) == {\"a\": 1, \"b\": 2}) so a failure in the test infrastructure is immediately visible.3. pytest configuration
Extend the existing top-level
pyproject.tomlwith a[tool.pytest.ini_options]section:Do not set a coverage threshold — only enable optional reporting via
--covflags passed on the command line.4. Zuul CI integration
In
.zuul.yaml:Define a new job
netbox-manager-unit-tests(analogous to the existing lint jobs):Add the job to the
checkandperiodic-dailypipelines (alongsideflake8,mypy,python-black,yamllint).Create a new playbook
playbooks/test-unit.ymlthat:pippip install -r requirements.txt -r test-requirements.txtandpip install -e .(sofrom netbox_manager import …works)pytest tests/unitfrom the repo root and uses the exit code as the job result5. Local usage & documentation
Short section in
README.md(or a newCONTRIBUTING.md) describing:pip install -r requirements.txt -r test-requirements.txt && pip install -e .(orpipenv install --dev && pipenv shell)pytest tests/unitfor the full runpytest tests/unit/netbox_manager/test_smoke.pyto run a single testUpdate
CLAUDE.mdto add the test command alongside the existingflake8/mypyblock.6. Verification
pytest tests/unitruns green locallycheck/periodic-dailyand succeedsflake8,mypy,python-black,yamllintremain green (new files must comply with the rules in.flake8and.yamllint.yml; tests undertests/are insidemypy's scan unlesspyproject.tomlexcludes them — decide explicitly)tests/is excluded from the built sdist/wheel (verify viapython -m build && tar -tf dist/*.tar.gz | grep testsreturns nothing); add toMANIFEST.inor[tool.setuptools]exclude list if neededOpen questions for review
tests/(recommended above) or undernetbox_manager/tests/? Recommendation: repo root, keeps tests out of the installed package automatically and matches the convention used byosism/python-osism.test-requirements.txtor under[dev-packages]inPipfileonly? Recommendation: both —test-requirements.txtfor the Zuul job (independent of pipenv), mirrored intoPipfilefor local development convenience.pyproject.tomldeclares>=3.8and classifies 3.8–3.14. Recommendation: 3.13 for now (matches osism/python-osism's foundation choice — see Introduce foundation for unit tests (pytest + Zuul CI integration) python-osism#2192) and add a 3.8/3.14 matrix as a follow-up.tests/be inmypy's scan? Recommendation: yes, but withdisable_error_code = [\"no-untyped-def\"]for the test tree so test functions don't need return-type annotations.Definition of Done
check/periodic-dailypipelines contain and pass the newnetbox-manager-unit-testsjobpip install -r ...,pytest tests/unit)tests/Parent / tracking issue: #232