moved emane dependent tests into subdir, moved pytest config into setup.cfg, added CoreError and made use of in session.py
This commit is contained in:
parent
4598bddcdb
commit
3776e1dda7
14 changed files with 208 additions and 201 deletions
|
@ -5,6 +5,7 @@ verify_ssl = true
|
||||||
|
|
||||||
[scripts]
|
[scripts]
|
||||||
coredev = "python scripts/core-daemon -f data/core.conf -l data/logging.conf"
|
coredev = "python scripts/core-daemon -f data/core.conf -l data/logging.conf"
|
||||||
|
coretest = "python -m pytest -v tests"
|
||||||
|
|
||||||
[dev-packages]
|
[dev-packages]
|
||||||
grpcio-tools = "*"
|
grpcio-tools = "*"
|
||||||
|
|
|
@ -31,3 +31,11 @@ class CoreCommandError(subprocess.CalledProcessError):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Command(%s), Status(%s):\n%s" % (self.cmd, self.returncode, self.output)
|
return "Command(%s), Status(%s):\n%s" % (self.cmd, self.returncode, self.output)
|
||||||
|
|
||||||
|
|
||||||
|
class CoreError(Exception):
|
||||||
|
"""
|
||||||
|
Used for errors when dealing with CoreEmu and Sessions.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
|
@ -10,6 +10,7 @@ from queue import Empty, Queue
|
||||||
|
|
||||||
import grpc
|
import grpc
|
||||||
|
|
||||||
|
from core import CoreError
|
||||||
from core.api.grpc import core_pb2, core_pb2_grpc
|
from core.api.grpc import core_pb2, core_pb2_grpc
|
||||||
from core.emulator.data import (
|
from core.emulator.data import (
|
||||||
ConfigData,
|
ConfigData,
|
||||||
|
@ -638,7 +639,11 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
lon = request.position.lon
|
lon = request.position.lon
|
||||||
alt = request.position.alt
|
alt = request.position.alt
|
||||||
node_options.set_location(lat, lon, alt)
|
node_options.set_location(lat, lon, alt)
|
||||||
result = session.update_node(node_id, node_options)
|
result = True
|
||||||
|
try:
|
||||||
|
session.update_node(node_id, node_options)
|
||||||
|
except CoreError:
|
||||||
|
result = False
|
||||||
return core_pb2.EditNodeResponse(result=result)
|
return core_pb2.EditNodeResponse(result=result)
|
||||||
|
|
||||||
def DeleteNode(self, request, context):
|
def DeleteNode(self, request, context):
|
||||||
|
|
|
@ -15,7 +15,7 @@ import time
|
||||||
from multiprocessing.pool import ThreadPool
|
from multiprocessing.pool import ThreadPool
|
||||||
|
|
||||||
import core.nodes.base
|
import core.nodes.base
|
||||||
from core import constants, utils
|
from core import CoreError, constants, utils
|
||||||
from core.api.tlv import coreapi
|
from core.api.tlv import coreapi
|
||||||
from core.api.tlv.broker import CoreBroker
|
from core.api.tlv.broker import CoreBroker
|
||||||
from core.emane.emanemanager import EmaneManager
|
from core.emane.emanemanager import EmaneManager
|
||||||
|
@ -190,16 +190,17 @@ class Session(object):
|
||||||
:param list objects: possible objects to deal with
|
:param list objects: possible objects to deal with
|
||||||
:param bool connect: link interfaces if True, unlink otherwise
|
:param bool connect: link interfaces if True, unlink otherwise
|
||||||
:return: nothing
|
:return: nothing
|
||||||
|
:raises core.CoreError: when objects to link is less than 2, or no common networks are found
|
||||||
"""
|
"""
|
||||||
objects = [x for x in objects if x]
|
objects = [x for x in objects if x]
|
||||||
if len(objects) < 2:
|
if len(objects) < 2:
|
||||||
raise ValueError("wireless link failure: %s", objects)
|
raise CoreError("wireless link failure: %s" % objects)
|
||||||
logging.debug(
|
logging.debug(
|
||||||
"handling wireless linking objects(%s) connect(%s)", objects, connect
|
"handling wireless linking objects(%s) connect(%s)", objects, connect
|
||||||
)
|
)
|
||||||
common_networks = objects[0].commonnets(objects[1])
|
common_networks = objects[0].commonnets(objects[1])
|
||||||
if not common_networks:
|
if not common_networks:
|
||||||
raise ValueError("no common network found for wireless link/unlink")
|
raise CoreError("no common network found for wireless link/unlink")
|
||||||
|
|
||||||
for common_network, interface_one, interface_two in common_networks:
|
for common_network, interface_one, interface_two in common_networks:
|
||||||
if not nodeutils.is_node(
|
if not nodeutils.is_node(
|
||||||
|
@ -238,7 +239,7 @@ class Session(object):
|
||||||
:param core.emulator.emudata.InterfaceData interface_one: node one interface data, defaults to none
|
:param core.emulator.emudata.InterfaceData interface_one: node one interface data, defaults to none
|
||||||
:param core.emulator.emudata.InterfaceData interface_two: node two interface data, defaults to none
|
:param core.emulator.emudata.InterfaceData interface_two: node two interface data, defaults to none
|
||||||
:param core.emulator.emudata.LinkOptions link_options: data for creating link, defaults to no options
|
:param core.emulator.emudata.LinkOptions link_options: data for creating link, defaults to no options
|
||||||
:return:
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
if not link_options:
|
if not link_options:
|
||||||
link_options = LinkOptions()
|
link_options = LinkOptions()
|
||||||
|
@ -373,6 +374,7 @@ class Session(object):
|
||||||
:param int interface_two_id: interface id for node two
|
:param int interface_two_id: interface id for node two
|
||||||
:param core.emulator.enumerations.LinkTypes link_type: link type to delete
|
:param core.emulator.enumerations.LinkTypes link_type: link type to delete
|
||||||
:return: nothing
|
:return: nothing
|
||||||
|
:raises core.CoreError: when no common network is found for link being deleted
|
||||||
"""
|
"""
|
||||||
# get node objects identified by link data
|
# get node objects identified by link data
|
||||||
node_one, node_two, net_one, net_two, _tunnel = self._link_nodes(
|
node_one, node_two, net_one, net_two, _tunnel = self._link_nodes(
|
||||||
|
@ -417,7 +419,7 @@ class Session(object):
|
||||||
if interface_one.net != interface_two.net and all(
|
if interface_one.net != interface_two.net and all(
|
||||||
[interface_one.up, interface_two.up]
|
[interface_one.up, interface_two.up]
|
||||||
):
|
):
|
||||||
raise ValueError("no common network found")
|
raise CoreError("no common network found")
|
||||||
|
|
||||||
logging.info(
|
logging.info(
|
||||||
"deleting link node(%s):interface(%s) node(%s):interface(%s)",
|
"deleting link node(%s):interface(%s) node(%s):interface(%s)",
|
||||||
|
@ -478,6 +480,8 @@ class Session(object):
|
||||||
:param int interface_two_id: interface id for node two
|
:param int interface_two_id: interface id for node two
|
||||||
:param core.emulator.emudata.LinkOptions link_options: data to update link with
|
:param core.emulator.emudata.LinkOptions link_options: data to update link with
|
||||||
:return: nothing
|
:return: nothing
|
||||||
|
:raises core.CoreError: when updating a wireless type link, when there is a unknown
|
||||||
|
link between networks
|
||||||
"""
|
"""
|
||||||
if not link_options:
|
if not link_options:
|
||||||
link_options = LinkOptions()
|
link_options = LinkOptions()
|
||||||
|
@ -495,7 +499,7 @@ class Session(object):
|
||||||
try:
|
try:
|
||||||
# wireless link
|
# wireless link
|
||||||
if link_options.type == LinkTypes.WIRELESS.value:
|
if link_options.type == LinkTypes.WIRELESS.value:
|
||||||
raise ValueError("cannot update wireless link")
|
raise CoreError("cannot update wireless link")
|
||||||
else:
|
else:
|
||||||
if not node_one and not node_two:
|
if not node_one and not node_two:
|
||||||
if net_one and net_two:
|
if net_one and net_two:
|
||||||
|
@ -508,7 +512,7 @@ class Session(object):
|
||||||
interface = net_two.getlinknetif(net_one)
|
interface = net_two.getlinknetif(net_one)
|
||||||
|
|
||||||
if not interface:
|
if not interface:
|
||||||
raise ValueError("modify unknown link between nets")
|
raise CoreError("modify unknown link between nets")
|
||||||
|
|
||||||
if upstream:
|
if upstream:
|
||||||
interface.swapparams("_params_up")
|
interface.swapparams("_params_up")
|
||||||
|
@ -532,7 +536,7 @@ class Session(object):
|
||||||
)
|
)
|
||||||
interface.swapparams("_params_up")
|
interface.swapparams("_params_up")
|
||||||
else:
|
else:
|
||||||
raise ValueError("modify link for unknown nodes")
|
raise CoreError("modify link for unknown nodes")
|
||||||
elif not node_one:
|
elif not node_one:
|
||||||
# node1 = layer 2node, node2 = layer3 node
|
# node1 = layer 2node, node2 = layer3 node
|
||||||
interface = node_two.netif(interface_two_id, net_one)
|
interface = node_two.netif(interface_two_id, net_one)
|
||||||
|
@ -544,7 +548,7 @@ class Session(object):
|
||||||
else:
|
else:
|
||||||
common_networks = node_one.commonnets(node_two)
|
common_networks = node_one.commonnets(node_two)
|
||||||
if not common_networks:
|
if not common_networks:
|
||||||
raise ValueError("no common network found")
|
raise CoreError("no common network found")
|
||||||
|
|
||||||
for net_one, interface_one, interface_two in common_networks:
|
for net_one, interface_one, interface_two in common_networks:
|
||||||
if (
|
if (
|
||||||
|
@ -666,25 +670,17 @@ class Session(object):
|
||||||
:param core.emulator.emudata.NodeOptions node_options: data to update node with
|
:param core.emulator.emudata.NodeOptions node_options: data to update node with
|
||||||
:return: True if node updated, False otherwise
|
:return: True if node updated, False otherwise
|
||||||
:rtype: bool
|
:rtype: bool
|
||||||
|
:raises core.CoreError: when node to update does not exist
|
||||||
"""
|
"""
|
||||||
result = False
|
# get node to update
|
||||||
try:
|
node = self.get_node(node_id)
|
||||||
# get node to update
|
|
||||||
node = self.get_node(node_id)
|
|
||||||
|
|
||||||
# set node position and broadcast it
|
# set node position and broadcast it
|
||||||
self.set_node_position(node, node_options)
|
self.set_node_position(node, node_options)
|
||||||
|
|
||||||
# update attributes
|
# update attributes
|
||||||
node.canvas = node_options.canvas
|
node.canvas = node_options.canvas
|
||||||
node.icon = node_options.icon
|
node.icon = node_options.icon
|
||||||
|
|
||||||
# set node as updated successfully
|
|
||||||
result = True
|
|
||||||
except KeyError:
|
|
||||||
logging.error("failure to update node that does not exist: %s", node_id)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def set_node_position(self, node, node_options):
|
def set_node_position(self, node, node_options):
|
||||||
"""
|
"""
|
||||||
|
@ -1156,7 +1152,7 @@ class Session(object):
|
||||||
"""
|
"""
|
||||||
hooks = self._state_hooks.setdefault(state, [])
|
hooks = self._state_hooks.setdefault(state, [])
|
||||||
if hook in hooks:
|
if hook in hooks:
|
||||||
raise ValueError("attempting to add duplicate state hook")
|
raise CoreError("attempting to add duplicate state hook")
|
||||||
hooks.append(hook)
|
hooks.append(hook)
|
||||||
|
|
||||||
if self.state == state:
|
if self.state == state:
|
||||||
|
@ -1283,21 +1279,22 @@ class Session(object):
|
||||||
|
|
||||||
return node_id
|
return node_id
|
||||||
|
|
||||||
def create_node(self, cls, *clsargs, **clskwds):
|
def create_node(self, cls, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Create an emulation node.
|
Create an emulation node.
|
||||||
|
|
||||||
:param class cls: node class to create
|
:param class cls: node class to create
|
||||||
:param list clsargs: list of arguments for the class to create
|
:param list args: list of arguments for the class to create
|
||||||
:param dict clskwds: dictionary of arguments for the class to create
|
:param dict kwargs: dictionary of arguments for the class to create
|
||||||
:return: the created node instance
|
:return: the created node instance
|
||||||
|
:raises core.CoreError: when id of the node to create already exists
|
||||||
"""
|
"""
|
||||||
node = cls(self, *clsargs, **clskwds)
|
node = cls(self, *args, **kwargs)
|
||||||
|
|
||||||
with self._nodes_lock:
|
with self._nodes_lock:
|
||||||
if node.id in self.nodes:
|
if node.id in self.nodes:
|
||||||
node.shutdown()
|
node.shutdown()
|
||||||
raise KeyError("duplicate node id %s for %s" % (node.id, node.name))
|
raise CoreError("duplicate node id %s for %s" % (node.id, node.name))
|
||||||
self.nodes[node.id] = node
|
self.nodes[node.id] = node
|
||||||
|
|
||||||
return node
|
return node
|
||||||
|
@ -1309,9 +1306,10 @@ class Session(object):
|
||||||
:param int _id: node id to retrieve
|
:param int _id: node id to retrieve
|
||||||
:return: node for the given id
|
:return: node for the given id
|
||||||
:rtype: core.nodes.base.CoreNode
|
:rtype: core.nodes.base.CoreNode
|
||||||
|
:raises core.CoreError: when node does not exist
|
||||||
"""
|
"""
|
||||||
if _id not in self.nodes:
|
if _id not in self.nodes:
|
||||||
raise KeyError("unknown node id %s" % _id)
|
raise CoreError("unknown node id %s" % _id)
|
||||||
return self.nodes[_id]
|
return self.nodes[_id]
|
||||||
|
|
||||||
def delete_node(self, _id):
|
def delete_node(self, _id):
|
||||||
|
|
|
@ -234,16 +234,6 @@ class CoreNodeBase(NodeBase):
|
||||||
self.nodedir = None
|
self.nodedir = None
|
||||||
self.tmpnodedir = False
|
self.tmpnodedir = False
|
||||||
|
|
||||||
def addservice(self, service):
|
|
||||||
"""
|
|
||||||
Add a services to the service list.
|
|
||||||
|
|
||||||
:param core.services.coreservices.CoreService service: service to add
|
|
||||||
:return: nothing
|
|
||||||
"""
|
|
||||||
if service is not None:
|
|
||||||
self.services.append(service)
|
|
||||||
|
|
||||||
def makenodedir(self):
|
def makenodedir(self):
|
||||||
"""
|
"""
|
||||||
Create the node directory.
|
Create the node directory.
|
||||||
|
|
|
@ -415,7 +415,7 @@ class CoreServices(object):
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
logging.info("adding service to node(%s): %s", node.name, service_name)
|
logging.info("adding service to node(%s): %s", node.name, service_name)
|
||||||
node.addservice(service)
|
node.services.append(service)
|
||||||
|
|
||||||
def all_configs(self):
|
def all_configs(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -15,3 +15,6 @@ max-line-length=100
|
||||||
max-complexity=26
|
max-complexity=26
|
||||||
select=B,C,E,F,W,T4
|
select=B,C,E,F,W,T4
|
||||||
exclude=*_pb2*.py,utm.py,doc,build
|
exclude=*_pb2*.py,utm.py,doc,build
|
||||||
|
|
||||||
|
[tool:pytest]
|
||||||
|
norecursedirs=distributed emane
|
||||||
|
|
138
daemon/tests/emane/test_emane.py
Normal file
138
daemon/tests/emane/test_emane.py
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
"""
|
||||||
|
Unit tests for testing CORE EMANE networks.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from conftest import ping
|
||||||
|
from core import CoreError
|
||||||
|
from core.emane.bypass import EmaneBypassModel
|
||||||
|
from core.emane.commeffect import EmaneCommEffectModel
|
||||||
|
from core.emane.ieee80211abg import EmaneIeee80211abgModel
|
||||||
|
from core.emane.rfpipe import EmaneRfPipeModel
|
||||||
|
from core.emane.tdma import EmaneTdmaModel
|
||||||
|
from core.emulator.emudata import NodeOptions
|
||||||
|
|
||||||
|
_EMANE_MODELS = [
|
||||||
|
EmaneIeee80211abgModel,
|
||||||
|
EmaneRfPipeModel,
|
||||||
|
EmaneBypassModel,
|
||||||
|
EmaneCommEffectModel,
|
||||||
|
EmaneTdmaModel,
|
||||||
|
]
|
||||||
|
_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
class TestEmane:
|
||||||
|
@pytest.mark.parametrize("model", _EMANE_MODELS)
|
||||||
|
def test_models(self, session, model, ip_prefixes):
|
||||||
|
"""
|
||||||
|
Test emane models within a basic network.
|
||||||
|
|
||||||
|
:param core.emulator.coreemu.EmuSession session: session for test
|
||||||
|
:param model: emane model to test
|
||||||
|
:param ip_prefixes: generates ip addresses for nodes
|
||||||
|
"""
|
||||||
|
|
||||||
|
# create emane node for networking the core nodes
|
||||||
|
emane_network = session.create_emane_network(
|
||||||
|
model, geo_reference=(47.57917, -122.13232, 2.00000)
|
||||||
|
)
|
||||||
|
emane_network.setposition(x=80, y=50)
|
||||||
|
|
||||||
|
# configure tdma
|
||||||
|
if model == EmaneTdmaModel:
|
||||||
|
session.emane.set_model_config(
|
||||||
|
emane_network.id,
|
||||||
|
EmaneTdmaModel.name,
|
||||||
|
{"schedule": os.path.join(_DIR, "../examples/tdma/schedule.xml")},
|
||||||
|
)
|
||||||
|
|
||||||
|
# create nodes
|
||||||
|
node_options = NodeOptions()
|
||||||
|
node_options.set_position(150, 150)
|
||||||
|
node_one = session.create_wireless_node(node_options=node_options)
|
||||||
|
node_options.set_position(300, 150)
|
||||||
|
node_two = session.create_wireless_node(node_options=node_options)
|
||||||
|
|
||||||
|
for i, node in enumerate([node_one, node_two]):
|
||||||
|
node.setposition(x=150 * (i + 1), y=150)
|
||||||
|
interface = ip_prefixes.create_interface(node)
|
||||||
|
session.add_link(node.id, emane_network.id, interface_one=interface)
|
||||||
|
|
||||||
|
# instantiate session
|
||||||
|
session.instantiate()
|
||||||
|
|
||||||
|
# ping n2 from n1 and assert success
|
||||||
|
status = ping(node_one, node_two, ip_prefixes, count=5)
|
||||||
|
assert not status
|
||||||
|
|
||||||
|
def test_xml_emane(self, session, tmpdir, ip_prefixes):
|
||||||
|
"""
|
||||||
|
Test xml client methods for emane.
|
||||||
|
|
||||||
|
:param session: session for test
|
||||||
|
:param tmpdir: tmpdir to create data in
|
||||||
|
:param ip_prefixes: generates ip addresses for nodes
|
||||||
|
"""
|
||||||
|
# create emane node for networking the core nodes
|
||||||
|
emane_network = session.create_emane_network(
|
||||||
|
EmaneIeee80211abgModel,
|
||||||
|
geo_reference=(47.57917, -122.13232, 2.00000),
|
||||||
|
config={"test": "1"},
|
||||||
|
)
|
||||||
|
emane_network.setposition(x=80, y=50)
|
||||||
|
|
||||||
|
# create nodes
|
||||||
|
node_options = NodeOptions()
|
||||||
|
node_options.set_position(150, 150)
|
||||||
|
node_one = session.create_wireless_node(node_options=node_options)
|
||||||
|
node_options.set_position(300, 150)
|
||||||
|
node_two = session.create_wireless_node(node_options=node_options)
|
||||||
|
|
||||||
|
for i, node in enumerate([node_one, node_two]):
|
||||||
|
node.setposition(x=150 * (i + 1), y=150)
|
||||||
|
interface = ip_prefixes.create_interface(node)
|
||||||
|
session.add_link(node.id, emane_network.id, interface_one=interface)
|
||||||
|
|
||||||
|
# instantiate session
|
||||||
|
session.instantiate()
|
||||||
|
|
||||||
|
# get ids for nodes
|
||||||
|
emane_id = emane_network.id
|
||||||
|
n1_id = node_one.id
|
||||||
|
n2_id = node_two.id
|
||||||
|
|
||||||
|
# save xml
|
||||||
|
xml_file = tmpdir.join("session.xml")
|
||||||
|
file_path = xml_file.strpath
|
||||||
|
session.save_xml(file_path)
|
||||||
|
|
||||||
|
# verify xml file was created and can be parsed
|
||||||
|
assert xml_file.isfile()
|
||||||
|
assert ElementTree.parse(file_path)
|
||||||
|
|
||||||
|
# stop current session, clearing data
|
||||||
|
session.shutdown()
|
||||||
|
|
||||||
|
# verify nodes have been removed from session
|
||||||
|
with pytest.raises(CoreError):
|
||||||
|
assert not session.get_node(n1_id)
|
||||||
|
with pytest.raises(CoreError):
|
||||||
|
assert not session.get_node(n2_id)
|
||||||
|
|
||||||
|
# load saved xml
|
||||||
|
session.open_xml(file_path, start=True)
|
||||||
|
|
||||||
|
# retrieve configuration we set originally
|
||||||
|
value = str(
|
||||||
|
session.emane.get_config("test", emane_id, EmaneIeee80211abgModel.name)
|
||||||
|
)
|
||||||
|
|
||||||
|
# verify nodes and configuration were restored
|
||||||
|
assert session.get_node(n1_id)
|
||||||
|
assert session.get_node(n2_id)
|
||||||
|
assert session.get_node(emane_id)
|
||||||
|
assert value == "1"
|
|
@ -1,2 +0,0 @@
|
||||||
[pytest]
|
|
||||||
norecursedirs = distributed
|
|
|
@ -1,68 +0,0 @@
|
||||||
"""
|
|
||||||
Unit tests for testing CORE EMANE networks.
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from conftest import ping
|
|
||||||
from core.emane.bypass import EmaneBypassModel
|
|
||||||
from core.emane.commeffect import EmaneCommEffectModel
|
|
||||||
from core.emane.ieee80211abg import EmaneIeee80211abgModel
|
|
||||||
from core.emane.rfpipe import EmaneRfPipeModel
|
|
||||||
from core.emane.tdma import EmaneTdmaModel
|
|
||||||
from core.emulator.emudata import NodeOptions
|
|
||||||
|
|
||||||
_EMANE_MODELS = [
|
|
||||||
EmaneIeee80211abgModel,
|
|
||||||
EmaneRfPipeModel,
|
|
||||||
EmaneBypassModel,
|
|
||||||
EmaneCommEffectModel,
|
|
||||||
EmaneTdmaModel,
|
|
||||||
]
|
|
||||||
_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
|
|
||||||
|
|
||||||
class TestEmane:
|
|
||||||
@pytest.mark.parametrize("model", _EMANE_MODELS)
|
|
||||||
def test_models(self, session, model, ip_prefixes):
|
|
||||||
"""
|
|
||||||
Test emane models within a basic network.
|
|
||||||
|
|
||||||
:param core.emulator.coreemu.EmuSession session: session for test
|
|
||||||
:param model: emane model to test
|
|
||||||
:param ip_prefixes: generates ip addresses for nodes
|
|
||||||
"""
|
|
||||||
|
|
||||||
# create emane node for networking the core nodes
|
|
||||||
emane_network = session.create_emane_network(
|
|
||||||
model, geo_reference=(47.57917, -122.13232, 2.00000)
|
|
||||||
)
|
|
||||||
emane_network.setposition(x=80, y=50)
|
|
||||||
|
|
||||||
# configure tdma
|
|
||||||
if model == EmaneTdmaModel:
|
|
||||||
session.emane.set_model_config(
|
|
||||||
emane_network.id,
|
|
||||||
EmaneTdmaModel.name,
|
|
||||||
{"schedule": os.path.join(_DIR, "../examples/tdma/schedule.xml")},
|
|
||||||
)
|
|
||||||
|
|
||||||
# create nodes
|
|
||||||
node_options = NodeOptions()
|
|
||||||
node_options.set_position(150, 150)
|
|
||||||
node_one = session.create_wireless_node(node_options=node_options)
|
|
||||||
node_options.set_position(300, 150)
|
|
||||||
node_two = session.create_wireless_node(node_options=node_options)
|
|
||||||
|
|
||||||
for i, node in enumerate([node_one, node_two]):
|
|
||||||
node.setposition(x=150 * (i + 1), y=150)
|
|
||||||
interface = ip_prefixes.create_interface(node)
|
|
||||||
session.add_link(node.id, emane_network.id, interface_one=interface)
|
|
||||||
|
|
||||||
# instantiate session
|
|
||||||
session.instantiate()
|
|
||||||
|
|
||||||
# ping n2 from n1 and assert success
|
|
||||||
status = ping(node_one, node_two, ip_prefixes, count=5)
|
|
||||||
assert not status
|
|
|
@ -5,6 +5,7 @@ from queue import Queue
|
||||||
import grpc
|
import grpc
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from core import CoreError
|
||||||
from core.api.grpc import core_pb2
|
from core.api.grpc import core_pb2
|
||||||
from core.api.grpc.client import CoreGrpcClient
|
from core.api.grpc.client import CoreGrpcClient
|
||||||
from core.config import ConfigShim
|
from core.config import ConfigShim
|
||||||
|
@ -239,7 +240,7 @@ class TestGrpc:
|
||||||
# then
|
# then
|
||||||
assert response.result is expected
|
assert response.result is expected
|
||||||
if expected is True:
|
if expected is True:
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert session.get_node(node.id)
|
assert session.get_node(node.id)
|
||||||
|
|
||||||
def test_node_command(self, grpc_server):
|
def test_node_command(self, grpc_server):
|
||||||
|
|
|
@ -7,6 +7,7 @@ import time
|
||||||
import mock
|
import mock
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from core import CoreError
|
||||||
from core.api.tlv import coreapi
|
from core.api.tlv import coreapi
|
||||||
from core.emane.ieee80211abg import EmaneIeee80211abgModel
|
from core.emane.ieee80211abg import EmaneIeee80211abgModel
|
||||||
from core.emulator.enumerations import (
|
from core.emulator.enumerations import (
|
||||||
|
@ -92,7 +93,7 @@ class TestGui:
|
||||||
|
|
||||||
coreserver.request_handler.handle_message(message)
|
coreserver.request_handler.handle_message(message)
|
||||||
|
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
coreserver.session.get_node(node_id)
|
coreserver.session.get_node(node_id)
|
||||||
|
|
||||||
def test_link_add_node_to_net(self, coreserver):
|
def test_link_add_node_to_net(self, coreserver):
|
||||||
|
|
|
@ -3,7 +3,7 @@ import time
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from core import utils
|
from core import CoreError, utils
|
||||||
from core.emulator.emudata import NodeOptions
|
from core.emulator.emudata import NodeOptions
|
||||||
from core.emulator.enumerations import NodeTypes
|
from core.emulator.enumerations import NodeTypes
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ class TestNodes:
|
||||||
session.delete_node(node.id)
|
session.delete_node(node.id)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
session.get_node(node.id)
|
session.get_node(node.id)
|
||||||
|
|
||||||
@pytest.mark.parametrize("net_type", NET_TYPES)
|
@pytest.mark.parametrize("net_type", NET_TYPES)
|
||||||
|
|
|
@ -2,7 +2,7 @@ from xml.etree import ElementTree
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from core.emane.ieee80211abg import EmaneIeee80211abgModel
|
from core import CoreError
|
||||||
from core.emulator.emudata import LinkOptions, NodeOptions
|
from core.emulator.emudata import LinkOptions, NodeOptions
|
||||||
from core.emulator.enumerations import NodeTypes
|
from core.emulator.enumerations import NodeTypes
|
||||||
from core.location.mobility import BasicRangeModel
|
from core.location.mobility import BasicRangeModel
|
||||||
|
@ -84,9 +84,9 @@ class TestXml:
|
||||||
session.shutdown()
|
session.shutdown()
|
||||||
|
|
||||||
# verify nodes have been removed from session
|
# verify nodes have been removed from session
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n1_id)
|
assert not session.get_node(n1_id)
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n2_id)
|
assert not session.get_node(n2_id)
|
||||||
|
|
||||||
# load saved xml
|
# load saved xml
|
||||||
|
@ -145,9 +145,9 @@ class TestXml:
|
||||||
session.shutdown()
|
session.shutdown()
|
||||||
|
|
||||||
# verify nodes have been removed from session
|
# verify nodes have been removed from session
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n1_id)
|
assert not session.get_node(n1_id)
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n2_id)
|
assert not session.get_node(n2_id)
|
||||||
|
|
||||||
# load saved xml
|
# load saved xml
|
||||||
|
@ -205,9 +205,9 @@ class TestXml:
|
||||||
session.shutdown()
|
session.shutdown()
|
||||||
|
|
||||||
# verify nodes have been removed from session
|
# verify nodes have been removed from session
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n1_id)
|
assert not session.get_node(n1_id)
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n2_id)
|
assert not session.get_node(n2_id)
|
||||||
|
|
||||||
# load saved xml
|
# load saved xml
|
||||||
|
@ -222,74 +222,6 @@ class TestXml:
|
||||||
assert session.get_node(wlan_id)
|
assert session.get_node(wlan_id)
|
||||||
assert value == "1"
|
assert value == "1"
|
||||||
|
|
||||||
def test_xml_emane(self, session, tmpdir, ip_prefixes):
|
|
||||||
"""
|
|
||||||
Test xml client methods for emane.
|
|
||||||
|
|
||||||
:param session: session for test
|
|
||||||
:param tmpdir: tmpdir to create data in
|
|
||||||
:param ip_prefixes: generates ip addresses for nodes
|
|
||||||
"""
|
|
||||||
# create emane node for networking the core nodes
|
|
||||||
emane_network = session.create_emane_network(
|
|
||||||
EmaneIeee80211abgModel,
|
|
||||||
geo_reference=(47.57917, -122.13232, 2.00000),
|
|
||||||
config={"test": "1"},
|
|
||||||
)
|
|
||||||
emane_network.setposition(x=80, y=50)
|
|
||||||
|
|
||||||
# create nodes
|
|
||||||
node_options = NodeOptions()
|
|
||||||
node_options.set_position(150, 150)
|
|
||||||
node_one = session.create_wireless_node(node_options=node_options)
|
|
||||||
node_options.set_position(300, 150)
|
|
||||||
node_two = session.create_wireless_node(node_options=node_options)
|
|
||||||
|
|
||||||
for i, node in enumerate([node_one, node_two]):
|
|
||||||
node.setposition(x=150 * (i + 1), y=150)
|
|
||||||
interface = ip_prefixes.create_interface(node)
|
|
||||||
session.add_link(node.id, emane_network.id, interface_one=interface)
|
|
||||||
|
|
||||||
# instantiate session
|
|
||||||
session.instantiate()
|
|
||||||
|
|
||||||
# get ids for nodes
|
|
||||||
emane_id = emane_network.id
|
|
||||||
n1_id = node_one.id
|
|
||||||
n2_id = node_two.id
|
|
||||||
|
|
||||||
# save xml
|
|
||||||
xml_file = tmpdir.join("session.xml")
|
|
||||||
file_path = xml_file.strpath
|
|
||||||
session.save_xml(file_path)
|
|
||||||
|
|
||||||
# verify xml file was created and can be parsed
|
|
||||||
assert xml_file.isfile()
|
|
||||||
assert ElementTree.parse(file_path)
|
|
||||||
|
|
||||||
# stop current session, clearing data
|
|
||||||
session.shutdown()
|
|
||||||
|
|
||||||
# verify nodes have been removed from session
|
|
||||||
with pytest.raises(KeyError):
|
|
||||||
assert not session.get_node(n1_id)
|
|
||||||
with pytest.raises(KeyError):
|
|
||||||
assert not session.get_node(n2_id)
|
|
||||||
|
|
||||||
# load saved xml
|
|
||||||
session.open_xml(file_path, start=True)
|
|
||||||
|
|
||||||
# retrieve configuration we set originally
|
|
||||||
value = str(
|
|
||||||
session.emane.get_config("test", emane_id, EmaneIeee80211abgModel.name)
|
|
||||||
)
|
|
||||||
|
|
||||||
# verify nodes and configuration were restored
|
|
||||||
assert session.get_node(n1_id)
|
|
||||||
assert session.get_node(n2_id)
|
|
||||||
assert session.get_node(emane_id)
|
|
||||||
assert value == "1"
|
|
||||||
|
|
||||||
def test_network_to_network(self, session, tmpdir):
|
def test_network_to_network(self, session, tmpdir):
|
||||||
"""
|
"""
|
||||||
Test xml generation when dealing with network to network nodes.
|
Test xml generation when dealing with network to network nodes.
|
||||||
|
@ -324,9 +256,9 @@ class TestXml:
|
||||||
session.shutdown()
|
session.shutdown()
|
||||||
|
|
||||||
# verify nodes have been removed from session
|
# verify nodes have been removed from session
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n1_id)
|
assert not session.get_node(n1_id)
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n2_id)
|
assert not session.get_node(n2_id)
|
||||||
|
|
||||||
# load saved xml
|
# load saved xml
|
||||||
|
@ -383,9 +315,9 @@ class TestXml:
|
||||||
session.shutdown()
|
session.shutdown()
|
||||||
|
|
||||||
# verify nodes have been removed from session
|
# verify nodes have been removed from session
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n1_id)
|
assert not session.get_node(n1_id)
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n2_id)
|
assert not session.get_node(n2_id)
|
||||||
|
|
||||||
# load saved xml
|
# load saved xml
|
||||||
|
@ -450,9 +382,9 @@ class TestXml:
|
||||||
session.shutdown()
|
session.shutdown()
|
||||||
|
|
||||||
# verify nodes have been removed from session
|
# verify nodes have been removed from session
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n1_id)
|
assert not session.get_node(n1_id)
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n2_id)
|
assert not session.get_node(n2_id)
|
||||||
|
|
||||||
# load saved xml
|
# load saved xml
|
||||||
|
@ -532,9 +464,9 @@ class TestXml:
|
||||||
session.shutdown()
|
session.shutdown()
|
||||||
|
|
||||||
# verify nodes have been removed from session
|
# verify nodes have been removed from session
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n1_id)
|
assert not session.get_node(n1_id)
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(CoreError):
|
||||||
assert not session.get_node(n2_id)
|
assert not session.get_node(n2_id)
|
||||||
|
|
||||||
# load saved xml
|
# load saved xml
|
||||||
|
|
Loading…
Add table
Reference in a new issue