first commit
This commit is contained in:
336
netbox_librenms_plugin/tests/conftest.py
Normal file
336
netbox_librenms_plugin/tests/conftest.py
Normal file
@@ -0,0 +1,336 @@
|
||||
"""Shared pytest fixtures for NetBox LibreNMS Plugin tests."""
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
# =============================================================================
|
||||
# Configuration Fixtures
|
||||
# =============================================================================
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_multi_server_config():
|
||||
"""Multi-server configuration dict."""
|
||||
return {
|
||||
"default": {
|
||||
"librenms_url": "https://librenms-default.example.com",
|
||||
"api_token": "default-token-12345",
|
||||
"cache_timeout": 300,
|
||||
"verify_ssl": True,
|
||||
},
|
||||
"secondary": {
|
||||
"librenms_url": "https://librenms-secondary.example.com",
|
||||
"api_token": "secondary-token-67890",
|
||||
"cache_timeout": 600,
|
||||
"verify_ssl": False,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_legacy_config():
|
||||
"""Legacy single-server configuration dict (flat structure)."""
|
||||
return {
|
||||
"librenms_url": "https://librenms.example.com",
|
||||
"api_token": "legacy-token-abcdef",
|
||||
"cache_timeout": 300,
|
||||
"verify_ssl": True,
|
||||
}
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# API Instance Fixtures
|
||||
# =============================================================================
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_librenms_api(mock_multi_server_config):
|
||||
"""Pre-configured LibreNMSAPI instance with mocked dependencies."""
|
||||
with patch("netbox_librenms_plugin.librenms_api.get_plugin_config") as mock_config:
|
||||
mock_config.return_value = mock_multi_server_config
|
||||
from netbox_librenms_plugin.librenms_api import LibreNMSAPI
|
||||
|
||||
api = LibreNMSAPI(server_key="default")
|
||||
yield api
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# NetBox Object Mocks (Avoid Database)
|
||||
# =============================================================================
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_netbox_device():
|
||||
"""Mock NetBox Device object without database."""
|
||||
device = MagicMock()
|
||||
device.name = "test-device"
|
||||
device.cf = {} # Custom fields
|
||||
device.primary_ip4 = MagicMock()
|
||||
device.primary_ip4.address = MagicMock()
|
||||
device.primary_ip4.address.ip = "192.168.1.1"
|
||||
device.primary_ip4.__str__ = lambda self: "192.168.1.1/24"
|
||||
device.primary_ip6 = None
|
||||
device._meta.model_name = "device"
|
||||
return device
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_netbox_vm():
|
||||
"""Mock NetBox VirtualMachine object without database."""
|
||||
vm = MagicMock()
|
||||
vm.name = "test-vm"
|
||||
vm.cf = {}
|
||||
vm.primary_ip4 = MagicMock()
|
||||
vm.primary_ip4.address = MagicMock()
|
||||
vm.primary_ip4.address.ip = "10.0.0.1"
|
||||
vm.primary_ip6 = None
|
||||
vm._meta.model_name = "virtualmachine"
|
||||
return vm
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# HTTP Response Fixtures
|
||||
# =============================================================================
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_response_factory():
|
||||
"""Factory for creating mock HTTP responses."""
|
||||
|
||||
def _create_response(status_code=200, json_data=None, raise_for_status=None):
|
||||
response = MagicMock()
|
||||
response.status_code = status_code
|
||||
response.json.return_value = json_data or {}
|
||||
response.ok = 200 <= status_code < 300
|
||||
if raise_for_status:
|
||||
response.raise_for_status.side_effect = raise_for_status
|
||||
return response
|
||||
|
||||
return _create_response
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_success_response(mock_response_factory):
|
||||
"""Standard successful API response."""
|
||||
return mock_response_factory(status_code=200, json_data={"status": "ok", "message": "Success"})
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_device_response(mock_response_factory):
|
||||
"""Mock response for device info endpoint."""
|
||||
return mock_response_factory(
|
||||
status_code=200,
|
||||
json_data={
|
||||
"status": "ok",
|
||||
"devices": [
|
||||
{
|
||||
"device_id": 42,
|
||||
"hostname": "test-device.example.com",
|
||||
"sysName": "test-device",
|
||||
"ip": "192.168.1.1",
|
||||
"status": 1,
|
||||
"location": "Data Center 1",
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_error_response(mock_response_factory):
|
||||
"""Standard error API response."""
|
||||
return mock_response_factory(
|
||||
status_code=500,
|
||||
json_data={"status": "error", "message": "Internal server error"},
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_auth_error_response(mock_response_factory):
|
||||
"""Authentication error response (401)."""
|
||||
return mock_response_factory(status_code=401, json_data={"status": "error", "message": "Unauthorized"})
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Phase 2: Import Utilities Fixtures
|
||||
# =============================================================================
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_librenms_device():
|
||||
"""Sample LibreNMS device data for import tests."""
|
||||
return {
|
||||
"device_id": 1,
|
||||
"hostname": "switch-01.example.com",
|
||||
"sysName": "switch-01",
|
||||
"ip": "192.168.1.1",
|
||||
"location": "DC1",
|
||||
"os": "ios",
|
||||
"hardware": "C9300-48P",
|
||||
"version": "17.3.1",
|
||||
"status": 1,
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_librenms_device_minimal():
|
||||
"""Minimal LibreNMS device data with missing fields."""
|
||||
return {
|
||||
"device_id": 2,
|
||||
"hostname": "10.0.0.1",
|
||||
"status": 1,
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_validation_state():
|
||||
"""Sample validation state for testing updates."""
|
||||
return {
|
||||
"device_id": 1,
|
||||
"hostname": "switch-01",
|
||||
"is_ready": False,
|
||||
"can_import": False,
|
||||
"import_as_vm": False,
|
||||
"existing_device": None,
|
||||
"issues": ["Device role must be manually selected before import"],
|
||||
"warnings": [],
|
||||
"site": {
|
||||
"found": True,
|
||||
"site": MagicMock(id=1, name="DC1"),
|
||||
"match_type": "exact",
|
||||
},
|
||||
"device_type": {
|
||||
"found": True,
|
||||
"device_type": MagicMock(id=1, model="C9300-48P"),
|
||||
"match_type": "exact",
|
||||
},
|
||||
"device_role": {"found": False, "role": None, "available_roles": []},
|
||||
"cluster": {"found": False, "cluster": None, "available_clusters": []},
|
||||
"platform": {
|
||||
"found": True,
|
||||
"platform": MagicMock(id=1, name="ios"),
|
||||
"match_type": "exact",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_validation_state_vm():
|
||||
"""Sample validation state for VM import testing."""
|
||||
return {
|
||||
"device_id": 1,
|
||||
"hostname": "vm-01",
|
||||
"is_ready": False,
|
||||
"can_import": False,
|
||||
"import_as_vm": True,
|
||||
"existing_device": None,
|
||||
"issues": ["Cluster must be manually selected before import"],
|
||||
"warnings": [],
|
||||
"cluster": {"found": False, "cluster": None, "available_clusters": []},
|
||||
"device_role": {"found": False, "role": None, "available_roles": []},
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_netbox_site():
|
||||
"""Mock NetBox Site object."""
|
||||
site = MagicMock()
|
||||
site.id = 1
|
||||
site.name = "DC1"
|
||||
site.slug = "dc1"
|
||||
return site
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_netbox_platform():
|
||||
"""Mock NetBox Platform object."""
|
||||
platform = MagicMock()
|
||||
platform.id = 1
|
||||
platform.name = "Cisco IOS"
|
||||
platform.slug = "cisco_ios"
|
||||
return platform
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_netbox_device_type():
|
||||
"""Mock NetBox DeviceType object."""
|
||||
dt = MagicMock()
|
||||
dt.id = 1
|
||||
dt.model = "C9300-48P"
|
||||
dt.manufacturer = MagicMock(name="Cisco")
|
||||
return dt
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_netbox_device_role():
|
||||
"""Mock NetBox DeviceRole object."""
|
||||
role = MagicMock()
|
||||
role.id = 1
|
||||
role.name = "Access Switch"
|
||||
role.slug = "access-switch"
|
||||
return role
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_netbox_cluster():
|
||||
"""Mock NetBox Cluster object."""
|
||||
cluster = MagicMock()
|
||||
cluster.id = 1
|
||||
cluster.name = "VMware Cluster 1"
|
||||
return cluster
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_netbox_rack():
|
||||
"""Mock NetBox Rack object."""
|
||||
rack = MagicMock()
|
||||
rack.id = 1
|
||||
rack.name = "Rack A1"
|
||||
rack.site = MagicMock(id=1, name="DC1")
|
||||
return rack
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Server Mapping Fixtures (used by test_sync_view_mismatch.py)
|
||||
# =============================================================================
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_plugins_config_single_server():
|
||||
"""PLUGINS_CONFIG with a single 'production' server (for _build_all_server_mappings tests)."""
|
||||
return {
|
||||
"netbox_librenms_plugin": {
|
||||
"servers": {
|
||||
"production": {
|
||||
"display_name": "Production LibreNMS",
|
||||
"librenms_url": "https://librenms.example.com",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_plugins_config_empty_servers():
|
||||
"""PLUGINS_CONFIG with no configured servers (simulates all orphaned)."""
|
||||
return {"netbox_librenms_plugin": {"servers": {}}}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_plugins_config_multi_server_mapping():
|
||||
"""PLUGINS_CONFIG with 'production' and 'mock-dev' servers (for multi-server mapping tests)."""
|
||||
return {
|
||||
"netbox_librenms_plugin": {
|
||||
"servers": {
|
||||
"production": {
|
||||
"display_name": "Production LibreNMS",
|
||||
"librenms_url": "https://librenms.example.com",
|
||||
},
|
||||
"mock-dev": {
|
||||
"display_name": "Mock",
|
||||
"librenms_url": "http://mock.example.com",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user