Fixes #21653: Fix multi-position tracing in CablePath.from_origin() #142

Closed
opened 2026-04-05 16:22:13 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @jsenecal on 3/16/2026

Fixes: #21653

Summary

  • Fix CablePath.from_origin() to correctly trace cables when a termination has multiple positions, instead of only tracing the first position and discarding the rest
  • The position stack now preserves all positions from terminations[0].cable_positions and iterates over each when resolving peer terminations through cable profiles
  • Fix multi-connector tracing for trunk cables: stacked positions are now distributed to their owning terminations instead of always using terminations[0]
  • Add test coverage for multi-position and multi-connector cable path tracing scenarios

Bug 1: Multi-position loss

When a PathEndpoint had multiple cable positions (e.g. [1, 2, 3, 4]), the original code only pushed the first position onto the stack (cable_positions[0]) and only called get_peer_termination() once. This meant multi-position cables were incorrectly traced, losing position information along the path.

Bug 2: Multi-connector loss

When multiple terminations existed on different connectors of the same profiled cable (e.g. after a FrontPort fans out via PortMapping to two RearPorts on a Trunk2C2P), get_peer_termination() was only called with terminations[0]. Terminations on other connectors were dropped. See https://github.com/netbox-community/netbox/issues/21653#issuecomment-4069303962 for details.

Fix

Three changes in netbox/dcim/models/cables.py (steps from pre-existing comments):

  1. Step 1: push all positions onto the stack (list(terminations[0].cable_positions)) instead of just the first
  2. Step 6: build (termination, position) pairs by matching stacked positions to each termination's cable_positions, then call get_peer_termination() for each pair
  3. Step 6 fallback: preserve legacy behavior when positions don't match any cable_positions (e.g. empty position stack)

Tests

  • Added test_107: duplex interface through profiled cables and splice pass-throughs (1C2P)
  • Added test_108: positions seeded by PortMapping preserved across profiled cables
  • Added test_109: 4-position interface fanning out through patch panel to both connectors of a Trunk2C2P
  • Ran full cable path test suite: NETBOX_CONFIGURATION=netbox.configuration_testing python manage.py test dcim.tests.test_cablepaths dcim.tests.test_cablepaths2
  • All existing cable path tests pass with no regressions
*Originally created by @jsenecal on 3/16/2026* ### Fixes: #21653 **Summary** - Fix CablePath.from_origin() to correctly trace cables when a termination has multiple positions, instead of only tracing the first position and discarding the rest - The position stack now preserves all positions from terminations[0].cable_positions and iterates over each when resolving peer terminations through cable profiles - Fix multi-connector tracing for trunk cables: stacked positions are now distributed to their owning terminations instead of always using terminations[0] - Add test coverage for multi-position and multi-connector cable path tracing scenarios **Bug 1: Multi-position loss** When a PathEndpoint had multiple cable positions (e.g. [1, 2, 3, 4]), the original code only pushed the first position onto the stack (cable_positions[0]) and only called get_peer_termination() once. This meant multi-position cables were incorrectly traced, losing position information along the path. **Bug 2: Multi-connector loss** When multiple terminations existed on different connectors of the same profiled cable (e.g. after a FrontPort fans out via PortMapping to two RearPorts on a Trunk2C2P), get_peer_termination() was only called with terminations[0]. Terminations on other connectors were dropped. See https://github.com/netbox-community/netbox/issues/21653#issuecomment-4069303962 for details. **Fix** Three changes in netbox/dcim/models/cables.py (steps from pre-existing comments): 1. Step 1: push all positions onto the stack (list(terminations[0].cable_positions)) instead of just the first 2. Step 6: build (termination, position) pairs by matching stacked positions to each termination's cable_positions, then call get_peer_termination() for each pair 3. Step 6 fallback: preserve legacy behavior when positions don't match any cable_positions (e.g. empty position stack) **Tests** - Added test_107: duplex interface through profiled cables and splice pass-throughs (1C2P) - Added test_108: positions seeded by PortMapping preserved across profiled cables - Added test_109: 4-position interface fanning out through patch panel to both connectors of a Trunk2C2P - Ran full cable path test suite: NETBOX_CONFIGURATION=netbox.configuration_testing python manage.py test dcim.tests.test_cablepaths dcim.tests.test_cablepaths2 - All existing cable path tests pass with no regressions
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/netbox#142