Files
netbox-librenms-plugin/netbox_librenms_plugin/tests/conftest.py
Vlastislav Svatek 673e67106e
Some checks failed
ci / deploy (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
first commit
2026-06-05 10:39:05 +02:00

337 lines
9.5 KiB
Python

"""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",
},
}
}
}