caught up with latest gitlab commits, added a new tests directory leveraging pytest based tests for testing core functionality
This commit is contained in:
parent
2fc6345138
commit
14cb7dc251
14 changed files with 570 additions and 96 deletions
|
@ -38,6 +38,7 @@ from core.phys.pnodes import PhysicalNode
|
|||
logger = log.get_logger(__name__)
|
||||
|
||||
|
||||
# TODO: name conflict with main core server, probably should rename
|
||||
class CoreServer(object):
|
||||
def __init__(self, name, host, port):
|
||||
self.name = name
|
||||
|
@ -93,7 +94,6 @@ class CoreBroker(ConfigurableManager):
|
|||
self.nodemap_lock = threading.Lock()
|
||||
# reference counts of nodes on servers
|
||||
self.nodecounts = {}
|
||||
self.bootcount = 0
|
||||
# set of node numbers that are link-layer nodes (networks)
|
||||
self.network_nodes = set()
|
||||
# set of node numbers that are PhysicalNode nodes
|
||||
|
@ -224,11 +224,6 @@ class CoreBroker(ConfigurableManager):
|
|||
nodenum = msg.get_tlv(NodeTlvs.NUMBER.value)
|
||||
if nodenum is not None:
|
||||
count = self.delnodemap(server, nodenum)
|
||||
# snoop node add response to increment booted node count
|
||||
# (only CoreNodes send these response messages)
|
||||
elif msgflags & (MessageFlags.ADD.value | MessageFlags.LOCAL.value):
|
||||
self.incrbootcount()
|
||||
self.session.check_runtime()
|
||||
elif msgtype == MessageTypes.LINK.value:
|
||||
# this allows green link lines for remote WLANs
|
||||
msg = coreapi.CoreLinkMessage(msgflags, msghdr, msgdata)
|
||||
|
@ -485,19 +480,6 @@ class CoreBroker(ConfigurableManager):
|
|||
self.nodecounts[server] = count
|
||||
return count
|
||||
|
||||
def incrbootcount(self):
|
||||
"""
|
||||
Count a node that has booted.
|
||||
"""
|
||||
self.bootcount += 1
|
||||
return self.bootcount
|
||||
|
||||
def getbootcount(self):
|
||||
"""
|
||||
Return the number of booted nodes.
|
||||
"""
|
||||
return self.bootcount
|
||||
|
||||
def getserversbynode(self, nodenum):
|
||||
"""
|
||||
Retrieve a set of emulation servers given a node number.
|
||||
|
@ -588,13 +570,14 @@ class CoreBroker(ConfigurableManager):
|
|||
:rtype: bool
|
||||
"""
|
||||
servers = set()
|
||||
handle_locally = False
|
||||
# Do not forward messages when in definition state
|
||||
# (for e.g. configuring services)
|
||||
if self.session.state == EventTypes.DEFINITION_STATE.value:
|
||||
return False
|
||||
# Decide whether message should be handled locally or forwarded, or both
|
||||
if message.message_type == MessageTypes.NODE.value:
|
||||
servers = self.handlenodemsg(message)
|
||||
handle_locally, servers = self.handlenodemsg(message)
|
||||
elif message.message_type == MessageTypes.EVENT.value:
|
||||
# broadcast events everywhere
|
||||
servers = self.getservers()
|
||||
|
@ -611,7 +594,7 @@ class CoreBroker(ConfigurableManager):
|
|||
servers = self.getservers()
|
||||
if message.message_type == MessageTypes.LINK.value:
|
||||
# prepare a server list from two node numbers in link message
|
||||
servers, message = self.handlelinkmsg(message)
|
||||
handle_locally, servers, message = self.handlelinkmsg(message)
|
||||
elif len(servers) == 0:
|
||||
# check for servers based on node numbers in all messages but link
|
||||
nn = message.node_numbers()
|
||||
|
@ -626,7 +609,7 @@ class CoreBroker(ConfigurableManager):
|
|||
handler(message)
|
||||
|
||||
# Perform any message forwarding
|
||||
handle_locally = self.forwardmsg(message, servers)
|
||||
handle_locally |= self.forwardmsg(message, servers)
|
||||
return not handle_locally
|
||||
|
||||
def setupserver(self, servername):
|
||||
|
@ -694,6 +677,7 @@ class CoreBroker(ConfigurableManager):
|
|||
:return:
|
||||
"""
|
||||
servers = set()
|
||||
handle_locally = False
|
||||
serverfiletxt = None
|
||||
# snoop Node Message for emulation server TLV and record mapping
|
||||
n = message.tlv_data[NodeTlvs.NUMBER.value]
|
||||
|
@ -704,25 +688,21 @@ class CoreBroker(ConfigurableManager):
|
|||
nodecls = nodeutils.get_node_class(NodeTypes(nodetype))
|
||||
except KeyError:
|
||||
logger.warn("broker invalid node type %s" % nodetype)
|
||||
return servers
|
||||
return handle_locally, servers
|
||||
if nodecls is None:
|
||||
logger.warn("broker unimplemented node type %s" % nodetype)
|
||||
return servers
|
||||
return handle_locally, servers
|
||||
if issubclass(nodecls, PyCoreNet) and nodetype != NodeTypes.WIRELESS_LAN.value:
|
||||
# network node replicated on all servers; could be optimized
|
||||
# don"t replicate WLANs, because ebtables rules won"t work
|
||||
servers = self.getservers()
|
||||
handle_locally = True
|
||||
self.addnet(n)
|
||||
for server in servers:
|
||||
self.addnodemap(server, n)
|
||||
# do not record server name for networks since network
|
||||
# nodes are replicated across all server
|
||||
return servers
|
||||
if issubclass(nodecls, PyCoreNet) and nodetype == NodeTypes.WIRELESS_LAN.value:
|
||||
# special case where remote WLANs not in session._objs, and no
|
||||
# node response message received, so they are counted here
|
||||
if message.get_tlv(NodeTlvs.EMULATION_SERVER.value) is not None:
|
||||
self.incrbootcount()
|
||||
return handle_locally, servers
|
||||
elif issubclass(nodecls, PyCoreNode):
|
||||
name = message.get_tlv(NodeTlvs.NAME.value)
|
||||
if name:
|
||||
|
@ -743,7 +723,7 @@ class CoreBroker(ConfigurableManager):
|
|||
# hook to update coordinates of physical nodes
|
||||
if n in self.physical_nodes:
|
||||
self.session.mobility.physnodeupdateposition(message)
|
||||
return servers
|
||||
return handle_locally, servers
|
||||
|
||||
def handlelinkmsg(self, message):
|
||||
"""
|
||||
|
@ -804,10 +784,11 @@ class CoreBroker(ConfigurableManager):
|
|||
self.addtunnel(host, nn[0], nn[1], localn)
|
||||
elif message.flags & MessageFlags.DELETE.value:
|
||||
self.deltunnel(nn[0], nn[1])
|
||||
handle_locally = False
|
||||
else:
|
||||
servers = servers1.union(servers2)
|
||||
|
||||
return servers, message
|
||||
return handle_locally, servers, message
|
||||
|
||||
def addlinkendpoints(self, message, servers1, servers2):
|
||||
"""
|
||||
|
@ -946,7 +927,7 @@ class CoreBroker(ConfigurableManager):
|
|||
if server is not None:
|
||||
server.instantiation_complete = True
|
||||
|
||||
if self.session.is_connected():
|
||||
if self.session_handler:
|
||||
tlvdata = ""
|
||||
tlvdata += coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value, EventTypes.INSTANTIATION_COMPLETE.value)
|
||||
msg = coreapi.CoreEventMessage.pack(0, tlvdata)
|
||||
|
|
|
@ -71,6 +71,7 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
|
|||
}
|
||||
self.message_queue = Queue.Queue()
|
||||
self.node_status_request = {}
|
||||
self._shutdown_lock = threading.Lock()
|
||||
|
||||
self.handler_threads = []
|
||||
num_threads = int(server.config["numthreads"])
|
||||
|
@ -602,20 +603,14 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
|
|||
self.node_status_request[node_id] = True
|
||||
|
||||
elif message.flags & MessageFlags.DELETE.value:
|
||||
# TODO: logic below seems pointless, when the deletion is attempted regardless
|
||||
node = None
|
||||
try:
|
||||
node = self.session.get_object(node_id)
|
||||
except KeyError:
|
||||
logger.exception("error retrieving object: %s", node_id)
|
||||
|
||||
with self._shutdown_lock:
|
||||
self.session.delete_object(node_id)
|
||||
|
||||
if message.flags & MessageFlags.STRING.value:
|
||||
tlv_data = ""
|
||||
tlv_data += coreapi.CoreNodeTlv.pack(NodeTlvs.NUMBER.value, node_id)
|
||||
tlvdata = ""
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(NodeTlvs.NUMBER.value, node_id)
|
||||
flags = MessageFlags.DELETE.value | MessageFlags.LOCAL.value
|
||||
replies.append(coreapi.CoreNodeMessage.pack(flags, tlv_data))
|
||||
replies.append(coreapi.CoreNodeMessage.pack(flags, tlvdata))
|
||||
|
||||
self.session.check_shutdown()
|
||||
# Node modify message (no add/del flag)
|
||||
|
|
|
@ -457,6 +457,7 @@ class EmaneManager(ConfigurableManager):
|
|||
servers.append(s)
|
||||
self._objslock.release()
|
||||
|
||||
servers.sort(key=lambda x: x.name)
|
||||
for server in servers:
|
||||
if server.name == "localhost":
|
||||
continue
|
||||
|
@ -1139,6 +1140,24 @@ class EmaneManager(ConfigurableManager):
|
|||
|
||||
return True
|
||||
|
||||
def emanerunning(self, node):
|
||||
"""
|
||||
Return True if an EMANE process associated with the given node
|
||||
is running, False otherwise.
|
||||
"""
|
||||
status = -1
|
||||
cmd = ['pkill', '-0', '-x', 'emane']
|
||||
|
||||
try:
|
||||
if self.version < emane.EMANE092:
|
||||
status = subprocess.call(cmd)
|
||||
else:
|
||||
status = node.cmd(cmd, wait=True)
|
||||
except IOError:
|
||||
logger.exception("error checking if emane is running")
|
||||
|
||||
return status == 0
|
||||
|
||||
|
||||
class EmaneGlobalModel(EmaneModel):
|
||||
"""
|
||||
|
|
|
@ -422,25 +422,24 @@ class BasicRangeModel(WirelessModel):
|
|||
"""
|
||||
if netif == netif2:
|
||||
return
|
||||
|
||||
try:
|
||||
(x, y, z) = self._netifs[netif]
|
||||
(x2, y2, z2) = self._netifs[netif2]
|
||||
except KeyError:
|
||||
return
|
||||
x, y, z = self._netifs[netif]
|
||||
x2, y2, z2 = self._netifs[netif2]
|
||||
|
||||
if x2 is None or y2 is None:
|
||||
return
|
||||
|
||||
d = self.calcdistance((x, y, z), (x2, y2, z2))
|
||||
|
||||
# ordering is important, to keep the wlan._linked dict organized
|
||||
a = min(netif, netif2)
|
||||
b = max(netif, netif2)
|
||||
try:
|
||||
self.wlan._linked_lock.acquire()
|
||||
|
||||
with self.wlan._linked_lock:
|
||||
linked = self.wlan.linked(a, b)
|
||||
except KeyError:
|
||||
return
|
||||
finally:
|
||||
self.wlan._linked_lock.release()
|
||||
|
||||
logger.info("checking if link distance is out of range: %s > %s", d, self.range)
|
||||
if d > self.range:
|
||||
if linked:
|
||||
self.wlan.unlink(a, b)
|
||||
|
@ -449,6 +448,8 @@ class BasicRangeModel(WirelessModel):
|
|||
if not linked:
|
||||
self.wlan.link(a, b)
|
||||
self.sendlinkmsg(a, b)
|
||||
except KeyError:
|
||||
logger.exception("error getting interfaces during calclinkS")
|
||||
|
||||
@staticmethod
|
||||
def calcdistance(p1, p2):
|
||||
|
|
|
@ -312,7 +312,7 @@ class WlanNode(LxBrNet):
|
|||
for netif in self.netifs():
|
||||
netif.poshook = self.model.position_callback
|
||||
if netif.node is not None:
|
||||
(x, y, z) = netif.node.position.get()
|
||||
x, y, z = netif.node.position.get()
|
||||
netif.poshook(netif, x, y, z)
|
||||
self.model.setlinkparams()
|
||||
elif model.config_type == RegisterTlvs.MOBILITY.value:
|
||||
|
|
|
@ -8,7 +8,9 @@ import time
|
|||
|
||||
from core import constants
|
||||
from core.coreobj import PyCoreNetIf
|
||||
from core.enumerations import NodeTypes
|
||||
from core.misc import log
|
||||
from core.misc import nodeutils
|
||||
from core.misc import utils
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
|
@ -116,7 +118,20 @@ class TunTap(PyCoreNetIf):
|
|||
cmd = (constants.IP_BIN, 'link', 'show', self.name)
|
||||
return self.node.cmd(cmd)
|
||||
|
||||
count = 0
|
||||
while True:
|
||||
try:
|
||||
self.waitfor(nodedevexists)
|
||||
break
|
||||
except RuntimeError as e:
|
||||
# check if this is an EMANE interface; if so, continue
|
||||
# waiting if EMANE is still running
|
||||
# TODO: remove emane code
|
||||
if count < 5 and nodeutils.is_node(self.net, NodeTypes.EMANE) and \
|
||||
self.node.session.emane.emanerunning(self.node):
|
||||
count += 1
|
||||
else:
|
||||
raise e
|
||||
|
||||
def install(self):
|
||||
"""
|
||||
|
|
|
@ -40,8 +40,7 @@ class Sdt(object):
|
|||
DEFAULT_SDT_URL = "tcp://127.0.0.1:50000/"
|
||||
# default altitude (in meters) for flyto view
|
||||
DEFAULT_ALT = 2500
|
||||
# TODO: read in user's nodes.conf here; below are default node types
|
||||
# from the GUI
|
||||
# TODO: read in user's nodes.conf here; below are default node types from the GUI
|
||||
DEFAULT_SPRITES = [
|
||||
('router', 'router.gif'), ('host', 'host.gif'),
|
||||
('PC', 'pc.gif'), ('mdr', 'mdr.gif'),
|
||||
|
|
|
@ -636,12 +636,9 @@ class Session(object):
|
|||
with self._objects_lock:
|
||||
try:
|
||||
obj = self.objects.pop(object_id)
|
||||
obj.shutdown()
|
||||
except KeyError:
|
||||
logger.error("failed to remove object, object with id was not found: %s", object_id)
|
||||
obj = None
|
||||
|
||||
if obj:
|
||||
obj.shutdown()
|
||||
|
||||
def delete_objects(self):
|
||||
"""
|
||||
|
@ -840,23 +837,6 @@ class Session(object):
|
|||
logger.info("valid runtime state found, returning")
|
||||
return
|
||||
|
||||
# session_node_count = self.get_node_count()
|
||||
#
|
||||
# node_count = self.get_node_count()
|
||||
|
||||
# count booted nodes not emulated on this server
|
||||
# TODO: let slave server determine RUNTIME and wait for Event Message
|
||||
# broker.getbootocunt() counts all CoreNodes from status reponse
|
||||
# messages, plus any remote WLANs; remote EMANE, hub, switch, etc.
|
||||
# are already counted in self._objs
|
||||
# node_count += self.broker.getbootcount()
|
||||
# logger.info("Checking for runtime with %d of %d session nodes",
|
||||
# node_count, session_node_count)
|
||||
# if node_count < session_node_count:
|
||||
# return # do not have information on all nodes yet
|
||||
|
||||
# information on all nodes has been received and they have been started enter the runtime state
|
||||
|
||||
# check to verify that all nodes and networks are running
|
||||
if not self.broker.instantiation_complete():
|
||||
return
|
||||
|
|
|
@ -60,6 +60,7 @@ def test(options):
|
|||
|
||||
# launches terminal for the first node
|
||||
# n[0].term("bash")
|
||||
n[0].icmd(["ping", "-c", "5", "127.0.0.1"])
|
||||
|
||||
# wait for rate seconds to allow ebtables commands to commit
|
||||
time.sleep(EbtablesQueue.rate)
|
||||
|
|
|
@ -4,3 +4,5 @@ grpcio-tools==1.0.0
|
|||
pycco==0.5.1
|
||||
sphinx==1.4.8
|
||||
sphinx_rtd_theme==0.1.9
|
||||
pytest==3.0.7
|
||||
pytest-runner==2.11.1
|
||||
|
|
2
daemon/setup.cfg
Normal file
2
daemon/setup.cfg
Normal file
|
@ -0,0 +1,2 @@
|
|||
[aliases]
|
||||
test=pytest
|
|
@ -27,6 +27,8 @@ setup(name="core-python",
|
|||
install_requires=[
|
||||
"enum34"
|
||||
],
|
||||
setup_requires=["pytest-runner"],
|
||||
tests_require=["pytest"],
|
||||
description="Python components of CORE",
|
||||
url="http://www.nrl.navy.mil/itd/ncs/products/core",
|
||||
author="Boeing Research & Technology",
|
||||
|
|
142
daemon/tests/conftest.py
Normal file
142
daemon/tests/conftest.py
Normal file
|
@ -0,0 +1,142 @@
|
|||
"""
|
||||
Unit test fixture module.
|
||||
"""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from core.session import Session
|
||||
from core.misc import ipaddress
|
||||
from core.misc import nodemaps
|
||||
from core.misc import nodeutils
|
||||
from core.netns import nodes
|
||||
|
||||
|
||||
class Core(object):
|
||||
def __init__(self, session, ip_prefix):
|
||||
self.session = session
|
||||
self.ip_prefix = ip_prefix
|
||||
self.current_ip = 1
|
||||
self.nodes = {}
|
||||
self.node_ips = {}
|
||||
|
||||
def create_node(self, name):
|
||||
node = self.session.add_object(cls=nodes.CoreNode, name=name)
|
||||
self.nodes[name] = node
|
||||
|
||||
def add_interface(self, network, name):
|
||||
node_ip = self.ip_prefix.addr(self.current_ip)
|
||||
self.current_ip += 1
|
||||
self.node_ips[name] = node_ip
|
||||
node = self.nodes[name]
|
||||
interface_id = node.newnetif(network, ["%s/%s" % (node_ip, self.ip_prefix.prefixlen)])
|
||||
return node.netif(interface_id)
|
||||
|
||||
def get_node(self, name):
|
||||
"""
|
||||
Retrieve node from current session.
|
||||
|
||||
:param str name: name of node to retrieve
|
||||
:return: core node
|
||||
:rtype: core.netns.nodes.CoreNode
|
||||
"""
|
||||
return self.nodes[name]
|
||||
|
||||
def get_ip(self, name):
|
||||
return self.node_ips[name]
|
||||
|
||||
def link(self, network, from_interface, to_interface):
|
||||
network.link(from_interface, to_interface)
|
||||
|
||||
def configure_link(self, network, interface_one, interface_two, values, unidirectional=False):
|
||||
network.linkconfig(
|
||||
netif=interface_one,
|
||||
netif2=interface_two,
|
||||
**values
|
||||
)
|
||||
|
||||
if not unidirectional:
|
||||
network.linkconfig(
|
||||
netif=interface_two,
|
||||
netif2=interface_one,
|
||||
**values
|
||||
)
|
||||
|
||||
def ping(self, from_name, to_name):
|
||||
from_node = self.nodes[from_name]
|
||||
to_ip = str(self.get_ip(to_name))
|
||||
return from_node.cmd(["ping", "-c", "3", to_ip])
|
||||
|
||||
def ping_output(self, from_name, to_name):
|
||||
from_node = self.nodes[from_name]
|
||||
to_ip = str(self.get_ip(to_name))
|
||||
vcmd, stdin, stdout, stderr = from_node.popen(["ping", "-i", "0.05", "-c", "3", to_ip])
|
||||
return stdout.read().strip()
|
||||
|
||||
def iping(self, from_name, to_name):
|
||||
from_node = self.nodes[from_name]
|
||||
to_ip = str(self.get_ip(to_name))
|
||||
from_node.icmd(["ping", "-i", "0.01", "-c", "10", to_ip])
|
||||
|
||||
def iperf(self, from_name, to_name):
|
||||
from_node = self.nodes[from_name]
|
||||
to_node = self.nodes[to_name]
|
||||
to_ip = str(self.get_ip(to_name))
|
||||
|
||||
# run iperf server, run client, kill iperf server
|
||||
vcmd, stdin, stdout, stderr = to_node.popen(["iperf", "-s", "-u", "-y", "C"])
|
||||
from_node.cmd(["iperf", "-u", "-t", "5", "-c", to_ip])
|
||||
to_node.cmd(["killall", "-9", "iperf"])
|
||||
|
||||
return stdout.read().strip()
|
||||
|
||||
def assert_nodes(self):
|
||||
for node in self.nodes.itervalues():
|
||||
assert os.path.exists(node.nodedir)
|
||||
|
||||
def create_link_network(self):
|
||||
# create switch
|
||||
ptp_node = self.session.add_object(cls=nodes.PtpNet)
|
||||
|
||||
# create nodes
|
||||
self.create_node("n1")
|
||||
self.create_node("n2")
|
||||
|
||||
# add interfaces
|
||||
interface_one = self.add_interface(ptp_node, "n1")
|
||||
interface_two = self.add_interface(ptp_node, "n2")
|
||||
|
||||
# instantiate session
|
||||
self.session.instantiate()
|
||||
|
||||
# assert node directories created
|
||||
self.assert_nodes()
|
||||
|
||||
return ptp_node, interface_one, interface_two
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def session():
|
||||
# configure default nodes
|
||||
node_map = nodemaps.CLASSIC_NODES
|
||||
nodeutils.set_node_map(node_map)
|
||||
|
||||
# create and return session
|
||||
session_fixture = Session(1, persistent=True)
|
||||
assert os.path.exists(session_fixture.session_dir)
|
||||
yield session_fixture
|
||||
|
||||
# cleanup
|
||||
print "shutting down session"
|
||||
session_fixture.shutdown()
|
||||
assert not os.path.exists(session_fixture.session_dir)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def ip_prefix():
|
||||
return ipaddress.Ipv4Prefix("10.83.0.0/16")
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def core(session, ip_prefix):
|
||||
return Core(session, ip_prefix)
|
335
daemon/tests/test_core.py
Normal file
335
daemon/tests/test_core.py
Normal file
|
@ -0,0 +1,335 @@
|
|||
"""
|
||||
Unit tests for testing with a CORE switch.
|
||||
"""
|
||||
from core.mobility import BasicRangeModel
|
||||
from core.netns import nodes
|
||||
|
||||
|
||||
class TestCore:
|
||||
def test_ptp(self, core):
|
||||
"""
|
||||
Test ptp node network.
|
||||
|
||||
:param conftest.Core core: core fixture to test with
|
||||
"""
|
||||
|
||||
# create switch
|
||||
ptp_node = core.session.add_object(cls=nodes.PtpNet)
|
||||
|
||||
# create nodes
|
||||
core.create_node("n1")
|
||||
core.create_node("n2")
|
||||
|
||||
# add interfaces
|
||||
core.add_interface(ptp_node, "n1")
|
||||
core.add_interface(ptp_node, "n2")
|
||||
|
||||
# instantiate session
|
||||
core.session.instantiate()
|
||||
|
||||
# assert node directories created
|
||||
core.assert_nodes()
|
||||
|
||||
# ping n2 from n1 and assert success
|
||||
status = core.ping("n1", "n2")
|
||||
assert not status
|
||||
|
||||
def test_hub(self, core):
|
||||
"""
|
||||
Test basic hub network.
|
||||
|
||||
:param conftest.Core core: core fixture to test with
|
||||
"""
|
||||
|
||||
# create switch
|
||||
hub_node = core.session.add_object(cls=nodes.HubNode)
|
||||
|
||||
# create nodes
|
||||
core.create_node("n1")
|
||||
core.create_node("n2")
|
||||
|
||||
# add interfaces
|
||||
core.add_interface(hub_node, "n1")
|
||||
core.add_interface(hub_node, "n2")
|
||||
|
||||
# instantiate session
|
||||
core.session.instantiate()
|
||||
|
||||
# assert node directories created
|
||||
core.assert_nodes()
|
||||
|
||||
# ping n2 from n1 and assert success
|
||||
status = core.ping("n1", "n2")
|
||||
assert not status
|
||||
|
||||
def test_switch(self, core):
|
||||
"""
|
||||
Test basic switch network.
|
||||
|
||||
:param conftest.Core core: core fixture to test with
|
||||
"""
|
||||
|
||||
# create switch
|
||||
switch_node = core.session.add_object(cls=nodes.SwitchNode)
|
||||
|
||||
# create nodes
|
||||
core.create_node("n1")
|
||||
core.create_node("n2")
|
||||
|
||||
# add interfaces
|
||||
core.add_interface(switch_node, "n1")
|
||||
core.add_interface(switch_node, "n2")
|
||||
|
||||
# instantiate session
|
||||
core.session.instantiate()
|
||||
|
||||
# assert node directories created
|
||||
core.assert_nodes()
|
||||
|
||||
# ping n2 from n1 and assert success
|
||||
status = core.ping("n1", "n2")
|
||||
assert not status
|
||||
|
||||
def test_wlan_basic_range_good(self, core):
|
||||
"""
|
||||
Test basic wlan network.
|
||||
|
||||
:param conftest.Core core: core fixture to test with
|
||||
"""
|
||||
|
||||
# create wlan
|
||||
wlan_node = core.session.add_object(cls=nodes.WlanNode)
|
||||
values = BasicRangeModel.getdefaultvalues()
|
||||
wlan_node.setmodel(BasicRangeModel, values)
|
||||
|
||||
# create nodes
|
||||
core.create_node("n1")
|
||||
core.create_node("n2")
|
||||
|
||||
# add interfaces
|
||||
interface_one = core.add_interface(wlan_node, "n1")
|
||||
interface_two = core.add_interface(wlan_node, "n2")
|
||||
|
||||
# link nodes in wlan
|
||||
core.link(wlan_node, interface_one, interface_two)
|
||||
|
||||
# mark node position as together
|
||||
core.get_node("n1").setposition(0, 0)
|
||||
core.get_node("n2").setposition(0, 0)
|
||||
|
||||
# instantiate session
|
||||
core.session.instantiate()
|
||||
|
||||
# assert node directories created
|
||||
core.assert_nodes()
|
||||
|
||||
# ping n2 from n1 and assert success
|
||||
status = core.ping("n1", "n2")
|
||||
assert not status
|
||||
|
||||
def test_wlan_basic_range_bad(self, core):
|
||||
"""
|
||||
Test basic wlan network with leveraging basic range model.
|
||||
|
||||
:param conftest.Core core: core fixture to test with
|
||||
"""
|
||||
|
||||
# create wlan
|
||||
wlan_node = core.session.add_object(cls=nodes.WlanNode)
|
||||
values = BasicRangeModel.getdefaultvalues()
|
||||
wlan_node.setmodel(BasicRangeModel, values)
|
||||
|
||||
# create nodes
|
||||
core.create_node("n1")
|
||||
core.create_node("n2")
|
||||
|
||||
# add interfaces
|
||||
interface_one = core.add_interface(wlan_node, "n1")
|
||||
interface_two = core.add_interface(wlan_node, "n2")
|
||||
|
||||
# link nodes in wlan
|
||||
core.link(wlan_node, interface_one, interface_two)
|
||||
|
||||
# move nodes out of range, default range check is 275
|
||||
core.get_node("n1").setposition(0, 0)
|
||||
core.get_node("n2").setposition(500, 500)
|
||||
|
||||
# instantiate session
|
||||
core.session.instantiate()
|
||||
|
||||
# assert node directories created
|
||||
core.assert_nodes()
|
||||
|
||||
# ping n2 from n1 and assert failure
|
||||
import time
|
||||
time.sleep(1)
|
||||
status = core.ping("n1", "n2")
|
||||
assert status
|
||||
|
||||
def test_link_bandwidth(self, core):
|
||||
"""
|
||||
Test ptp node network with modifying link bandwidth.
|
||||
|
||||
:param conftest.Core core: core fixture to test with
|
||||
"""
|
||||
|
||||
# create switch
|
||||
ptp_node = core.session.add_object(cls=nodes.PtpNet)
|
||||
|
||||
# create nodes
|
||||
core.create_node("n1")
|
||||
core.create_node("n2")
|
||||
|
||||
# add interfaces
|
||||
interface_one = core.add_interface(ptp_node, "n1")
|
||||
interface_two = core.add_interface(ptp_node, "n2")
|
||||
|
||||
# instantiate session
|
||||
core.session.instantiate()
|
||||
|
||||
# assert node directories created
|
||||
core.assert_nodes()
|
||||
|
||||
# output csv index
|
||||
bandwidth_index = 8
|
||||
|
||||
# run iperf, validate normal bandwidth
|
||||
stdout = core.iperf("n1", "n2")
|
||||
assert stdout
|
||||
value = int(stdout.split(',')[bandwidth_index])
|
||||
print "bandwidth before: %s" % value
|
||||
assert 900000 <= value <= 1100000
|
||||
|
||||
# change bandwidth in bits per second
|
||||
bandwidth = 500000
|
||||
core.configure_link(ptp_node, interface_one, interface_two, {
|
||||
"bw": bandwidth
|
||||
})
|
||||
|
||||
# run iperf again
|
||||
stdout = core.iperf("n1", "n2")
|
||||
assert stdout
|
||||
value = int(stdout.split(',')[bandwidth_index])
|
||||
assert 400000 <= value <= 600000
|
||||
|
||||
def test_link_loss(self, core):
|
||||
"""
|
||||
Test ptp node network with modifying link packet loss.
|
||||
|
||||
:param conftest.Core core: core fixture to test with
|
||||
"""
|
||||
|
||||
# create switch
|
||||
ptp_node = core.session.add_object(cls=nodes.PtpNet)
|
||||
|
||||
# create nodes
|
||||
core.create_node("n1")
|
||||
core.create_node("n2")
|
||||
|
||||
# add interfaces
|
||||
interface_one = core.add_interface(ptp_node, "n1")
|
||||
interface_two = core.add_interface(ptp_node, "n2")
|
||||
|
||||
# instantiate session
|
||||
core.session.instantiate()
|
||||
|
||||
# assert node directories created
|
||||
core.assert_nodes()
|
||||
|
||||
# output csv index
|
||||
loss_index = -2
|
||||
|
||||
# run iperf, validate normal bandwidth
|
||||
stdout = core.iperf("n1", "n2")
|
||||
assert stdout
|
||||
value = float(stdout.split(',')[loss_index])
|
||||
assert 0 <= value <= 0.5
|
||||
|
||||
# change bandwidth in bits per second
|
||||
loss = 50
|
||||
core.configure_link(ptp_node, interface_one, interface_two, {
|
||||
"loss": loss
|
||||
})
|
||||
|
||||
# run iperf again
|
||||
stdout = core.iperf("n1", "n2")
|
||||
assert stdout
|
||||
value = float(stdout.split(',')[loss_index])
|
||||
assert 45 <= value <= 55
|
||||
|
||||
def test_link_delay(self, core):
|
||||
"""
|
||||
Test ptp node network with modifying link packet delay.
|
||||
|
||||
:param conftest.Core core: core fixture to test with
|
||||
"""
|
||||
|
||||
# create switch
|
||||
ptp_node = core.session.add_object(cls=nodes.PtpNet)
|
||||
|
||||
# create nodes
|
||||
core.create_node("n1")
|
||||
core.create_node("n2")
|
||||
|
||||
# add interfaces
|
||||
interface_one = core.add_interface(ptp_node, "n1")
|
||||
interface_two = core.add_interface(ptp_node, "n2")
|
||||
|
||||
# instantiate session
|
||||
core.session.instantiate()
|
||||
|
||||
# assert node directories created
|
||||
core.assert_nodes()
|
||||
|
||||
# run ping for delay information
|
||||
stdout = core.ping_output("n1", "n2")
|
||||
assert stdout
|
||||
rtt_line = stdout.split("\n")[-1]
|
||||
rtt_values = rtt_line.split("=")[1].split("ms")[0].strip()
|
||||
rtt_avg = float(rtt_values.split("/")[2])
|
||||
assert 0 <= rtt_avg <= 0.1
|
||||
|
||||
# change delay in microseconds
|
||||
delay = 1000000
|
||||
core.configure_link(ptp_node, interface_one, interface_two, {
|
||||
"delay": delay
|
||||
})
|
||||
|
||||
# run ping for delay information again
|
||||
stdout = core.ping_output("n1", "n2")
|
||||
assert stdout
|
||||
rtt_line = stdout.split("\n")[-1]
|
||||
rtt_values = rtt_line.split("=")[1].split("ms")[0].strip()
|
||||
rtt_avg = float(rtt_values.split("/")[2])
|
||||
assert 1800 <= rtt_avg <= 2200
|
||||
|
||||
def test_link_jitter(self, core):
|
||||
"""
|
||||
Test ptp node network with modifying link packet jitter.
|
||||
|
||||
:param conftest.Core core: core fixture to test with
|
||||
"""
|
||||
|
||||
# create link network
|
||||
ptp_node, interface_one, interface_two = core.create_link_network()
|
||||
|
||||
# output csv index
|
||||
jitter_index = 9
|
||||
|
||||
# run iperf
|
||||
stdout = core.iperf("n1", "n2")
|
||||
assert stdout
|
||||
value = float(stdout.split(",")[jitter_index])
|
||||
assert -0.5 <= value <= 0.05
|
||||
|
||||
# change jitter in microseconds
|
||||
jitter = 1000000
|
||||
core.configure_link(ptp_node, interface_one, interface_two, {
|
||||
"jitter": jitter
|
||||
})
|
||||
|
||||
# run iperf again
|
||||
stdout = core.iperf("n1", "n2")
|
||||
assert stdout
|
||||
value = float(stdout.split(",")[jitter_index])
|
||||
assert 200 <= value <= 500
|
Loading…
Reference in a new issue