daemon: initial pass to revamp how node linking and link management is done, provides a consistent way to link all wired nodes and allows them to be configured for tc for the same behavior across the board

This commit is contained in:
Blake Harnden 2022-03-17 15:28:38 -07:00
parent d684b8eb5a
commit cd7f1a641e
19 changed files with 1393 additions and 1556 deletions

View file

@ -10,7 +10,7 @@ from core.emulator.session import Session
from core.errors import CoreError
from core.location.mobility import BasicRangeModel
from core.nodes.base import CoreNode
from core.nodes.network import PtpNet, SwitchNode, WlanNode
from core.nodes.network import SwitchNode, WlanNode
from core.services.utility import SshService
@ -65,25 +65,18 @@ class TestXml:
:param tmpdir: tmpdir to create data in
:param ip_prefixes: generates ip addresses for nodes
"""
# create ptp
ptp_node = session.add_node(PtpNet)
# create nodes
node1 = session.add_node(CoreNode)
node2 = session.add_node(CoreNode)
# link nodes to ptp net
for node in [node1, node2]:
iface_data = ip_prefixes.create_iface(node)
session.add_link(node.id, ptp_node.id, iface1_data=iface_data)
# link nodes
iface1_data = ip_prefixes.create_iface(node1)
iface2_data = ip_prefixes.create_iface(node2)
session.add_link(node1.id, node2.id, iface1_data, iface2_data)
# instantiate session
session.instantiate()
# get ids for nodes
node1_id = node1.id
node2_id = node2.id
# save xml
xml_file = tmpdir.join("session.xml")
file_path = Path(xml_file.strpath)
@ -98,16 +91,19 @@ class TestXml:
# verify nodes have been removed from session
with pytest.raises(CoreError):
assert not session.get_node(node1_id, CoreNode)
assert not session.get_node(node1.id, CoreNode)
with pytest.raises(CoreError):
assert not session.get_node(node2_id, CoreNode)
assert not session.get_node(node2.id, CoreNode)
# verify no links are known
assert len(session.link_manager.links()) == 0
# load saved xml
session.open_xml(file_path, start=True)
# verify nodes have been recreated
assert session.get_node(node1_id, CoreNode)
assert session.get_node(node2_id, CoreNode)
assert session.get_node(node1.id, CoreNode)
assert session.get_node(node2.id, CoreNode)
assert len(session.link_manager.links()) == 1
def test_xml_ptp_services(
self, session: Session, tmpdir: TemporaryFile, ip_prefixes: IpPrefixes
@ -119,18 +115,15 @@ class TestXml:
:param tmpdir: tmpdir to create data in
:param ip_prefixes: generates ip addresses for nodes
"""
# create ptp
ptp_node = session.add_node(PtpNet)
# create nodes
options = NodeOptions(model="host")
node1 = session.add_node(CoreNode, options=options)
node2 = session.add_node(CoreNode)
# link nodes to ptp net
for node in [node1, node2]:
iface_data = ip_prefixes.create_iface(node)
session.add_link(node.id, ptp_node.id, iface1_data=iface_data)
iface1_data = ip_prefixes.create_iface(node1)
iface2_data = ip_prefixes.create_iface(node2)
session.add_link(node1.id, node2.id, iface1_data, iface2_data)
# set custom values for node service
session.services.set_service(node1.id, SshService.name)
@ -143,10 +136,6 @@ class TestXml:
# instantiate session
session.instantiate()
# get ids for nodes
node1_id = node1.id
node2_id = node2.id
# save xml
xml_file = tmpdir.join("session.xml")
file_path = Path(xml_file.strpath)
@ -161,9 +150,9 @@ class TestXml:
# verify nodes have been removed from session
with pytest.raises(CoreError):
assert not session.get_node(node1_id, CoreNode)
assert not session.get_node(node1.id, CoreNode)
with pytest.raises(CoreError):
assert not session.get_node(node2_id, CoreNode)
assert not session.get_node(node2.id, CoreNode)
# load saved xml
session.open_xml(file_path, start=True)
@ -172,8 +161,8 @@ class TestXml:
service = session.services.get_service(node1.id, SshService.name)
# verify nodes have been recreated
assert session.get_node(node1_id, CoreNode)
assert session.get_node(node2_id, CoreNode)
assert session.get_node(node1.id, CoreNode)
assert session.get_node(node2.id, CoreNode)
assert service.config_data.get(service_file) == file_data
def test_xml_mobility(
@ -187,8 +176,8 @@ class TestXml:
:param ip_prefixes: generates ip addresses for nodes
"""
# create wlan
wlan_node = session.add_node(WlanNode)
session.mobility.set_model(wlan_node, BasicRangeModel, {"test": "1"})
wlan = session.add_node(WlanNode)
session.mobility.set_model(wlan, BasicRangeModel, {"test": "1"})
# create nodes
options = NodeOptions(model="mdr")
@ -199,16 +188,11 @@ class TestXml:
# link nodes
for node in [node1, node2]:
iface_data = ip_prefixes.create_iface(node)
session.add_link(node.id, wlan_node.id, iface1_data=iface_data)
session.add_link(node.id, wlan.id, iface1_data=iface_data)
# instantiate session
session.instantiate()
# get ids for nodes
wlan_id = wlan_node.id
node1_id = node1.id
node2_id = node2.id
# save xml
xml_file = tmpdir.join("session.xml")
file_path = Path(xml_file.strpath)
@ -223,20 +207,20 @@ class TestXml:
# verify nodes have been removed from session
with pytest.raises(CoreError):
assert not session.get_node(node1_id, CoreNode)
assert not session.get_node(node1.id, CoreNode)
with pytest.raises(CoreError):
assert not session.get_node(node2_id, CoreNode)
assert not session.get_node(node2.id, CoreNode)
# load saved xml
session.open_xml(file_path, start=True)
# retrieve configuration we set originally
value = str(session.mobility.get_config("test", wlan_id, BasicRangeModel.name))
value = str(session.mobility.get_config("test", wlan.id, BasicRangeModel.name))
# verify nodes and configuration were restored
assert session.get_node(node1_id, CoreNode)
assert session.get_node(node2_id, CoreNode)
assert session.get_node(wlan_id, WlanNode)
assert session.get_node(node1.id, CoreNode)
assert session.get_node(node2.id, CoreNode)
assert session.get_node(wlan.id, WlanNode)
assert value == "1"
def test_network_to_network(self, session: Session, tmpdir: TemporaryFile):
@ -256,10 +240,6 @@ class TestXml:
# instantiate session
session.instantiate()
# get ids for nodes
node1_id = switch1.id
node2_id = switch2.id
# save xml
xml_file = tmpdir.join("session.xml")
file_path = Path(xml_file.strpath)
@ -274,19 +254,19 @@ class TestXml:
# verify nodes have been removed from session
with pytest.raises(CoreError):
assert not session.get_node(node1_id, SwitchNode)
assert not session.get_node(switch1.id, SwitchNode)
with pytest.raises(CoreError):
assert not session.get_node(node2_id, SwitchNode)
assert not session.get_node(switch2.id, SwitchNode)
# load saved xml
session.open_xml(file_path, start=True)
# verify nodes have been recreated
switch1 = session.get_node(node1_id, SwitchNode)
switch2 = session.get_node(node2_id, SwitchNode)
switch1 = session.get_node(switch1.id, SwitchNode)
switch2 = session.get_node(switch2.id, SwitchNode)
assert switch1
assert switch2
assert len(switch1.links() + switch2.links()) == 1
assert len(session.link_manager.links()) == 1
def test_link_options(
self, session: Session, tmpdir: TemporaryFile, ip_prefixes: IpPrefixes
@ -316,10 +296,6 @@ class TestXml:
# instantiate session
session.instantiate()
# get ids for nodes
node1_id = node1.id
node2_id = switch.id
# save xml
xml_file = tmpdir.join("session.xml")
file_path = Path(xml_file.strpath)
@ -334,27 +310,25 @@ class TestXml:
# verify nodes have been removed from session
with pytest.raises(CoreError):
assert not session.get_node(node1_id, CoreNode)
assert not session.get_node(node1.id, CoreNode)
with pytest.raises(CoreError):
assert not session.get_node(node2_id, SwitchNode)
assert not session.get_node(switch.id, SwitchNode)
# load saved xml
session.open_xml(file_path, start=True)
# verify nodes have been recreated
assert session.get_node(node1_id, CoreNode)
assert session.get_node(node2_id, SwitchNode)
links = []
for node_id in session.nodes:
node = session.nodes[node_id]
links += node.links()
link = links[0]
assert options.loss == link.options.loss
assert options.bandwidth == link.options.bandwidth
assert options.jitter == link.options.jitter
assert options.delay == link.options.delay
assert options.dup == link.options.dup
assert options.buffer == link.options.buffer
assert session.get_node(node1.id, CoreNode)
assert session.get_node(switch.id, SwitchNode)
assert len(session.link_manager.links()) == 1
link = list(session.link_manager.links())[0]
link_options = link.options()
assert options.loss == link_options.loss
assert options.bandwidth == link_options.bandwidth
assert options.jitter == link_options.jitter
assert options.delay == link_options.delay
assert options.dup == link_options.dup
assert options.buffer == link_options.buffer
def test_link_options_ptp(
self, session: Session, tmpdir: TemporaryFile, ip_prefixes: IpPrefixes
@ -385,10 +359,6 @@ class TestXml:
# instantiate session
session.instantiate()
# get ids for nodes
node1_id = node1.id
node2_id = node2.id
# save xml
xml_file = tmpdir.join("session.xml")
file_path = Path(xml_file.strpath)
@ -403,27 +373,25 @@ class TestXml:
# verify nodes have been removed from session
with pytest.raises(CoreError):
assert not session.get_node(node1_id, CoreNode)
assert not session.get_node(node1.id, CoreNode)
with pytest.raises(CoreError):
assert not session.get_node(node2_id, CoreNode)
assert not session.get_node(node2.id, CoreNode)
# load saved xml
session.open_xml(file_path, start=True)
# verify nodes have been recreated
assert session.get_node(node1_id, CoreNode)
assert session.get_node(node2_id, CoreNode)
links = []
for node_id in session.nodes:
node = session.nodes[node_id]
links += node.links()
link = links[0]
assert options.loss == link.options.loss
assert options.bandwidth == link.options.bandwidth
assert options.jitter == link.options.jitter
assert options.delay == link.options.delay
assert options.dup == link.options.dup
assert options.buffer == link.options.buffer
assert session.get_node(node1.id, CoreNode)
assert session.get_node(node2.id, CoreNode)
assert len(session.link_manager.links()) == 1
link = list(session.link_manager.links())[0]
link_options = link.options()
assert options.loss == link_options.loss
assert options.bandwidth == link_options.bandwidth
assert options.jitter == link_options.jitter
assert options.delay == link_options.delay
assert options.dup == link_options.dup
assert options.buffer == link_options.buffer
def test_link_options_bidirectional(
self, session: Session, tmpdir: TemporaryFile, ip_prefixes: IpPrefixes
@ -450,7 +418,9 @@ class TestXml:
options1.dup = 5
options1.jitter = 5
options1.buffer = 50
session.add_link(node1.id, node2.id, iface1_data, iface2_data, options1)
iface1, iface2 = session.add_link(
node1.id, node2.id, iface1_data, iface2_data, options1
)
options2 = LinkOptions()
options2.unidirectional = 1
options2.bandwidth = 10000
@ -459,17 +429,11 @@ class TestXml:
options2.dup = 10
options2.jitter = 10
options2.buffer = 100
session.update_link(
node2.id, node1.id, iface2_data.id, iface1_data.id, options2
)
session.update_link(node2.id, node1.id, iface2.id, iface1.id, options2)
# instantiate session
session.instantiate()
# get ids for nodes
node1_id = node1.id
node2_id = node2.id
# save xml
xml_file = tmpdir.join("session.xml")
file_path = Path(xml_file.strpath)
@ -484,32 +448,26 @@ class TestXml:
# verify nodes have been removed from session
with pytest.raises(CoreError):
assert not session.get_node(node1_id, CoreNode)
assert not session.get_node(node1.id, CoreNode)
with pytest.raises(CoreError):
assert not session.get_node(node2_id, CoreNode)
assert not session.get_node(node2.id, CoreNode)
# load saved xml
session.open_xml(file_path, start=True)
# verify nodes have been recreated
assert session.get_node(node1_id, CoreNode)
assert session.get_node(node2_id, CoreNode)
links = []
for node_id in session.nodes:
node = session.nodes[node_id]
links += node.links()
assert len(links) == 2
link1 = links[0]
link2 = links[1]
assert options1.bandwidth == link1.options.bandwidth
assert options1.delay == link1.options.delay
assert options1.loss == link1.options.loss
assert options1.dup == link1.options.dup
assert options1.jitter == link1.options.jitter
assert options1.buffer == link1.options.buffer
assert options2.bandwidth == link2.options.bandwidth
assert options2.delay == link2.options.delay
assert options2.loss == link2.options.loss
assert options2.dup == link2.options.dup
assert options2.jitter == link2.options.jitter
assert options2.buffer == link2.options.buffer
assert session.get_node(node1.id, CoreNode)
assert session.get_node(node2.id, CoreNode)
assert len(session.link_manager.links()) == 1
assert options1.bandwidth == iface1.options.bandwidth
assert options1.delay == iface1.options.delay
assert options1.loss == iface1.options.loss
assert options1.dup == iface1.options.dup
assert options1.jitter == iface1.options.jitter
assert options1.buffer == iface1.options.buffer
assert options2.bandwidth == iface2.options.bandwidth
assert options2.delay == iface2.options.delay
assert options2.loss == iface2.options.loss
assert options2.dup == iface2.options.dup
assert options2.jitter == iface2.options.jitter
assert options2.buffer == iface2.options.buffer