Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions netbox/dcim/svg/cables.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def draw_object_terminations(self, terminations, offset_x, width):
nodes_height = 0
nodes = []
# Sort them by name to make renders more readable
for i, term in enumerate(sorted(terminations, key=lambda x: x.name)):
for i, term in enumerate(sorted(terminations, key=lambda x: str(x))):
node = Node(
position=(offset_x + i * width, self.cursor),
width=width,
Expand Down Expand Up @@ -266,7 +266,7 @@ def draw_far_objects(self, obj_list, terminations):
Draw the far-end objects and its terminations and return all created nodes
"""
# Make sure elements are sorted by name for readability
objects = sorted(obj_list, key=lambda x: x.name)
objects = sorted(obj_list, key=lambda x: str(x))
width = self.width / len(objects)

# Max-height of created terminations
Expand Down Expand Up @@ -361,7 +361,8 @@ def render(self):
# Connector (a Cable or WirelessLink)
if links:

parent_object_nodes, far_terminations = self.draw_far_objects(set(end.parent_object for end in far_ends), far_ends)
obj_list = {end.parent_object for end in far_ends}
parent_object_nodes, far_terminations = self.draw_far_objects(obj_list, far_ends)
for cable in links:
# Fill in labels and description with all available data
description = [
Expand Down
63 changes: 63 additions & 0 deletions netbox/dcim/tests/test_cablepaths.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,9 @@ def test_201_single_path_via_pass_through(self):
)
self.assertEqual(CablePath.objects.count(), 2)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 2
cable2.delete()
path1 = self.assertPathExists(
Expand Down Expand Up @@ -450,6 +453,9 @@ def test_202_single_path_via_pass_through_with_breakouts(self):
)
self.assertEqual(CablePath.objects.count(), 2)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 2
cable2.delete()
path1 = self.assertPathExists(
Expand Down Expand Up @@ -558,6 +564,9 @@ def test_203_multiple_paths_via_pass_through(self):
)
self.assertEqual(CablePath.objects.count(), 4)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 3
cable3.delete()

Expand Down Expand Up @@ -673,6 +682,9 @@ def test_204_multiple_paths_via_pass_through_with_breakouts(self):
)
self.assertEqual(CablePath.objects.count(), 4)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 3
cable3.delete()

Expand Down Expand Up @@ -804,6 +816,9 @@ def test_205_multiple_paths_via_nested_pass_throughs(self):
)
self.assertEqual(CablePath.objects.count(), 4)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 3
cable3.delete()

Expand Down Expand Up @@ -931,6 +946,9 @@ def test_206_multiple_paths_via_multiple_pass_throughs(self):
)
self.assertEqual(CablePath.objects.count(), 4)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 5
cable5.delete()

Expand Down Expand Up @@ -1034,6 +1052,9 @@ def test_207_multiple_paths_via_patched_pass_throughs(self):
)
self.assertEqual(CablePath.objects.count(), 4)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 3
cable3.delete()

Expand Down Expand Up @@ -1093,6 +1114,9 @@ def test_208_unidirectional_split_paths(self):
)
self.assertEqual(CablePath.objects.count(), 3)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 1
cable1.delete()

Expand Down Expand Up @@ -1135,6 +1159,9 @@ def test_209_rearport_without_frontport(self):
)
self.assertEqual(CablePath.objects.count(), 1)

# Test SVG generation
CableTraceSVG(interface1).render()

def test_210_interface_to_circuittermination(self):
"""
[IF1] --C1-- [CT1]
Expand All @@ -1156,6 +1183,9 @@ def test_210_interface_to_circuittermination(self):
)
self.assertEqual(CablePath.objects.count(), 1)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 1
cable1.delete()
self.assertEqual(CablePath.objects.count(), 0)
Expand Down Expand Up @@ -1212,6 +1242,9 @@ def test_211_interface_to_interface_via_circuit(self):
)
self.assertEqual(CablePath.objects.count(), 2)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 2
cable2.delete()
path1 = self.assertPathExists(
Expand Down Expand Up @@ -1277,6 +1310,9 @@ def test_212_interface_to_interface_via_circuit_with_breakouts(self):
)
self.assertEqual(CablePath.objects.count(), 2)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 2
cable2.delete()
path1 = self.assertPathExists(
Expand Down Expand Up @@ -1314,6 +1350,9 @@ def test_213_interface_to_site_via_circuit(self):
)
self.assertEqual(CablePath.objects.count(), 1)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 1
cable1.delete()
self.assertEqual(CablePath.objects.count(), 0)
Expand Down Expand Up @@ -1342,6 +1381,9 @@ def test_214_interface_to_providernetwork_via_circuit(self):
self.assertEqual(CablePath.objects.count(), 1)
self.assertTrue(CablePath.objects.first().is_complete)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 1
cable1.delete()
self.assertEqual(CablePath.objects.count(), 0)
Expand Down Expand Up @@ -1439,6 +1481,9 @@ def test_215_multiple_paths_via_circuit(self):
)
self.assertEqual(CablePath.objects.count(), 4)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cables 3-4
cable3.delete()
cable4.delete()
Expand Down Expand Up @@ -1495,6 +1540,9 @@ def test_216_interface_to_interface_via_multiple_circuits(self):
)
self.assertEqual(CablePath.objects.count(), 2)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 2
cable2.delete()
path1 = self.assertPathExists(
Expand Down Expand Up @@ -1578,6 +1626,9 @@ def test_217_interface_to_interface_via_rear_ports(self):
)
self.assertEqual(CablePath.objects.count(), 2)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 2
cable2.delete()

Expand Down Expand Up @@ -1697,6 +1748,9 @@ def test_218_interfaces_to_interfaces_via_multiposition_rear_ports(self):
)
self.assertEqual(CablePath.objects.count(), 4)

# Test SVG generation
CableTraceSVG(interface1).render()

# Delete cable 3
cable3.delete()

Expand Down Expand Up @@ -1784,6 +1838,9 @@ def test_219_interface_to_interface_duplex_via_multiple_rearports(self):
)
self.assertEqual(CablePath.objects.count(), 2)

# Test SVG generation
CableTraceSVG(interface1).render()

def test_220_interface_to_interface_duplex_via_multiple_front_and_rear_ports(self):
"""
[IF1] --C1-- [FP1] [RP1] --C2-- [RP2] [FP2] --C3-- [IF2]
Expand Down Expand Up @@ -1877,6 +1934,9 @@ def test_220_interface_to_interface_duplex_via_multiple_front_and_rear_ports(sel
)
self.assertEqual(CablePath.objects.count(), 3)

# Test SVG generation
CableTraceSVG(interface1).render()

def test_221_non_symmetric_paths(self):
"""
[IF1] --C1-- [FP1] [RP1] --C2-- [RP2] [FP2] --C3-- -------------------------------------- [IF2]
Expand Down Expand Up @@ -1997,6 +2057,9 @@ def test_221_non_symmetric_paths(self):
)
self.assertEqual(CablePath.objects.count(), 3)

# Test SVG generation
CableTraceSVG(interface1).render()

def test_301_create_path_via_existing_cable(self):
"""
[IF1] --C1-- [FP1] [RP1] --C2-- [RP2] [FP2] --C3-- [IF2]
Expand Down