More elegant and comprehensive way to detect if a cable is already in the path

This commit is contained in:
Brian Tiemann 2024-11-17 19:26:52 -05:00
parent 11237c6736
commit 92a96a38d0
2 changed files with 16 additions and 15 deletions

View File

@ -546,7 +546,6 @@ class CablePath(models.Model):
is_split = False is_split = False
while terminations: while terminations:
prev_path = path.copy()
# Terminations must all be of the same type # Terminations must all be of the same type
assert all(isinstance(t, type(terminations[0])) for t in terminations[1:]) assert all(isinstance(t, type(terminations[0])) for t in terminations[1:])
@ -588,9 +587,19 @@ class CablePath(models.Model):
# Step 4: Record the links, keeping cables in order to allow for SVG rendering # Step 4: Record the links, keeping cables in order to allow for SVG rendering
cables = [] cables = []
loop_detected = False
for link in links: for link in links:
if object_to_path_node(link) not in cables: cable = object_to_path_node(link)
cables.append(object_to_path_node(link)) if cable not in cables:
# Detect infinite loop in cabling topology
for node in path:
if cable in node:
loop_detected = True
cables.append(cable)
if loop_detected:
logger.warning('Infinite loop detected while updating cable path trace')
break
path.append(cables) path.append(cables)
# Step 5: Update the path status if a link is not connected # Step 5: Update the path status if a link is not connected
@ -726,14 +735,6 @@ class CablePath(models.Model):
is_split = True is_split = True
break break
# Detect infinite loop in cabling topology
num_elements_added = len(path) - len(prev_path)
prev_elements_added = prev_path[-num_elements_added:]
elements_added = path[-num_elements_added:]
if elements_added == prev_elements_added:
logger.warning('Infinite loop detected while updating cable path trace')
break
return cls( return cls(
path=path, path=path,
is_complete=is_complete, is_complete=is_complete,

View File

@ -2373,12 +2373,12 @@ class CablePathTestCase(TestCase):
ct_rearport = ContentType.objects.get(app_label='dcim', model='rearport') ct_rearport = ContentType.objects.get(app_label='dcim', model='rearport')
cable_1 = Cable.objects.create() cable_1 = Cable.objects.create()
termination_1a = CableTermination.objects.create(cable=cable_1, cable_end='A', termination_type=ct_interface, termination_id=interface.id) CableTermination.objects.create(cable=cable_1, cable_end='A', termination_type=ct_interface, termination_id=interface.id)
termination_1b = CableTermination.objects.create(cable=cable_1, cable_end='B', termination_type=ct_frontport, termination_id=front_port_1.id) CableTermination.objects.create(cable=cable_1, cable_end='B', termination_type=ct_frontport, termination_id=front_port_1.id)
cable_2 = Cable.objects.create() cable_2 = Cable.objects.create()
termination_2a = CableTermination.objects.create(cable=cable_2, cable_end='A', termination_type=ct_frontport, termination_id=front_port_2.id) CableTermination.objects.create(cable=cable_2, cable_end='A', termination_type=ct_frontport, termination_id=front_port_2.id)
termination_2b = CableTermination.objects.create(cable=cable_2, cable_end='B', termination_type=ct_rearport, termination_id=rear_splice.id) CableTermination.objects.create(cable=cable_2, cable_end='B', termination_type=ct_rearport, termination_id=rear_splice.id)
cable_1._terminations_modified = True cable_1._terminations_modified = True
cable_1.save() cable_1.save()