⚠️ INITIAL DEVELOPMENT: This package is under active initial development and not yet ready for production use.
A shared library consolidating duplicated PyATS testing infrastructure across NAC (Network as Code) architecture repositories. This package serves as a Layer 2 adapter between architecture-specific test repositories (ACI, SD-WAN, Catalyst Center) and the core nac-test framework.
The nac-test-pyats-common package addresses the architectural challenge of duplicated pyats_common/ directories across NAC architecture repositories. It consolidates shared PyATS testing infrastructure—including authentication classes, test base classes, and device resolvers—into a centralized, maintainable package.
Each NAC architecture repository previously contained duplicated PyATS infrastructure code:
- ~90% of base test class code was identical across architectures
- Bug fixes and improvements required manual propagation to all repos
- Each architecture team maintained essentially the same code
- Adding new architectures (ISE, Meraki, IOS-XE) compounded the duplication problem
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 3: Architecture Repositories │
│ (nac-aci-terraform, nac-sdwan-terraform, nac-catc-terraform) │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Test Files │ │ NAC Schema │ │
│ │ (verify_*.py) │ │ Definitions │ │
│ └────────┬────────┘ └─────────────────┘ │
│ │ │
│ │ imports │
│ ▼ │
└───────────┼──────────────────────────────────────────────────────────┘
│
┌───────────▼──────────────────────────────────────────────────────────┐
│ Layer 2: nac-test-pyats-common (Architecture Adapters) │
│ DEPENDS ON nac-test │
│ │
│ • Architecture-specific authentication (APICAuth, VManageAuth) │
│ • Architecture-specific test base classes (APICTestBase, etc.) │
│ • Architecture-specific device resolvers (SDWANDeviceResolver) │
│ │ │
│ │ imports NACTestBase, SSHTestBase, AuthCache │
│ ▼ │
└───────────────────────┼──────────────────────────────────────────────┘
│
┌───────────────────────▼──────────────────────────────────────────────┐
│ Layer 1: nac-test (Core Framework) │
│ Orchestration + Generic Infrastructure │
│ │
│ • Test orchestration (discovering tests, running them) │
│ • Testbed generation (generic device dict → PyATS YAML) │
│ • Connection brokering (SSH connection pooling) │
│ • HTML report generation │
│ • Generic base classes (NACTestBase, SSHTestBase) │
└─────────────────────────────────────────────────────────────────────┘
-
ACI (Application Centric Infrastructure)
APICAuth- APIC authentication with cookie-based sessionsAPICTestBase- Base class for ACI/APIC testsACIDeviceResolver- Device inventory from ACI data models
-
SD-WAN
VManageAuth- vManage authentication with token-based sessionsVManageTestBase- Base class for vManage API testsSDWANSSHTestBase- Base class for SD-WAN D2D/SSH testsSDWANDeviceResolver- Device inventory from sites.nac.yaml
-
Catalyst Center
CatalystCenterAuth- Token-based authentication (X-Auth-Token)CatalystCenterTestBase- Base class for Catalyst Center API testsCatalystCenterDeviceResolver- Device inventory from NAC schemas
- ISE (Identity Services Engine)
- Meraki
- IOS-XE (Direct device access)
Python 3.10+ is required. Don't have Python 3.10 or later? See Python 3 Installation & Setup Guide.
pip install nac-test-pyats-commonThis will automatically install the required dependencies:
nac-test~=1.1.0- Core testing framework (brings PyATS as transitive dependency)httpx>=0.28- HTTP client for authentication
Replace the old fragile imports from architecture repos:
# Old pattern (remove this)
from templates.catc.test.pyats_common.catc_base_test import CatalystCenterTestBase
# New pattern (use this)
from nac_test_pyats_common.catc import CatalystCenterTestBase# In nac-catalystcenter-terraform/tests/templates/catc/test/api/verify_something.py
from nac_test_pyats_common.catc import CatalystCenterTestBase
from nac_test.pyats_core.reporting.types import ResultStatus
from pyats import aetest
class TestCatalystCenterFeature(CatalystCenterTestBase):
"""Test class for Catalyst Center feature verification."""
@aetest.test
def verify_feature(self):
"""Verify feature configuration."""
# self.client is already configured with auth headers
response = self.client.get("/api/v1/feature")
if response.status_code == 200:
self.result = ResultStatus.PASS
else:
self.result = ResultStatus.FAILEach architecture provides an authentication class that handles controller-specific authentication:
from nac_test_pyats_common.aci import APICAuth
from nac_test_pyats_common.sdwan import VManageAuth
from nac_test_pyats_common.catc import CatalystCenterAuth
# Authentication is handled automatically when using test base classes
# But can be used directly if needed:
auth_data = CatalystCenterAuth.get_auth() # Uses AuthCache internallyTest base classes extend NACTestBase from nac-test with architecture-specific setup:
from nac_test_pyats_common.catc import CatalystCenterTestBase
class MyTest(CatalystCenterTestBase):
"""Your test class."""
@aetest.setup
def setup(self):
"""Setup is handled by base class."""
super().setup()
# self.client is now available with auth headers configured
# self.auth_data contains authentication tokens/cookiesDevice resolvers parse NAC schemas to provide device inventory for SSH tests:
from nac_test_pyats_common.sdwan import SDWANDeviceResolver
# Used by nac-test orchestrator internally
devices = SDWANDeviceResolver.get_ssh_device_inventory(data_model)Each architecture requires specific environment variables for authentication:
CC_URL- Controller URLCC_USERNAME- UsernameCC_PASSWORD- PasswordCC_INSECURE- Skip SSL verification (optional, default: "True")
VMANAGE_URL- vManage URLVMANAGE_USERNAME- UsernameVMANAGE_PASSWORD- PasswordVMANAGE_INSECURE- Skip SSL verification (optional, default: "True")
APIC_URL- APIC URLAPIC_USERNAME- UsernameAPIC_PASSWORD- PasswordAPIC_INSECURE- Skip SSL verification (optional, default: "True")
# Clone the repository
git clone https://github.com/netascode/nac-test-pyats-common.git
cd nac-test-pyats-common
# Install in editable mode with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/unit/ -v
pytest tests/integration/ -v # Requires nac-test
# Type checking
mypy --strict src/
# Linting
ruff check src/When contributing, understand which repository to modify:
| Change Type | Repository | Example |
|---|---|---|
| Auth endpoint change | nac-test-pyats-common | Catalyst Center adds new auth API |
| Test base setup logic | nac-test-pyats-common | Add new setup step for all CC tests |
| Generic orchestration | nac-test | Change how tests are discovered/run |
| HTML report format | nac-test | Modify report template |
| Test file (verify_*.py) | Architecture repo | Add new verification test |
nac-test~=1.1.0- Core testing framework- Provides:
NACTestBase,SSHTestBase,AuthCache, orchestration - Brings PyATS as transitive dependency
- Provides:
httpx>=0.28- Modern async-capable HTTP client
This package follows Semantic Versioning 2.0.0:
- MAJOR: Breaking API changes
- MINOR: New features, backward compatible
- PATCH: Bug fixes, backward compatible
| nac-test-pyats-common | nac-test Required | Notes |
|---|---|---|
| 1.0.x | ~=1.1.0 | Initial release |
| 1.1.x | ~=1.1.0 | New architecture added |
| 2.0.x | ~=2.0.0 | Breaking changes |
This project is licensed under the Mozilla Public License 2.0 (MPL-2.0) - see the LICENSE file for details.
For issues, questions, or contributions, please visit the GitHub repository.