def assertPathExists(self, origin, destination, path=None, is_active=None, msg=None): """ Assert that a CablePath from origin to destination with a specific intermediate path exists. :param origin: Originating endpoint :param destination: Terminating endpoint, or None :param path: Sequence of objects comprising the intermediate path (optional) :param is_active: Boolean indicating whether the end-to-end path is complete and active (optional) :param msg: Custom failure message (optional) :return: The matching CablePath (if any) """ kwargs = { 'origin_type': ContentType.objects.get_for_model(origin), 'origin_id': origin.pk, } if destination is not None: kwargs['destination_type'] = ContentType.objects.get_for_model(destination) kwargs['destination_id'] = destination.pk else: kwargs['destination_type__isnull'] = True kwargs['destination_id__isnull'] = True if path is not None: kwargs['path'] = [object_to_path_node(obj) for obj in path] if is_active is not None: kwargs['is_active'] = is_active if msg is None: if destination is not None: msg = f"Missing path from {origin} to {destination}" else: msg = f"Missing partial path originating from {origin}" cablepath = CablePath.objects.filter(**kwargs).first() self.assertIsNotNone(cablepath, msg=msg) return cablepath
def from_origin(cls, origin): """ Create a new CablePath instance as traced from the given path origin. """ from circuits.models import CircuitTermination if origin is None or origin.cable is None: return None destination = None path = [] position_stack = [] is_active = True is_split = False node = origin while node.cable is not None: if node.cable.status != CableStatusChoices.STATUS_CONNECTED: is_active = False # Follow the cable to its far-end termination path.append(object_to_path_node(node.cable)) peer_termination = node.get_cable_peer() # Follow a FrontPort to its corresponding RearPort if isinstance(peer_termination, FrontPort): path.append(object_to_path_node(peer_termination)) node = peer_termination.rear_port if node.positions > 1: position_stack.append(peer_termination.rear_port_position) path.append(object_to_path_node(node)) # Follow a RearPort to its corresponding FrontPort (if any) elif isinstance(peer_termination, RearPort): path.append(object_to_path_node(peer_termination)) # Determine the peer FrontPort's position if peer_termination.positions == 1: position = 1 elif position_stack: position = position_stack.pop() else: # No position indicated: path has split, so we stop at the RearPort is_split = True break try: node = FrontPort.objects.get(rear_port=peer_termination, rear_port_position=position) path.append(object_to_path_node(node)) except ObjectDoesNotExist: # No corresponding FrontPort found for the RearPort break # Follow a CircuitTermination to its corresponding CircuitTermination (A to Z or vice versa) elif isinstance(peer_termination, CircuitTermination): path.append(object_to_path_node(peer_termination)) # Get peer CircuitTermination node = peer_termination.get_peer_termination() if node: path.append(object_to_path_node(node)) if node.provider_network: destination = node.provider_network break elif node.site and not node.cable: destination = node.site break else: # No peer CircuitTermination exists; halt the trace break # Anything else marks the end of the path else: destination = peer_termination break if destination is None: is_active = False return cls(origin=origin, destination=destination, path=path, is_active=is_active, is_split=is_split)
def get_prep_lookup(self): self.rhs = [object_to_path_node(self.rhs)] return super().get_prep_lookup()