fixed emane version checks, fixed emane config message handling, added initial emane test cases

This commit is contained in:
Blake J. Harnden 2017-07-10 09:25:33 -07:00
parent 613e550e8a
commit dced47b588
8 changed files with 275 additions and 57 deletions

View file

@ -348,7 +348,7 @@ class Configurable(object):
typeflags = ConfigFlags.UPDATE.value
else:
defaults = cls.getdefaultvalues()
typeflags = ConfigFlags.coreapi.CONF_TYPE_FLAGS_NONE
typeflags = ConfigFlags.NONE.value
values = manager.getconfig(node_id, cls.name, defaults)[1]
if values is None:
# node has no active config for this model (don't send defaults)

View file

@ -59,8 +59,6 @@ class EmaneManager(ConfigurableManager):
emulation, and for controlling the EMANE daemons.
"""
name = "emane"
version = None
versionstr = None
config_type = RegisterTlvs.EMULATION_SERVER.value
_hwaddr_prefix = "02:02"
(SUCCESS, NOT_NEEDED, NOT_READY) = (0, 1, 2)
@ -121,20 +119,21 @@ class EmaneManager(ConfigurableManager):
- For version >= 0.9.1 this is passed into the EventService
constructor.
"""
logger.info("initializing emane event service: %s", emane.VERSIONSTR)
self.deleteeventservice()
self.service = None
# EMANE 0.9.1+ does not require event service XML config
if EmaneManager.version >= emane.EMANE091:
if emane.VERSION >= emane.EMANE091:
if shutdown:
return
# Get the control network to be used for events
values = self.getconfig(None, "emane",
self.emane_config.getdefaultvalues())[1]
values = self.getconfig(None, "emane", self.emane_config.getdefaultvalues())[1]
group, port = self.emane_config.valueof('eventservicegroup', values).split(':')
eventdev = self.emane_config.valueof('eventservicedevice', values)
eventnetidx = self.session.get_control_net_index(eventdev)
if EmaneManager.version > emane.EMANE091:
if emane.VERSION > emane.EMANE091:
if eventnetidx < 0:
msg = "Invalid Event Service device provided: %s" % eventdev
logger.error(msg)
@ -913,8 +912,9 @@ class EmaneManager(ConfigurableManager):
try:
cmd = emanecmd + ["-f", os.path.join(path, "emane%d.log" % n), os.path.join(path, "platform%d.xml" % n)]
logger.info("Emane.startdaemons2() running %s" % str(cmd))
status = node.cmd(cmd, wait=True)
status, output = node.cmdresult(cmd)
logger.info("Emane.startdaemons2() return code %d" % status)
logger.info("Emane.startdaemons2() output: %s" % output)
except subprocess.CalledProcessError:
logger.exception("error starting emane")
@ -1151,7 +1151,7 @@ class EmaneManager(ConfigurableManager):
cmd = ['pkill', '-0', '-x', 'emane']
try:
if self.version < emane.EMANE092:
if emane.VERSION < emane.EMANE092:
status = subprocess.call(cmd)
else:
status = node.cmd(cmd, wait=True)

View file

@ -110,11 +110,11 @@ class EmaneRfPipeModel(EmaneModel):
mac = macdoc.getElementsByTagName("mac").pop()
mac.setAttribute("name", "RF-PIPE MAC")
mac.setAttribute("library", "rfpipemaclayer")
if e.version < e.EMANE091 and \
if emane.VERSION < emane.EMANE091 and \
self.valueof("transmissioncontrolmap", values) is "":
macnames.remove("transmissioncontrolmap")
# EMANE 0.7.4 support
if e.version == e.EMANE074:
if emane.VERSION == emane.EMANE074:
# convert datarate from bps to kbps
i = names.index('datarate')
values = list(values)

View file

@ -97,18 +97,16 @@ def maketuple(obj):
return obj,
# TODO: remove unused parameter type
def maketuplefromstr(s, type):
def maketuplefromstr(s, value_type):
"""
Create a tuple from a string.
:param str s: string to convert to a tuple
:param type: type of tuple to convert to
:param value_type: type of values to be contained within tuple
:return: tuple from string
:rtype: tuple
"""
s.replace("\\", "\\\\")
return ast.literal_eval(s)
return tuple(value_type(i) for i in s.split(","))
def mutecall(*args, **kwargs):

View file

