Merge remote-tracking branch 'origin/feature/1789-add-convenience-methods-to-network-object' into feature/1801-Database

This commit is contained in:
Marek Wolan
2023-08-29 13:22:14 +01:00
4 changed files with 44 additions and 30 deletions

View File

@@ -1,6 +1,6 @@
"""Core of the PrimAITE Simulator.""" """Core of the PrimAITE Simulator."""
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Callable, Dict, List, Optional from typing import Callable, Dict, List, Optional, Union
from uuid import uuid4 from uuid import uuid4
from pydantic import BaseModel, ConfigDict, Extra from pydantic import BaseModel, ConfigDict, Extra
@@ -224,9 +224,9 @@ class SimComponent(BaseModel):
return self._parent return self._parent
@parent.setter @parent.setter
def parent(self, new_parent: "SimComponent") -> None: def parent(self, new_parent: Union["SimComponent", None]) -> None:
if self._parent: if self._parent and new_parent:
msg = f"Overwriting parent of {self}, {self._parent} with {new_parent}" msg = f"Overwriting parent of {self.uuid}. Old parent: {self._parent.uuid}, New parent: {new_parent.uuid}"
_LOGGER.warn(msg) _LOGGER.warn(msg)
raise RuntimeWarning(msg) raise RuntimeWarning(msg)
self._parent = new_parent self._parent = new_parent

View File

@@ -55,11 +55,11 @@ class Network(SimComponent):
:type node: Node :type node: Node
""" """
if node in self: if node in self:
msg = f"Can't add node {node}. It is already in the network." _LOGGER.warning(f"Can't add node {node.uuid}. It is already in the network.")
_LOGGER.warning(msg) return
raise RuntimeWarning(msg)
self.nodes[node.uuid] = node self.nodes[node.uuid] = node
node.parent = self node.parent = self
_LOGGER.info(f"Added node {node.uuid} to Network {self.uuid}")
def remove_node(self, node: Node) -> None: def remove_node(self, node: Node) -> None:
""" """
@@ -69,11 +69,11 @@ class Network(SimComponent):
:type node: Node :type node: Node
""" """
if node not in self: if node not in self:
msg = f"Can't remove node {node}. It's not in the network." _LOGGER.warning(f"Can't remove node {node.uuid}. It's not in the network.")
_LOGGER.warning(msg) return
raise RuntimeWarning(msg) self.nodes.pop(node.uuid)
del self.nodes[node.uuid] node.parent = None
del node.parent # misleading? _LOGGER.info(f"Removed node {node.uuid} from network {self.uuid}")
def connect(self, endpoint_a: Union[NIC, SwitchPort], endpoint_b: Union[NIC, SwitchPort], **kwargs) -> None: def connect(self, endpoint_a: Union[NIC, SwitchPort], endpoint_b: Union[NIC, SwitchPort], **kwargs) -> None:
"""Connect two nodes on the network by creating a link between an NIC/SwitchPort of each one. """Connect two nodes on the network by creating a link between an NIC/SwitchPort of each one.
@@ -86,20 +86,18 @@ class Network(SimComponent):
""" """
node_a = endpoint_a.parent node_a = endpoint_a.parent
node_b = endpoint_b.parent node_b = endpoint_b.parent
msg = ""
if node_a not in self: if node_a not in self:
msg = f"Cannot create a link to {endpoint_a} because the node is not in the network." self.add_node(node_a)
if node_b not in self: if node_b not in self:
msg = f"Cannot create a link to {endpoint_b} because the node is not in the network." self.add_node(node_b)
if node_a is node_b: if node_a is node_b:
msg = f"Cannot link {endpoint_a} to {endpoint_b} because they belong to the same node." _LOGGER.warn(f"Cannot link endpoint {endpoint_a} to {endpoint_b} because they belong to the same node.")
if msg: return
_LOGGER.error(msg)
raise RuntimeError(msg)
link = Link(endpoint_a=endpoint_a, endpoint_b=endpoint_b, **kwargs) link = Link(endpoint_a=endpoint_a, endpoint_b=endpoint_b, **kwargs)
self.links[link.uuid] = link self.links[link.uuid] = link
link.parent = self link.parent = self
_LOGGER.info(f"Added link {link.uuid} to connect {endpoint_a} and {endpoint_b}")
def remove_link(self, link: Link) -> None: def remove_link(self, link: Link) -> None:
"""Disconnect a link from the network. """Disconnect a link from the network.
@@ -109,12 +107,13 @@ class Network(SimComponent):
""" """
link.endpoint_a.disconnect_link() link.endpoint_a.disconnect_link()
link.endpoint_b.disconnect_link() link.endpoint_b.disconnect_link()
del self.links[link.uuid] self.links.pop(link.uuid)
del link.parent link.parent = None
_LOGGER.info(f"Removed link {link.uuid} from network {self.uuid}.")
def __contains__(self, item: Any) -> bool: def __contains__(self, item: Any) -> bool:
if isinstance(item, Node): if isinstance(item, Node):
return item.uuid in self.nodes return item.uuid in self.nodes
elif isinstance(item, Link): elif isinstance(item, Link):
return item.uuid in self.links return item.uuid in self.links
raise TypeError("") return False

