Tests are written in pytest and interact with a live NSO instance directly via MAAPI (NSO Python API).
- NSO running with the
l3vpnpackage loaded - NETSIM devices available in NSO
- NSO environment sourced before running tests:
source ~/nso/<version>/ncsrcTesting is initiated with:
make testThe test-packages target creates an isolated Python virtual environment, installs dependencies from tests/requirements.txt, runs pytest, then tears the environment down. The venv is not persisted between runs.
Fixtures are defined in conftest.py and are automatically discovered by pytest. Two session-scoped fixtures manage shared state across all tests:
maapi— opens a single MAAPI connection and user session for the duration of the test run; injected into any test or fixture that declares it as a parametertest_customer— creates thepytest-customerNSO customer required by thecustomer-nameleafref before any tests run; tears it down after the session. Runs automatically viaautouse=True
Tests are defined in test_service.py. Each test function that declares maapi as a parameter receives the shared session object and is responsible for its own service lifecycle (create, assert, delete).
| Test | Description |
|---|---|
test_service_lifecycle |
IPv4, two PE devices, port-mode true, no CE routing |
- Use the NSO CLI to configure the desired service instance
- Translate the configuration into a
test_*function intest_service.pyusing MAAPI - Follow the CREATE → READ → DELETE pattern with a
try/finallyblock to ensure cleanup on assertion failure
def test_service_lifecycle(maapi):
# CREATE
with maapi.start_write_trans() as t:
root = ncs.maagic.get_root(t)
svc = root.services.l3vpn.create('<customer>', '<service-id>')
# ... set service parameters ...
t.apply()
try:
# READ
with maapi.start_read_trans() as t:
root = ncs.maagic.get_root(t)
assert ('<customer>', '<service-id>') in root.services.l3vpn
# ... assert service parameters ...
finally:
# DELETE
with maapi.start_write_trans() as t:
root = ncs.maagic.get_root(t)
if ('<customer>', '<service-id>') in root.services.l3vpn:
del root.services.l3vpn['<customer>', '<service-id>']
t.apply()
# VERIFY DELETE
with maapi.start_read_trans() as t:
root = ncs.maagic.get_root(t)
assert ('<customer>', '<service-id>') not in root.services.l3vpnThe try/finally ensures DELETE always runs even if a READ assertion fails, keeping NSO clean between test runs.
Update the device names in test_service.py to match your NETSIM environment before running.