@ -2,9 +2,6 @@
quagga.py: defines routing services provided by Quagga.
"""
import os
import re
from core import constants
from core.enumerations import LinkTypes, NodeTypes
from core.misc import ipaddress
@ -13,7 +10,6 @@ from core.service import CoreService
from core.service import ServiceManager
class Zebra(CoreService):
_name = "zebra"
_group = "Quagga"
@ -56,17 +52,9 @@ class Zebra(CoreService):
# we could verify here that filename == Quagga.conf
cfg = ""
for ifc in node.netifs():
if has_ovs == 0:
ifname = ifc.name
else:
ifnumstr = re.findall(r"\d+", ifc.name)
ifnum = ifnumstr[0]
ifname = "rtr%s" % ifnum
cfg += "interface %s\n" % ifname
#cfg += "interface %s\n" % ifc.name
cfg += "interface %s\n" % ifc.name
# include control interfaces in addressing but not routing daemons
if hasattr(ifc, 'control') and ifc.control == True:
if hasattr(ifc, 'control') and ifc.control is True:
cfg += " "
cfg += "\n ".join(map(cls.addrstr, ifc.addrlist))
cfg += "\n"
@ -104,7 +92,7 @@ class Zebra(CoreService):
for s in services:
if cls._name not in s._depends:
continue
cfg += s.generatequaggaconfig(node, services)
cfg += s.generatequaggaconfig(node)
return cfg
@staticmethod
@ -293,8 +281,8 @@ class Ospfv2(QuaggaService):
"""
_name = "OSPFv2"
_startup = ()
_shutdown = ("killall ospfd", )
_validate = ("pidof ospfd", )
_shutdown = ("killall ospfd",)
_validate = ("pidof ospfd",)
_ipv4_routing = True
@staticmethod
@ -368,8 +356,8 @@ class Ospfv3(QuaggaService):
"""
_name = "OSPFv3"
_startup = ()
_shutdown = ("killall ospf6d", )
_validate = ("pidof ospf6d", )
_shutdown = ("killall ospf6d",)
_validate = ("pidof ospf6d",)
_ipv4_routing = True
_ipv6_routing = True
@ -418,13 +406,6 @@ class Ospfv3(QuaggaService):
for ifc in node.netifs():
if hasattr(ifc, 'control') and ifc.control is True:
continue
if has_ovs == 0:
ifname = ifc.name
else:
ifnumstr = re.findall(r"\d+", ifc.name)
ifnum = ifnumstr[0]
ifname = "rtr%s" % ifnum
cfg += " interface %s area 0.0.0.0\n" % ifc.name
cfg += "!\n"
return cfg
@ -484,8 +465,8 @@ class Bgp(QuaggaService):
"""
_name = "BGP"
_startup = ()
_shutdown = ("killall bgpd", )
_validate = ("pidof bgpd", )
_shutdown = ("killall bgpd",)
_validate = ("pidof bgpd",)
_custom_needed = True
_ipv4_routing = True
_ipv6_routing = True
@ -509,8 +490,8 @@ class Rip(QuaggaService):
"""
_name = "RIP"
_startup = ()
_shutdown = ("killall ripd", )
_validate = ("pidof ripd", )
_shutdown = ("killall ripd",)
_validate = ("pidof ripd",)
_ipv4_routing = True
@classmethod
@ -532,8 +513,8 @@ class Ripng(QuaggaService):
"""
_name = "RIPNG"
_startup = ()
_shutdown = ("killall ripngd", )
_validate = ("pidof ripngd", )
_shutdown = ("killall ripngd",)
_validate = ("pidof ripngd",)
_ipv6_routing = True
@classmethod
@ -556,8 +537,8 @@ class Babel(QuaggaService):
"""
_name = "Babel"
_startup = ()
_shutdown = ("killall babeld", )
_validate = ("pidof babeld", )
_shutdown = ("killall babeld",)
_validate = ("pidof babeld",)
_ipv6_routing = True
@classmethod
@ -585,8 +566,8 @@ class Xpimd(QuaggaService):
"""
_name = 'Xpimd'
_startup = ()
_shutdown = ('killall xpimd', )
_validate = ('pidof xpimd', )
_shutdown = ('killall xpimd',)
_validate = ('pidof xpimd',)
_ipv4_routing = True
@classmethod

View file

@ -19,8 +19,8 @@ class Core(object):
self.nodes = {}
self.node_ips = {}
def create_node(self, name):
node = self.session.add_object(cls=nodes.CoreNode, name=name)
def create_node(self, name, cls=nodes.CoreNode, objid=None):
node = self.session.add_object(cls=cls, name=name, objid=objid)
self.nodes[name] = node
def add_interface(self, network, name):

233
daemon/tests/test_emane.py Normal file
View file

