Cleanup; updated tests

This commit is contained in:
Jeremy Stretch
2025-12-12 10:26:01 -05:00
parent 15c32d44e7
commit 144f23444b
9 changed files with 56 additions and 38 deletions

View File

@@ -353,7 +353,7 @@ class CircuitTerminationFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet):
model = CircuitTermination
fields = (
'id', 'termination_id', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'description',
'mark_connected', 'pp_info', 'cable_end',
'mark_connected', 'pp_info', 'cable_end', 'cable_connector',
)
def search(self, queryset, name, value):

View File

@@ -433,7 +433,7 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests):
queryset = CircuitTermination.objects.all()
filterset = CircuitTerminationFilterSet
ignore_fields = ('cable',)
ignore_fields = ('cable', 'cable_positions')
@classmethod
def setUpTestData(cls):

View File

@@ -61,11 +61,11 @@ class CableTerminationSerializer(NetBoxModelSerializer):
model = CableTermination
fields = [
'id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id',
'termination', 'position', 'created', 'last_updated',
'termination', 'positions', 'created', 'last_updated',
]
read_only_fields = fields
brief_fields = (
'id', 'url', 'display', 'cable', 'cable_end', 'position', 'termination_type', 'termination_id',
'id', 'url', 'display', 'cable', 'cable_end', 'positions', 'termination_type', 'termination_id',
)

View File

