693 lines
27 KiB
Python
693 lines
27 KiB
Python
"""Coverage tests for views/base/librenms_sync_view.py missing lines."""
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
|
|
def _make_view():
|
|
"""Create a BaseLibreNMSSyncView instance bypassing __init__."""
|
|
from netbox_librenms_plugin.views.base.librenms_sync_view import BaseLibreNMSSyncView
|
|
|
|
view = object.__new__(BaseLibreNMSSyncView)
|
|
view.request = MagicMock()
|
|
view.tab = "librenms_sync"
|
|
view.model = MagicMock()
|
|
view.queryset = MagicMock()
|
|
view.kwargs = {}
|
|
view._librenms_api = MagicMock()
|
|
view._librenms_api.server_key = "default"
|
|
view._librenms_api.librenms_url = "https://x.example.com"
|
|
view._librenms_api.cache_timeout = 300
|
|
return view
|
|
|
|
|
|
class TestBaseLibreNMSSyncViewGet:
|
|
"""Tests for get() method (lines 29-53)."""
|
|
|
|
@patch("netbox_librenms_plugin.views.base.librenms_sync_view.render")
|
|
@patch("netbox_librenms_plugin.views.base.librenms_sync_view.get_object_or_404")
|
|
def test_get_non_vc_device(self, mock_get_obj, mock_render):
|
|
"""Non-VC device: librenms_lookup_device stays as obj."""
|
|
view = _make_view()
|
|
|
|
obj = MagicMock()
|
|
obj.virtual_chassis = None
|
|
mock_get_obj.return_value = obj
|
|
|
|
view._librenms_api = MagicMock()
|
|
view._librenms_api.server_key = "default"
|
|
view._librenms_api.get_librenms_id.return_value = 42
|
|
|
|
view.get_context_data = MagicMock(return_value={"test": "ctx"})
|
|
mock_render.return_value = MagicMock()
|
|
|
|
request = MagicMock()
|
|
view.get(request, pk=1)
|
|
|
|
# lookup device should be obj
|
|
assert view._librenms_lookup_device is obj
|
|
|
|
@patch("netbox_librenms_plugin.views.base.librenms_sync_view.render")
|
|
@patch("netbox_librenms_plugin.views.base.librenms_sync_view.get_object_or_404")
|
|
@patch("netbox_librenms_plugin.views.base.librenms_sync_view.get_librenms_sync_device")
|
|
def test_get_vc_member_always_delegates_to_sync_device(self, mock_get_sync, mock_get_obj, mock_render):
|
|
"""VC member: no own librenms_id - get_librenms_sync_device returns VC primary."""
|
|
view = _make_view()
|
|
|
|
obj = MagicMock()
|
|
obj.virtual_chassis = MagicMock()
|
|
mock_get_obj.return_value = obj
|
|
|
|
vc_primary = MagicMock() # Represents the VC primary device
|
|
mock_get_sync.return_value = vc_primary
|
|
|
|
view._librenms_api = MagicMock()
|
|
view._librenms_api.server_key = "default"
|
|
view._librenms_api.get_librenms_id.return_value = 99
|
|
|
|
view.get_context_data = MagicMock(return_value={})
|
|
mock_render.return_value = MagicMock()
|
|
|
|
request = MagicMock()
|
|
view.get(request, pk=1)
|
|
|
|
mock_get_sync.assert_called_once_with(obj, server_key="default")
|
|
# When member has no own ID, lookup uses the VC primary returned by get_librenms_sync_device
|
|
assert view._librenms_lookup_device is vc_primary
|
|
|
|
@patch("netbox_librenms_plugin.views.base.librenms_sync_view.render")
|
|
@patch("netbox_librenms_plugin.views.base.librenms_sync_view.get_object_or_404")
|
|
@patch("netbox_librenms_plugin.views.base.librenms_sync_view.get_librenms_sync_device")
|
|
def test_get_vc_member_with_own_librenms_id_uses_itself(self, mock_get_sync, mock_get_obj, mock_render):
|
|
"""VC member: has own librenms_id - get_librenms_sync_device still called, returns member itself."""
|
|
view = _make_view()
|
|
|
|
obj = MagicMock()
|
|
obj.virtual_chassis = MagicMock()
|
|
mock_get_obj.return_value = obj
|
|
|
|
# get_librenms_sync_device returns obj itself (member has own librenms_id, priority 1)
|
|
mock_get_sync.return_value = obj
|
|
|
|
view._librenms_api = MagicMock()
|
|
view._librenms_api.server_key = "default"
|
|
view._librenms_api.get_librenms_id.return_value = 55
|
|
|
|
view.get_context_data = MagicMock(return_value={})
|
|
mock_render.return_value = MagicMock()
|
|
|
|
request = MagicMock()
|
|
view.get(request, pk=1)
|
|
|
|
mock_get_sync.assert_called_once_with(obj, server_key="default")
|
|
# When member has its own ID, get_librenms_sync_device returns the member itself
|
|
assert view._librenms_lookup_device is obj
|
|
|
|
@patch("netbox_librenms_plugin.views.base.librenms_sync_view.render")
|
|
@patch("netbox_librenms_plugin.views.base.librenms_sync_view.get_object_or_404")
|
|
@patch("netbox_librenms_plugin.views.base.librenms_sync_view.get_librenms_sync_device")
|
|
def test_get_vc_member_no_sync_device_falls_back_to_obj(self, mock_get_sync, mock_get_obj, mock_render):
|
|
"""VC member: when get_librenms_sync_device returns None, keeps obj."""
|
|
view = _make_view()
|
|
|
|
obj = MagicMock()
|
|
obj.virtual_chassis = MagicMock()
|
|
mock_get_obj.return_value = obj
|
|
|
|
mock_get_sync.return_value = None
|
|
|
|
view._librenms_api = MagicMock()
|
|
view._librenms_api.server_key = "default"
|
|
view._librenms_api.get_librenms_id.return_value = 55
|
|
|
|
view.get_context_data = MagicMock(return_value={})
|
|
mock_render.return_value = MagicMock()
|
|
|
|
request = MagicMock()
|
|
view.get(request, pk=1)
|
|
|
|
mock_get_sync.assert_called_once_with(obj, server_key="default")
|
|
assert view._librenms_lookup_device is obj
|
|
|
|
|
|
class TestGetContextDataVC:
|
|
"""Tests for get_context_data() VC context (lines 69-91)."""
|
|
|
|
def test_vc_context_sync_device_has_id_and_ip(self):
|
|
"""VC device: sync_device_has_librenms_id and sync_device_has_primary_ip set."""
|
|
view = _make_view()
|
|
view.librenms_id = 42
|
|
view._librenms_lookup_device = MagicMock()
|
|
|
|
obj = MagicMock()
|
|
obj.virtual_chassis = MagicMock()
|
|
obj._meta = MagicMock()
|
|
obj._meta.model_name = "device"
|
|
|
|
sync_device = MagicMock()
|
|
sync_device.primary_ip = MagicMock()
|
|
sync_device._meta.model_name = "device"
|
|
sync_device.pk = 10
|
|
|
|
view._librenms_api = MagicMock()
|
|
view._librenms_api.server_key = "default"
|
|
view._librenms_api.librenms_url = "https://x.example.com"
|
|
|
|
view.get_librenms_device_info = MagicMock(
|
|
return_value={
|
|
"found_in_librenms": True,
|
|
"librenms_device_details": {
|
|
"librenms_device_serial": "SN001",
|
|
"librenms_device_hardware": "Cisco",
|
|
"librenms_device_os": "ios",
|
|
"librenms_device_version": "16.9",
|
|
"librenms_device_features": "-",
|
|
"librenms_device_location": "NYC",
|
|
"librenms_device_hardware_match": None,
|
|
"vc_inventory_serials": [],
|
|
},
|
|
"mismatched_device": False,
|
|
}
|
|
)
|
|
view.get_interface_context = MagicMock(return_value=None)
|
|
view.get_cable_context = MagicMock(return_value=None)
|
|
view.get_ip_context = MagicMock(return_value=None)
|
|
view.get_vlan_context = MagicMock(return_value=None)
|
|
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.get_librenms_sync_device") as mock_sync:
|
|
mock_sync.return_value = sync_device
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.get_librenms_device_id") as mock_id:
|
|
mock_id.return_value = 42
|
|
with patch(
|
|
"netbox_librenms_plugin.views.base.librenms_sync_view.get_interface_name_field",
|
|
return_value="ifName",
|
|
):
|
|
with patch(
|
|
"netbox_librenms_plugin.views.base.librenms_sync_view.BaseLibreNMSSyncView._build_all_server_mappings",
|
|
return_value=None,
|
|
):
|
|
with patch(
|
|
"netbox_librenms_plugin.views.base.librenms_sync_view.BaseLibreNMSSyncView._get_platform_info",
|
|
return_value={},
|
|
):
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.AddToLIbreSNMPV1V2"):
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.AddToLIbreSNMPV3"):
|
|
with patch("dcim.models.Manufacturer") as MockMfr:
|
|
MockMfr.objects.all.return_value.order_by.return_value = []
|
|
with patch.object(view, "get_context_data", wraps=view.get_context_data):
|
|
# Call parent get_context_data via a mock of super()
|
|
with patch(
|
|
"netbox_librenms_plugin.views.base.librenms_sync_view.LibreNMSAPIMixin.get_context_data",
|
|
return_value={},
|
|
):
|
|
ctx = view.get_context_data(MagicMock(), obj)
|
|
|
|
assert ctx.get("is_vc_member") is True
|
|
assert ctx.get("sync_device_has_librenms_id") is True
|
|
assert ctx.get("sync_device_has_primary_ip") is True
|
|
|
|
|
|
class TestBuildAllServerMappings:
|
|
"""Tests for _build_all_server_mappings (lines 181, 193, 200, 207-208)."""
|
|
|
|
def test_returns_none_for_non_dict_cf(self):
|
|
from netbox_librenms_plugin.views.base.librenms_sync_view import BaseLibreNMSSyncView
|
|
|
|
obj = MagicMock()
|
|
obj.custom_field_data = {"librenms_id": 42} # legacy bare int
|
|
result = BaseLibreNMSSyncView._build_all_server_mappings(obj, "default")
|
|
assert result is None
|
|
|
|
def test_returns_none_for_empty_dict_cf(self):
|
|
from netbox_librenms_plugin.views.base.librenms_sync_view import BaseLibreNMSSyncView
|
|
|
|
obj = MagicMock()
|
|
obj.custom_field_data = {"librenms_id": {}}
|
|
result = BaseLibreNMSSyncView._build_all_server_mappings(obj, "default")
|
|
assert result is None
|
|
|
|
def test_valid_dict_cf_returns_list(self):
|
|
from netbox_librenms_plugin.views.base.librenms_sync_view import BaseLibreNMSSyncView
|
|
|
|
obj = MagicMock()
|
|
obj.custom_field_data = {"librenms_id": {"default": 42, "secondary": 99}}
|
|
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.django_settings") as mock_settings:
|
|
mock_settings.PLUGINS_CONFIG = {
|
|
"netbox_librenms_plugin": {
|
|
"servers": {
|
|
"default": {"librenms_url": "https://x.example.com", "display_name": "Default"},
|
|
"secondary": {"librenms_url": "https://y.example.com", "display_name": "Secondary"},
|
|
}
|
|
}
|
|
}
|
|
result = BaseLibreNMSSyncView._build_all_server_mappings(obj, "default")
|
|
|
|
assert result is not None
|
|
assert len(result) == 2
|
|
# Active server should be first
|
|
assert result[0]["is_active"] is True
|
|
assert result[0]["server_key"] == "default"
|
|
|
|
def test_bool_value_skipped(self):
|
|
from netbox_librenms_plugin.views.base.librenms_sync_view import BaseLibreNMSSyncView
|
|
|
|
obj = MagicMock()
|
|
obj.custom_field_data = {"librenms_id": {"default": True, "other": 42}}
|
|
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.django_settings") as mock_settings:
|
|
mock_settings.PLUGINS_CONFIG = {
|
|
"netbox_librenms_plugin": {
|
|
"servers": {"other": {"librenms_url": "https://x.example.com", "display_name": "Other"}}
|
|
}
|
|
}
|
|
result = BaseLibreNMSSyncView._build_all_server_mappings(obj, "default")
|
|
|
|
assert result is not None
|
|
assert len(result) == 1
|
|
assert result[0]["server_key"] == "other"
|
|
|
|
def test_string_device_id_converted_to_int(self):
|
|
from netbox_librenms_plugin.views.base.librenms_sync_view import BaseLibreNMSSyncView
|
|
|
|
obj = MagicMock()
|
|
obj.custom_field_data = {"librenms_id": {"default": "77"}}
|
|
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.django_settings") as mock_settings:
|
|
mock_settings.PLUGINS_CONFIG = {
|
|
"netbox_librenms_plugin": {
|
|
"servers": {"default": {"librenms_url": "https://x.example.com", "display_name": "Default"}}
|
|
}
|
|
}
|
|
result = BaseLibreNMSSyncView._build_all_server_mappings(obj, "default")
|
|
|
|
assert result[0]["device_id"] == 77
|
|
|
|
def test_non_digit_string_skipped(self):
|
|
from netbox_librenms_plugin.views.base.librenms_sync_view import BaseLibreNMSSyncView
|
|
|
|
obj = MagicMock()
|
|
obj.custom_field_data = {"librenms_id": {"default": "not-a-number"}}
|
|
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.django_settings") as mock_settings:
|
|
mock_settings.PLUGINS_CONFIG = {"netbox_librenms_plugin": {"servers": {}}}
|
|
result = BaseLibreNMSSyncView._build_all_server_mappings(obj, "default")
|
|
|
|
assert result is None
|
|
|
|
def test_legacy_default_key_falls_back_to_root_librenms_url(self):
|
|
"""'default' key with no matching servers entry uses root librenms_url."""
|
|
from netbox_librenms_plugin.views.base.librenms_sync_view import BaseLibreNMSSyncView
|
|
|
|
obj = MagicMock()
|
|
obj.custom_field_data = {"librenms_id": {"default": 42}}
|
|
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.django_settings") as mock_settings:
|
|
mock_settings.PLUGINS_CONFIG = {
|
|
"netbox_librenms_plugin": {
|
|
"librenms_url": "https://legacy.example.com",
|
|
"display_name": "Legacy Server",
|
|
"servers": {},
|
|
}
|
|
}
|
|
result = BaseLibreNMSSyncView._build_all_server_mappings(obj, "default")
|
|
|
|
assert result is not None
|
|
assert result[0]["librenms_url"] == "https://legacy.example.com"
|
|
|
|
def test_malformed_server_config_treated_as_unconfigured(self):
|
|
"""Non-dict server config entry → is_configured=False."""
|
|
from netbox_librenms_plugin.views.base.librenms_sync_view import BaseLibreNMSSyncView
|
|
|
|
obj = MagicMock()
|
|
obj.custom_field_data = {"librenms_id": {"default": 42}}
|
|
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.django_settings") as mock_settings:
|
|
mock_settings.PLUGINS_CONFIG = {"netbox_librenms_plugin": {"servers": {"default": "this-is-not-a-dict"}}}
|
|
result = BaseLibreNMSSyncView._build_all_server_mappings(obj, "default")
|
|
|
|
assert result is not None
|
|
assert result[0]["is_configured"] is False
|
|
|
|
|
|
class TestGetLibreNMSDeviceInfo:
|
|
"""Tests for get_librenms_device_info (lines 228+)."""
|
|
|
|
def test_no_librenms_id_returns_defaults(self):
|
|
view = _make_view()
|
|
view.librenms_id = None
|
|
view._librenms_api = MagicMock()
|
|
|
|
obj = MagicMock()
|
|
result = view.get_librenms_device_info(obj)
|
|
|
|
assert result["found_in_librenms"] is False
|
|
assert result["mismatched_device"] is False
|
|
|
|
def test_librenms_id_success_sets_found(self):
|
|
view = _make_view()
|
|
view.librenms_id = 42
|
|
view._librenms_api = MagicMock()
|
|
view._librenms_api.librenms_url = "https://x.example.com"
|
|
|
|
obj = MagicMock()
|
|
obj.primary_ip = None
|
|
obj.name = "mydevice"
|
|
obj.virtual_chassis = None
|
|
obj.serial = "SN001"
|
|
obj.platform = None
|
|
|
|
device_info = {
|
|
"hardware": "Cisco C9300",
|
|
"serial": "SN001",
|
|
"os": "ios",
|
|
"version": "16.9",
|
|
"features": "-",
|
|
"sysName": "mydevice",
|
|
"hostname": "mydevice.example.com",
|
|
"ip": "10.0.0.1",
|
|
"location": "NYC",
|
|
}
|
|
view._librenms_api.get_device_info.return_value = (True, device_info)
|
|
|
|
with patch(
|
|
"netbox_librenms_plugin.views.base.librenms_sync_view.match_librenms_hardware_to_device_type"
|
|
) as mock_match:
|
|
mock_match.return_value = {"matched": False, "device_type": None, "match_type": None}
|
|
result = view.get_librenms_device_info(obj)
|
|
|
|
assert result["found_in_librenms"] is True
|
|
|
|
def test_mismatched_device_when_names_differ(self):
|
|
view = _make_view()
|
|
view.librenms_id = 42
|
|
view._librenms_api = MagicMock()
|
|
view._librenms_api.librenms_url = "https://x.example.com"
|
|
|
|
obj = MagicMock()
|
|
obj.primary_ip = None
|
|
obj.name = "device-netbox"
|
|
obj.virtual_chassis = None
|
|
obj.serial = ""
|
|
obj.platform = None
|
|
|
|
device_info = {
|
|
"hardware": "-",
|
|
"serial": "-",
|
|
"os": "-",
|
|
"version": "-",
|
|
"features": "-",
|
|
"sysName": "completely-different",
|
|
"hostname": "also-different.example.com",
|
|
"ip": "192.168.0.1",
|
|
"location": "-",
|
|
}
|
|
view._librenms_api.get_device_info.return_value = (True, device_info)
|
|
|
|
with patch(
|
|
"netbox_librenms_plugin.views.base.librenms_sync_view.match_librenms_hardware_to_device_type"
|
|
) as mock_match:
|
|
mock_match.return_value = {"matched": False, "device_type": None, "match_type": None}
|
|
with patch(
|
|
"netbox_librenms_plugin.views.base.librenms_sync_view.BaseLibreNMSSyncView._strip_vc_pattern",
|
|
return_value=None,
|
|
):
|
|
result = view.get_librenms_device_info(obj)
|
|
|
|
assert result["mismatched_device"] is True
|
|
|
|
|
|
class TestStripVcPattern:
|
|
"""Tests for _strip_vc_pattern (lines 378+)."""
|
|
|
|
def test_strips_default_pattern(self):
|
|
from netbox_librenms_plugin.views.base.librenms_sync_view import BaseLibreNMSSyncView
|
|
|
|
mock_settings_cls = MagicMock()
|
|
settings_obj = MagicMock()
|
|
settings_obj.vc_member_name_pattern = "-M{position}"
|
|
mock_settings_cls.objects.first.return_value = settings_obj
|
|
|
|
with patch("netbox_librenms_plugin.models.LibreNMSSettings", mock_settings_cls, create=True):
|
|
result = BaseLibreNMSSyncView._strip_vc_pattern("switch01-m2")
|
|
# The suffix -m2 should be stripped, returning "switch01"
|
|
assert result == "switch01" # suffix -m2 must be stripped
|
|
|
|
def test_returns_none_on_exception(self):
|
|
from netbox_librenms_plugin.views.base.librenms_sync_view import BaseLibreNMSSyncView
|
|
|
|
mock_settings_cls = MagicMock()
|
|
mock_settings_cls.objects.first.side_effect = Exception("DB error")
|
|
|
|
with patch("netbox_librenms_plugin.models.LibreNMSSettings", mock_settings_cls, create=True):
|
|
result = BaseLibreNMSSyncView._strip_vc_pattern("some-device")
|
|
assert result is None
|
|
|
|
|
|
class TestLibreNMSIdLegacyDetection:
|
|
"""Tests for librenms_id_is_legacy detection (lines 113-115)."""
|
|
|
|
def test_bare_int_cf_detected_as_legacy(self):
|
|
"""bare int CF → librenms_id_is_legacy = True."""
|
|
view = _make_view()
|
|
view.librenms_id = 42
|
|
view._librenms_lookup_device = MagicMock()
|
|
view._librenms_lookup_device.cf = {"librenms_id": 42}
|
|
|
|
obj = MagicMock()
|
|
obj.virtual_chassis = None
|
|
obj._meta = MagicMock()
|
|
obj._meta.model_name = "device"
|
|
obj.pk = 1
|
|
obj.serial = "SN"
|
|
obj.platform = None
|
|
|
|
view._librenms_api = MagicMock()
|
|
view._librenms_api.server_key = "default"
|
|
view._librenms_api.librenms_url = "https://x.example.com"
|
|
|
|
view.get_librenms_device_info = MagicMock(
|
|
return_value={
|
|
"found_in_librenms": True,
|
|
"librenms_device_details": {
|
|
"librenms_device_serial": "SN",
|
|
"librenms_device_hardware": "-",
|
|
"librenms_device_os": "-",
|
|
"librenms_device_version": "-",
|
|
"librenms_device_features": "-",
|
|
"librenms_device_location": "-",
|
|
"librenms_device_hardware_match": None,
|
|
"vc_inventory_serials": [],
|
|
},
|
|
"mismatched_device": False,
|
|
}
|
|
)
|
|
view.get_interface_context = MagicMock(return_value=None)
|
|
view.get_cable_context = MagicMock(return_value=None)
|
|
view.get_ip_context = MagicMock(return_value=None)
|
|
view.get_vlan_context = MagicMock(return_value=None)
|
|
|
|
with patch(
|
|
"netbox_librenms_plugin.views.base.librenms_sync_view.get_interface_name_field", return_value="ifName"
|
|
):
|
|
with patch(
|
|
"netbox_librenms_plugin.views.base.librenms_sync_view.BaseLibreNMSSyncView._build_all_server_mappings",
|
|
return_value=None,
|
|
):
|
|
with patch(
|
|
"netbox_librenms_plugin.views.base.librenms_sync_view.BaseLibreNMSSyncView._get_platform_info",
|
|
return_value={},
|
|
):
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.AddToLIbreSNMPV1V2"):
|
|
with patch("netbox_librenms_plugin.views.base.librenms_sync_view.AddToLIbreSNMPV3"):
|
|
with patch("dcim.models.Manufacturer") as MockMfr:
|
|
MockMfr.objects.all.return_value.order_by.return_value = []
|
|
with patch(
|
|
"netbox_librenms_plugin.views.base.librenms_sync_view.LibreNMSAPIMixin.get_context_data",
|
|
return_value={},
|
|
):
|
|
ctx = view.get_context_data(MagicMock(), obj)
|
|
|
|
assert ctx.get("librenms_id_is_legacy") is True
|
|
|
|
|
|
class TestAbstractMethods:
|
|
"""Tests for abstract get_*_context methods (lines 349-376)."""
|
|
|
|
def test_get_interface_context_returns_none(self):
|
|
view = _make_view()
|
|
result = view.get_interface_context(MagicMock(), MagicMock())
|
|
assert result is None
|
|
|
|
def test_get_cable_context_returns_none(self):
|
|
view = _make_view()
|
|
result = view.get_cable_context(MagicMock(), MagicMock())
|
|
assert result is None
|
|
|
|
def test_get_ip_context_returns_none(self):
|
|
view = _make_view()
|
|
result = view.get_ip_context(MagicMock(), MagicMock())
|
|
assert result is None
|
|
|
|
def test_get_vlan_context_returns_none(self):
|
|
view = _make_view()
|
|
result = view.get_vlan_context(MagicMock(), MagicMock())
|
|
assert result is None
|
|
|
|
|
|
class TestGetVCInventorySerials:
|
|
"""Tests for _get_vc_inventory_serials (lines 412-452)."""
|
|
|
|
def test_no_inventory_returns_empty(self):
|
|
view = _make_view()
|
|
view.librenms_id = 42
|
|
view._librenms_api.get_device_inventory.return_value = (False, [])
|
|
|
|
obj = MagicMock()
|
|
obj.virtual_chassis = MagicMock()
|
|
obj.virtual_chassis.members.all.return_value = []
|
|
|
|
result = view._get_vc_inventory_serials(obj)
|
|
assert result == []
|
|
|
|
def test_chassis_components_matched(self):
|
|
view = _make_view()
|
|
view.librenms_id = 42
|
|
|
|
inventory = [
|
|
{
|
|
"entPhysicalClass": "chassis",
|
|
"entPhysicalSerialNum": "SN001",
|
|
"entPhysicalDescr": "Chassis",
|
|
"entPhysicalModelName": "C9300",
|
|
},
|
|
{
|
|
"entPhysicalClass": "module",
|
|
"entPhysicalSerialNum": "SN002",
|
|
"entPhysicalDescr": "Module",
|
|
"entPhysicalModelName": "",
|
|
},
|
|
]
|
|
view._librenms_api.get_device_inventory.return_value = (True, inventory)
|
|
|
|
member = MagicMock()
|
|
member.serial = "SN001"
|
|
|
|
obj = MagicMock()
|
|
obj.virtual_chassis = MagicMock()
|
|
obj.virtual_chassis.members.all.return_value = [member]
|
|
|
|
result = view._get_vc_inventory_serials(obj)
|
|
assert len(result) == 1
|
|
assert result[0]["serial"] == "SN001"
|
|
assert result[0]["assigned_member"] is member
|
|
|
|
def test_unassigned_serial_returns_none_member(self):
|
|
view = _make_view()
|
|
view.librenms_id = 42
|
|
|
|
inventory = [
|
|
{
|
|
"entPhysicalClass": "chassis",
|
|
"entPhysicalSerialNum": "UNKNOWN_SN",
|
|
"entPhysicalDescr": "Chassis",
|
|
"entPhysicalModelName": "MX480",
|
|
},
|
|
]
|
|
view._librenms_api.get_device_inventory.return_value = (True, inventory)
|
|
|
|
member = MagicMock()
|
|
member.serial = "SN001" # Different serial
|
|
|
|
obj = MagicMock()
|
|
obj.virtual_chassis = MagicMock()
|
|
obj.virtual_chassis.members.all.return_value = [member]
|
|
|
|
result = view._get_vc_inventory_serials(obj)
|
|
assert len(result) == 1
|
|
assert result[0]["assigned_member"] is None
|
|
|
|
def test_empty_serial_skipped(self):
|
|
view = _make_view()
|
|
view.librenms_id = 42
|
|
|
|
inventory = [
|
|
{
|
|
"entPhysicalClass": "chassis",
|
|
"entPhysicalSerialNum": "-",
|
|
"entPhysicalDescr": "Chassis",
|
|
"entPhysicalModelName": "",
|
|
},
|
|
]
|
|
view._librenms_api.get_device_inventory.return_value = (True, inventory)
|
|
|
|
obj = MagicMock()
|
|
obj.virtual_chassis = MagicMock()
|
|
obj.virtual_chassis.members.all.return_value = []
|
|
|
|
result = view._get_vc_inventory_serials(obj)
|
|
assert result == []
|
|
|
|
|
|
class TestGetPlatformInfo:
|
|
"""Tests for _get_platform_info (lines 463-502)."""
|
|
|
|
def test_no_os_returns_no_platform(self):
|
|
view = _make_view()
|
|
obj = MagicMock()
|
|
obj.platform = None
|
|
|
|
librenms_info = {
|
|
"librenms_device_details": {
|
|
"librenms_device_os": "-",
|
|
"librenms_device_version": "-",
|
|
}
|
|
}
|
|
|
|
with patch("dcim.models.Platform") as MockPlatform:
|
|
MockPlatform.DoesNotExist = type("DoesNotExist", (Exception,), {})
|
|
MockPlatform.objects.get.side_effect = MockPlatform.DoesNotExist()
|
|
result = view._get_platform_info(librenms_info, obj)
|
|
|
|
assert result["platform_exists"] is False
|
|
assert result["platform_name"] is None
|
|
|
|
def test_matching_platform_found(self):
|
|
view = _make_view()
|
|
obj = MagicMock()
|
|
mock_platform = MagicMock()
|
|
|
|
librenms_info = {
|
|
"librenms_device_details": {
|
|
"librenms_device_os": "ios",
|
|
"librenms_device_version": "16.9",
|
|
}
|
|
}
|
|
|
|
with patch("dcim.models.Platform") as MockPlatform:
|
|
MockPlatform.DoesNotExist = type("DoesNotExist", (Exception,), {})
|
|
MockPlatform.objects.get.return_value = mock_platform
|
|
result = view._get_platform_info(librenms_info, obj)
|
|
|
|
assert result["platform_exists"] is True
|
|
assert result["matching_platform"] is mock_platform
|
|
|
|
def test_platform_does_not_exist(self):
|
|
view = _make_view()
|
|
obj = MagicMock()
|
|
obj.platform = None
|
|
|
|
librenms_info = {
|
|
"librenms_device_details": {
|
|
"librenms_device_os": "eos",
|
|
"librenms_device_version": "4.28",
|
|
}
|
|
}
|
|
|
|
with patch("dcim.models.Platform") as MockPlatform:
|
|
MockPlatform.DoesNotExist = type("DoesNotExist", (Exception,), {})
|
|
MockPlatform.objects.get.side_effect = MockPlatform.DoesNotExist()
|
|
result = view._get_platform_info(librenms_info, obj)
|
|
|
|
assert result["platform_exists"] is False
|
|
assert result["matching_platform"] is None
|