@ -0,0 +1,233 @@
"""
Unit tests for testing with a CORE switch.
"""
from core.emane.bypass import EmaneBypassModel
from core.emane.commeffect import EmaneCommEffectModel
from core.emane.ieee80211abg import EmaneIeee80211abgModel
from core.emane.nodes import EmaneNode
from core.emane.rfpipe import EmaneRfPipeModel
from core.services import quagga
from core.services import utility
class TestGui:
def test_80211(self, core):
"""
Test emane 80211 model.
:param conftest.Core core: core fixture to test with
"""
# load services
quagga.load_services()
utility.load_services()
# set and load emane models
core.session.master = True
core.session.location.setrefgeo(47.57917, -122.13232, 2.00000)
core.session.location.refscale = 150.0
core.session.emane.loadmodels()
# create emane node for networking the core nodes
emane_node = core.session.add_object(name="emane", cls=EmaneNode)
emane_node.setposition(x=80, y=50)
# set the emane model
emane_model = EmaneIeee80211abgModel
values = emane_model.getdefaultvalues()
core.session.emane.setconfig(emane_node.objid, emane_model.name, values)
# create nodes
core.create_node("n1", objid=1)
core.create_node("n2", objid=2)
node_one = core.get_node("n1")
node_two = core.get_node("n2")
# set node positions
node_one.setposition(x=150, y=150)
node_two.setposition(x=300, y=150)
# add services
services = "zebra|OSPFv3MDR|IPForward"
core.session.services.addservicestonode(node_one, "", services)
core.session.services.addservicestonode(node_two, "", services)
# add interfaces to nodes
core.add_interface(emane_node, "n1")
core.add_interface(emane_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_rfpipe(self, core):
"""
Test emane 80211 model.
:param conftest.Core core: core fixture to test with
"""
# load services
quagga.load_services()
utility.load_services()
# set and load emane models
core.session.master = True
core.session.location.setrefgeo(47.57917, -122.13232, 2.00000)
core.session.location.refscale = 150.0
core.session.emane.loadmodels()
# create emane node for networking the core nodes
emane_node = core.session.add_object(name="emane", cls=EmaneNode)
emane_node.setposition(x=80, y=50)
# set the emane model
emane_model = EmaneRfPipeModel
values = emane_model.getdefaultvalues()
core.session.emane.setconfig(emane_node.objid, emane_model.name, values)
# create nodes
core.create_node("n1", objid=1)
core.create_node("n2", objid=2)
node_one = core.get_node("n1")
node_two = core.get_node("n2")
# set node positions
node_one.setposition(x=150, y=150)
node_two.setposition(x=300, y=150)
# add services
services = "zebra|OSPFv3MDR|IPForward"
core.session.services.addservicestonode(node_one, "", services)
core.session.services.addservicestonode(node_two, "", services)
# add interfaces to nodes
core.add_interface(emane_node, "n1")
core.add_interface(emane_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_commeffect(self, core):
"""
Test emane 80211 model.
:param conftest.Core core: core fixture to test with
"""
# load services
quagga.load_services()
utility.load_services()
# set and load emane models
core.session.master = True
core.session.location.setrefgeo(47.57917, -122.13232, 2.00000)
core.session.location.refscale = 150.0
core.session.emane.loadmodels()
# create emane node for networking the core nodes
emane_node = core.session.add_object(name="emane", cls=EmaneNode)
emane_node.setposition(x=80, y=50)
# set the emane model
emane_model = EmaneCommEffectModel
values = emane_model.getdefaultvalues()
core.session.emane.setconfig(emane_node.objid, emane_model.name, values)
# create nodes
core.create_node("n1", objid=1)
core.create_node("n2", objid=2)
node_one = core.get_node("n1")
node_two = core.get_node("n2")
# set node positions
node_one.setposition(x=150, y=150)
node_two.setposition(x=300, y=150)
# add services
services = "zebra|OSPFv3MDR|IPForward"
core.session.services.addservicestonode(node_one, "", services)
core.session.services.addservicestonode(node_two, "", services)
# add interfaces to nodes
core.add_interface(emane_node, "n1")
core.add_interface(emane_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_bypass(self, core):
"""
Test emane 80211 model.
:param conftest.Core core: core fixture to test with
"""
# load services
quagga.load_services()
utility.load_services()
# set and load emane models
core.session.master = True
core.session.location.setrefgeo(47.57917, -122.13232, 2.00000)
core.session.location.refscale = 150.0
core.session.emane.loadmodels()
# create emane node for networking the core nodes
emane_node = core.session.add_object(name="emane", cls=EmaneNode)
emane_node.setposition(x=80, y=50)
# set the emane model
emane_model = EmaneBypassModel
values = emane_model.getdefaultvalues()
core.session.emane.setconfig(emane_node.objid, emane_model.name, values)
# create nodes
core.create_node("n1", objid=1)
core.create_node("n2", objid=2)
node_one = core.get_node("n1")
node_two = core.get_node("n2")
# set node positions
node_one.setposition(x=150, y=150)
node_two.setposition(x=300, y=150)
# add services
services = "zebra|OSPFv3MDR|IPForward"
core.session.services.addservicestonode(node_one, "", services)
core.session.services.addservicestonode(node_two, "", services)
# add interfaces to nodes
core.add_interface(emane_node, "n1")
core.add_interface(emane_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

View file

@ -3,10 +3,16 @@ Unit tests for testing with a CORE switch.
"""
from core.api import coreapi, dataconversion
from core.api.coreapi import CoreExecuteTlv
from core.enumerations import CORE_API_PORT, EventTypes, EventTlvs, MessageFlags, LinkTlvs, LinkTypes, ExecuteTlvs, \
MessageTypes
from core.enumerations import CORE_API_PORT
from core.enumerations import EventTlvs
from core.enumerations import EventTypes
from core.enumerations import ExecuteTlvs
from core.enumerations import LinkTlvs
from core.enumerations import LinkTypes
from core.enumerations import MessageFlags
from core.enumerations import MessageTypes
from core.misc import ipaddress
from core.netns.nodes import SwitchNode, CoreNode
from core.netns.nodes import SwitchNode
def cmd(node, exec_cmd):