@@ -1,29 +1,37 @@
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from dcim.models import CableTermination
class BaseCableProfile:
def clean(self, cable):
pass
# # Enforce maximum connection limits
# if self.a_max_connections and len(cable.a_terminations) > self.a_max_connections:
# raise ValidationError({
# 'a_terminations': _(
# 'Maximum A side connections for profile {profile}: {max}'
# ).format(
# profile=cable.get_profile_display(),
# max=self.a_max_connections,
# )
# })
# if self.b_max_connections and len(cable.b_terminations) > self.b_max_connections:
# raise ValidationError({
# 'b_terminations': _(
# 'Maximum B side connections for profile {profile}: {max}'
# ).format(
# profile=cable.get_profile_display(),
# max=self.b_max_connections,
# )
# })
# Enforce maximum terminations limits
a_terminations_count = len(cable.a_terminations)
b_terminations_count = len(cable.b_terminations)
max_a_terminations = len(self.a_connectors)
max_b_terminations = len(self.b_connectors)
if a_terminations_count > max_a_terminations:
raise ValidationError({
'a_terminations': _(
'A side of cable has {count} terminations but only {max} are permitted for profile {profile}'
).format(
count=a_terminations_count,
profile=cable.get_profile_display(),
max=max_a_terminations,
)
})
if b_terminations_count > max_b_terminations:
raise ValidationError({
'b_terminations': _(
'B side of cable has {count} terminations but only {max} are permitted for profile {profile}'
).format(
count=b_terminations_count,
profile=cable.get_profile_display(),
max=max_b_terminations,
)
})
def get_mapped_position(self, side, connector, position):
"""
@@ -36,14 +44,11 @@ class BaseCableProfile:
"""
Given a terminating object, return the peer terminating object (if any) on the opposite end of the cable.
"""
print(f'get_peer_termination({termination}, {position})')
print(f' Mapping {termination.cable_end} {termination.cable_connector}:{position}...')
connector, position = self.get_mapped_position(
termination.cable_end,
termination.cable_connector,
position
)
print(f' Mapped to {connector}:{position}')
try:
ct = CableTermination.objects.get(
cable=termination.cable,
@@ -51,10 +56,8 @@ class BaseCableProfile:
connector=connector,
positions__contains=[position],
)
print(f' Found termination {ct.termination}')
return ct.termination, position
except CableTermination.DoesNotExist:
print(f' Failed to resolve far end termination for {connector}:{position}')
return None, None

View File

@@ -1748,7 +1748,9 @@ class ConsolePortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSe
class Meta:
model = ConsolePort
fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end')
fields = (
'id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end', 'cable_connector',
)
@register_filterset
@@ -1760,7 +1762,9 @@ class ConsoleServerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFi
class Meta:
model = ConsoleServerPort
fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end')
fields = (
'id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end', 'cable_connector',
)
@register_filterset
@@ -1774,6 +1778,7 @@ class PowerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet,
model = PowerPort
fields = (
'id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description', 'mark_connected', 'cable_end',
'cable_connector',
)
@@ -1800,6 +1805,7 @@ class PowerOutletFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSe
model = PowerOutlet
fields = (
'id', 'name', 'status', 'label', 'feed_leg', 'description', 'color', 'mark_connected', 'cable_end',
'cable_connector',
)
@@ -2109,7 +2115,7 @@ class InterfaceFilterSet(
fields = (
'id', 'name', 'label', 'type', 'enabled', 'mtu', 'mgmt_only', 'poe_mode', 'poe_type', 'mode', 'rf_role',
'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'description', 'mark_connected',
'cable_id', 'cable_end',
'cable_id', 'cable_end', 'cable_connector',
)
def filter_virtual_chassis_member_or_master(self, queryset, name, value):
@@ -2165,6 +2171,7 @@ class FrontPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet)
model = FrontPort
fields = (
'id', 'name', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable_end',
'cable_connector',
)
@@ -2185,6 +2192,7 @@ class RearPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet):
model = RearPort
fields = (
'id', 'name', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable_end',
'cable_connector',
)
@@ -2659,7 +2667,7 @@ class PowerFeedFilterSet(PrimaryModelFilterSet, CabledObjectFilterSet, PathEndpo
model = PowerFeed
fields = (
'id', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization',
'available_power', 'mark_connected', 'cable_end', 'description',
'available_power', 'mark_connected', 'cable_end', 'cable_connector', 'description',
)
def search(self, queryset, name, value):

View File

@@ -532,7 +532,7 @@ class CableTermination(ChangeLoggedModel):
termination.cable = None
termination.cable_end = None
termination.cable_connector = None
termination.cable_position = None
termination.cable_positions = None
termination.save()
super().delete(*args, **kwargs)

View File

@@ -224,9 +224,9 @@ class CabledObjectModel(models.Model):
raise ValidationError({
"cable_end": _("Cable end must not be set without a cable.")
})
if self.cable_position and not self.cable:
if self.cable_positions and not self.cable:
raise ValidationError({
"cable_position": _("Cable termination position must not be set without a cable.")
"cable_positions": _("Cable termination positions must not be set without a cable.")
})
if self.mark_connected and self.cable:
raise ValidationError({

View File

@@ -2620,7 +2620,7 @@ class CableTerminationTest(
APIViewTestCases.ListObjectsViewTestCase,
):
model = CableTermination
brief_fields = ['cable', 'cable_end', 'display', 'id', 'position', 'termination_id', 'termination_type', 'url']
brief_fields = ['cable', 'cable_end', 'display', 'id', 'positions', 'termination_id', 'termination_type', 'url']
@classmethod
def setUpTestData(cls):

View File

@@ -3332,6 +3332,7 @@ class ModuleTestCase(TestCase, ChangeLoggedFilterSetTests):
class ConsolePortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = ConsolePort.objects.all()
filterset = ConsolePortFilterSet
ignore_fields = ('cable_positions',)
@classmethod
def setUpTestData(cls):
@@ -3582,6 +3583,7 @@ class ConsolePortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedF
class ConsoleServerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = ConsoleServerPort.objects.all()
filterset = ConsoleServerPortFilterSet
ignore_fields = ('cable_positions',)
@classmethod
def setUpTestData(cls):
@@ -3832,6 +3834,7 @@ class ConsoleServerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeL
class PowerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = PowerPort.objects.all()
filterset = PowerPortFilterSet
ignore_fields = ('cable_positions',)
@classmethod
def setUpTestData(cls):
@@ -4096,6 +4099,7 @@ class PowerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
class PowerOutletTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = PowerOutlet.objects.all()
filterset = PowerOutletFilterSet
ignore_fields = ('cable_positions',)
@classmethod
def setUpTestData(cls):
@@ -4380,7 +4384,7 @@ class PowerOutletTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedF
class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = Interface.objects.all()
filterset = InterfaceFilterSet
ignore_fields = ('tagged_vlans', 'untagged_vlan', 'qinq_svlan', 'vdcs')
ignore_fields = ('tagged_vlans', 'untagged_vlan', 'qinq_svlan', 'vdcs', 'cable_positions')
@classmethod
def setUpTestData(cls):
@@ -5017,6 +5021,7 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
class FrontPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = FrontPort.objects.all()
filterset = FrontPortFilterSet
ignore_fields = ('cable_positions',)
@classmethod
def setUpTestData(cls):
@@ -5321,6 +5326,7 @@ class FrontPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
class RearPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = RearPort.objects.all()
filterset = RearPortFilterSet
ignore_fields = ('cable_positions',)
@classmethod
def setUpTestData(cls):
@@ -6859,6 +6865,7 @@ class PowerPanelTestCase(TestCase, ChangeLoggedFilterSetTests):
class PowerFeedTestCase(TestCase, ChangeLoggedFilterSetTests):
queryset = PowerFeed.objects.all()
filterset = PowerFeedFilterSet
ignore_fields = ('cable_positions',)
@classmethod
def setUpTestData(cls):