View File

@@ -939,7 +939,7 @@ class Node(SimComponent):
nic = self.nics.get(nic) nic = self.nics.get(nic)
if nic or nic.uuid in self.nics: if nic or nic.uuid in self.nics:
self.nics.pop(nic.uuid) self.nics.pop(nic.uuid)
del nic.parent nic.parent = None
nic.disable() nic.disable()
self.sys_log.info(f"Disconnected NIC {nic}") self.sys_log.info(f"Disconnected NIC {nic}")
else: else:

View File

@@ -22,8 +22,7 @@ def test_readding_node():
net = Network() net = Network()
n1 = Node(hostname="computer") n1 = Node(hostname="computer")
net.add_node(n1) net.add_node(n1)
with pytest.raises(RuntimeWarning): net.add_node(n1)
net.add_node(n1)
assert n1.parent is net assert n1.parent is net
assert n1 in net assert n1 in net
@@ -32,8 +31,7 @@ def test_removing_nonexistent_node():
"""Check that warning is raised when trying to remove a node that is not in the network.""" """Check that warning is raised when trying to remove a node that is not in the network."""
net = Network() net = Network()
n1 = Node(hostname="computer") n1 = Node(hostname="computer")
with pytest.raises(RuntimeWarning): net.remove_node(n1)
net.remove_node(n1)
assert n1.parent is None assert n1.parent is None
assert n1 not in net assert n1 not in net
@@ -69,8 +67,7 @@ def test_connecting_node_to_itself():
net.add_node(node) net.add_node(node)
with pytest.raises(RuntimeError): net.connect(node.nics[nic1.uuid], node.nics[nic2.uuid], bandwidth=30)
net.connect(node.nics[nic1.uuid], node.nics[nic2.uuid], bandwidth=30)
assert node in net assert node in net
assert nic1.connected_link is None assert nic1.connected_link is None
@@ -79,4 +76,22 @@ def test_connecting_node_to_itself():
def test_disconnecting_nodes(): def test_disconnecting_nodes():
... net = Network()
n1 = Node(hostname="computer")
n1_nic = NIC(ip_address="120.30.0.1", gateway="192.168.0.1", subnet_mask="255.255.255.0")
n1.connect_nic(n1_nic)
net.add_node(n1)
n2 = Node(hostname="server")
n2_nic = NIC(ip_address="120.30.0.2", gateway="192.168.0.1", subnet_mask="255.255.255.0")
n2.connect_nic(n2_nic)
net.add_node(n2)
net.connect(n1.nics[n1_nic.uuid], n2.nics[n2_nic.uuid], bandwidth=30)
assert len(net.links) == 1
link = list(net.links.values())[0]
net.remove_link(link)
assert link not in net
assert len(net.links) == 0