fixed emane version checks, fixed emane config message handling, added initial emane test cases
This commit is contained in:
parent
613e550e8a
commit
dced47b588
8 changed files with 275 additions and 57 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
233
daemon/tests/test_emane.py
Normal 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
|
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue