From cdc84ca63a26fa2b56ee6f71d051decde6afc217 Mon Sep 17 00:00:00 2001 From: Alina Quereilhac Date: Tue, 4 Feb 2014 15:01:24 +0100 Subject: [PATCH] Almost working local example for linux ns-3 simulator --- src/nepi/execution/ec.py | 1 - src/nepi/execution/resource.py | 9 ++- .../resources/linux/ccn/ccnapplication.py | 1 - src/nepi/resources/linux/ccn/ccncontent.py | 1 - src/nepi/resources/linux/ccn/ccnd.py | 1 - src/nepi/resources/linux/ccn/ccnr.py | 1 - src/nepi/resources/linux/ccn/fibentry.py | 1 - src/nepi/resources/linux/ns3/ns3simulator.py | 12 +++- src/nepi/resources/linux/udptunnel.py | 1 - src/nepi/resources/ns3/ns3application.py | 22 +++++- src/nepi/resources/ns3/ns3arpl3protocol.py | 44 ++++++++++++ src/nepi/resources/ns3/ns3base.py | 47 ++++++------ src/nepi/resources/ns3/ns3channel.py | 23 ++++-- src/nepi/resources/ns3/ns3errormodel.py | 20 +++--- src/nepi/resources/ns3/ns3errorratemodel.py | 22 +++--- src/nepi/resources/ns3/ns3icmpv4l4protocol.py | 44 ++++++++++++ src/nepi/resources/ns3/ns3ipv4l3protocol.py | 18 +++++ src/nepi/resources/ns3/ns3netdevice.py | 35 +++++++-- src/nepi/resources/ns3/ns3node.py | 12 ++-- .../resources/ns3/ns3propagationdelaymodel.py | 22 +++--- .../resources/ns3/ns3propagationlossmodel.py | 22 +++--- src/nepi/resources/ns3/ns3queue.py | 24 ++++--- src/nepi/resources/ns3/ns3wifimac.py | 24 ++++--- src/nepi/resources/ns3/ns3wifiphy.py | 28 +++++--- .../ns3/ns3wifiremotestationmanager.py | 29 ++++---- .../ns3/resource_manager_generator.py | 72 ++++++++----------- src/nepi/resources/planetlab/tap.py | 1 - test/resources/linux/ns3/ns3simulator.py | 6 +- 28 files changed, 363 insertions(+), 180 deletions(-) create mode 100644 src/nepi/resources/ns3/ns3arpl3protocol.py create mode 100644 src/nepi/resources/ns3/ns3icmpv4l4protocol.py diff --git a/src/nepi/execution/ec.py b/src/nepi/execution/ec.py index 47110a43..571b3d5c 100644 --- a/src/nepi/execution/ec.py +++ b/src/nepi/execution/ec.py @@ -747,7 +747,6 @@ class ExperimentController(object): break if reschedule: - callback = functools.partial(wait_all_and_start, group) self.schedule("1s", callback) else: diff --git a/src/nepi/execution/resource.py b/src/nepi/execution/resource.py index f0fad39a..15375c80 100644 --- a/src/nepi/execution/resource.py +++ b/src/nepi/execution/resource.py @@ -512,7 +512,6 @@ class ResourceManager(Logger): with self._release_lock: if self._state != ResourceState.RELEASED: self.do_deploy() - self.debug("----- READY ---- ") def release(self): """ Perform actions to free resources used by the RM. @@ -533,7 +532,6 @@ class ResourceManager(Logger): self.error(err) self.set_released() - self.debug("----- RELEASED ---- ") def fail(self): """ Sets the RM to state FAILED. @@ -955,30 +953,37 @@ class ResourceManager(Logger): def set_started(self): """ Mark ResourceManager as STARTED """ self.set_state(ResourceState.STARTED, "_start_time") + self.debug("----- STARTED ---- ") def set_stopped(self): """ Mark ResourceManager as STOPPED """ self.set_state(ResourceState.STOPPED, "_stop_time") + self.debug("----- STOPPED ---- ") def set_ready(self): """ Mark ResourceManager as READY """ self.set_state(ResourceState.READY, "_ready_time") + self.debug("----- READY ---- ") def set_released(self): """ Mark ResourceManager as REALEASED """ self.set_state(ResourceState.RELEASED, "_release_time") + self.debug("----- RELEASED ---- ") def set_failed(self): """ Mark ResourceManager as FAILED """ self.set_state(ResourceState.FAILED, "_failed_time") + self.debug("----- FAILED ---- ") def set_discovered(self): """ Mark ResourceManager as DISCOVERED """ self.set_state(ResourceState.DISCOVERED, "_discover_time") + self.debug("----- DISCOVERED ---- ") def set_provisioned(self): """ Mark ResourceManager as PROVISIONED """ self.set_state(ResourceState.PROVISIONED, "_provision_time") + self.debug("----- PROVISIONED ---- ") def set_state(self, state, state_time_attr): """ Set the state of the RM while keeping a trace of the time """ diff --git a/src/nepi/resources/linux/ccn/ccnapplication.py b/src/nepi/resources/linux/ccn/ccnapplication.py index 89c949c5..f79c7cf3 100644 --- a/src/nepi/resources/linux/ccn/ccnapplication.py +++ b/src/nepi/resources/linux/ccn/ccnapplication.py @@ -59,7 +59,6 @@ class LinuxCCNApplication(LinuxApplication): self.do_discover() self.do_provision() - self.debug("----- READY ---- ") self.set_ready() @property diff --git a/src/nepi/resources/linux/ccn/ccncontent.py b/src/nepi/resources/linux/ccn/ccncontent.py index d23ca372..c7ce3bf8 100644 --- a/src/nepi/resources/linux/ccn/ccncontent.py +++ b/src/nepi/resources/linux/ccn/ccncontent.py @@ -96,7 +96,6 @@ class LinuxCCNContent(LinuxApplication): self.do_discover() self.do_provision() - self.debug("----- READY ---- ") self.set_ready() def upload_start_command(self): diff --git a/src/nepi/resources/linux/ccn/ccnd.py b/src/nepi/resources/linux/ccn/ccnd.py index b32937a9..070e2cf1 100644 --- a/src/nepi/resources/linux/ccn/ccnd.py +++ b/src/nepi/resources/linux/ccn/ccnd.py @@ -176,7 +176,6 @@ class LinuxCCND(LinuxApplication): self.do_discover() self.do_provision() - self.debug("----- READY ---- ") self.set_ready() def upload_start_command(self): diff --git a/src/nepi/resources/linux/ccn/ccnr.py b/src/nepi/resources/linux/ccn/ccnr.py index 6b0aa6fc..69a84375 100644 --- a/src/nepi/resources/linux/ccn/ccnr.py +++ b/src/nepi/resources/linux/ccn/ccnr.py @@ -220,7 +220,6 @@ class LinuxCCNR(LinuxApplication): self.do_discover() self.do_provision() - self.debug("----- READY ---- ") self.set_ready() def upload_start_command(self): diff --git a/src/nepi/resources/linux/ccn/fibentry.py b/src/nepi/resources/linux/ccn/fibentry.py index 31272f3b..dca91c24 100644 --- a/src/nepi/resources/linux/ccn/fibentry.py +++ b/src/nepi/resources/linux/ccn/fibentry.py @@ -134,7 +134,6 @@ class LinuxFIBEntry(LinuxApplication): self.do_provision() self.configure() - self.debug("----- READY ---- ") self.set_ready() def upload_start_command(self): diff --git a/src/nepi/resources/linux/ns3/ns3simulator.py b/src/nepi/resources/linux/ns3/ns3simulator.py index 90edbc59..e468005f 100644 --- a/src/nepi/resources/linux/ns3/ns3simulator.py +++ b/src/nepi/resources/linux/ns3/ns3simulator.py @@ -54,7 +54,6 @@ class LinuxNS3Simulator(LinuxApplication, NS3Simulator): # ccnd needs to wait until node is deployed and running self.ec.schedule(reschedule_delay, self.deploy) else: - # TODO: Create socket!! socket_name = self.get("socketName") self._client = LinuxNS3Client(socket_name) @@ -62,6 +61,15 @@ class LinuxNS3Simulator(LinuxApplication, NS3Simulator): #self.do_discover() #self.do_provision() - self.debug("----- READY ---- ") self.set_ready() + def do_start(self): + command = self.get("command") + + self.info("Starting ns-3 simulation") + + self._client.start() + + self.set_started() + + # TODO! DESTROY SOCKET AND SHUTDOWN CLIENT diff --git a/src/nepi/resources/linux/udptunnel.py b/src/nepi/resources/linux/udptunnel.py index 44edad61..ba96788f 100644 --- a/src/nepi/resources/linux/udptunnel.py +++ b/src/nepi/resources/linux/udptunnel.py @@ -198,7 +198,6 @@ class UdpTunnel(LinuxApplication): self.do_discover() self.do_provision() - self.debug("----- READY ---- ") self.set_ready() def do_start(self): diff --git a/src/nepi/resources/ns3/ns3application.py b/src/nepi/resources/ns3/ns3application.py index 6f8ad6bf..b00b47f9 100644 --- a/src/nepi/resources/ns3/ns3application.py +++ b/src/nepi/resources/ns3/ns3application.py @@ -24,12 +24,31 @@ from nepi.resources.ns3.ns3base import NS3Base class NS3BaseApplication(NS3Base): _rtype = "abstract::ns3::Application" + @property + def node(self): + from nepi.resources.ns3.ns3node import NS3BaseNode + nodes = self.get_connected(NS3BaseNode.get_rtype()) + + if not nodes: + msg = "Application not connected to node" + self.error(msg) + raise RuntimeError, msg + + return nodes[0] + + @property + def _rms_to_wait(self): + rms = set() + rms.add(self.node) + return rms + def _connect_object(self): node = self.node - if node and node.uuid not in self.connected: + if node.uuid not in self.connected: self.simulator.invoke(node.uuid, "AddApplication", self.uuid) self._connected.add(node.uuid) + """ def do_start(self): if self.state == ResourceState.READY: self.info("Starting") @@ -50,4 +69,5 @@ class NS3BaseApplication(NS3Base): self.info("Stopping command '%s'" % command) self.simulator.invoke(self.uuid, "Stop") self.set_stopped() + """ diff --git a/src/nepi/resources/ns3/ns3arpl3protocol.py b/src/nepi/resources/ns3/ns3arpl3protocol.py new file mode 100644 index 00000000..b40c5812 --- /dev/null +++ b/src/nepi/resources/ns3/ns3arpl3protocol.py @@ -0,0 +1,44 @@ +# +# NEPI, a framework to manage network experiments +# Copyright (C) 2014 INRIA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Author: Alina Quereilhac + +from nepi.execution.resource import clsinit_copy +from nepi.resources.ns3.ns3base import NS3Base + +@clsinit_copy +class NS3BaseArpL3Protocol(NS3Base): + _rtype = "abstract::ns3::ArpL3Protocol" + + @property + def node(self): + from nepi.resources.ns3.ns3node import NS3BaseNode + nodes = self.get_connected(NS3BaseNode.get_rtype()) + + if not nodes: + msg = "ArpL3Protocol not connected to node" + self.error(msg) + raise RuntimeError, msg + + return nodes[0] + + @property + def _rms_to_wait(self): + rms = set() + rms.add(self.node) + return rms + diff --git a/src/nepi/resources/ns3/ns3base.py b/src/nepi/resources/ns3/ns3base.py index ba035969..7cc077a5 100644 --- a/src/nepi/resources/ns3/ns3base.py +++ b/src/nepi/resources/ns3/ns3base.py @@ -42,11 +42,8 @@ class NS3Base(ResourceManager): @property def simulator(self): - # Ns3 RMs should be connected to the simulator through a ns3 node - node = self.node - if node: return node.simulator - return None - + return self.node.simulator + @property def node(self): from nepi.resources.ns3.ns3node import NS3BaseNode @@ -55,11 +52,18 @@ class NS3Base(ResourceManager): return None @property - def others_to_wait(self): - others = set() + def _rms_to_wait(self): + """ Returns the collection of ns-3 RMs that this RM needs to + wait for before start + + This method should be overriden to wait for other ns-3 + objects to be deployed before proceeding with the deployment + + """ + rms = set() node = self.node - if node: others.add(node) - return others + if node: rms.add(node) + return rms def _instantiate_object(self): if self.uuid: @@ -83,21 +87,16 @@ class NS3Base(ResourceManager): self.simulator.invoke(node.uuid, "AggregateObject", self.uuid) self._connected.add(node.uuid) - def _wait_others(self): - """ Returns the collection of ns-3 RMs that this RM needs to - wait for before start - - This method should be overriden to wait for other ns-3 - objects to be deployed before proceeding with the deployment - - """ - for other in self.others_to_wait: - if other and other.state < ResourceState.READY: + def _wait_rms(self): + """ Returns True if dependent RMs are not yer READY, False otherwise""" + for rm in self._rms_to_wait: + if rm and rm.state < ResourceState.READY: + rm.debug("Not yet READY") return True return False def do_provision(self): - # create run dir for ns3 object + # TODO: create run dir for ns3 object !!!! # self.simulator.node.mkdir(self.run_home) self._instantiate_object() @@ -109,18 +108,14 @@ class NS3Base(ResourceManager): super(NS3Base, self).do_provision() def do_deploy(self): - if not self.simulator or self.simulator.state < ResourceState.READY or \ - self._wait_others(): + if self._wait_rms(): self.debug("---- RESCHEDULING DEPLOY ----" ) - - # ccnd needs to wait until node is deployed and running self.ec.schedule(reschedule_delay, self.deploy) else: - # TODO: CREATE AND CONFIGURE NS-3 C++ OBJECT + self.info("Entering deploy") self.do_discover() self.do_provision() - self.debug("----- READY ---- ") self.set_ready() def do_start(self): diff --git a/src/nepi/resources/ns3/ns3channel.py b/src/nepi/resources/ns3/ns3channel.py index 7386346b..92dc8928 100644 --- a/src/nepi/resources/ns3/ns3channel.py +++ b/src/nepi/resources/ns3/ns3channel.py @@ -24,14 +24,25 @@ from nepi.resources.ns3.ns3base import NS3Base class NS3BaseChannel(NS3Base): _rtype = "abstract::ns3::Channel" + @property + def simulator(self): + return self.devices[0].node.simulator + @property def devices(self): from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice - return self.get_connected(NS3BaseNetDevice.get_rtype()) + devices = self.get_connected(NS3BaseNetDevice.get_rtype()) + + if not devices: + msg = "Channel not connected to devices" + self.error(msg) + raise RuntimeError, msg + + return devices @property - def simulator(self): - devices = self.devices - if devices: return devices[0].node.simulator - return None - + def _rms_to_wait(self): + rms = set() + rms.add(self.simulator) + return rms + diff --git a/src/nepi/resources/ns3/ns3errormodel.py b/src/nepi/resources/ns3/ns3errormodel.py index 656b580a..fa0779da 100644 --- a/src/nepi/resources/ns3/ns3errormodel.py +++ b/src/nepi/resources/ns3/ns3errormodel.py @@ -28,19 +28,23 @@ class NS3BaseErrorModel(NS3Base): def device(self): from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice devices = self.get_connected(NS3BaseNetDevice.get_rtype()) - if devices: return devices[0] - return None + + if not devices: + msg = "ErrorModel not connected to device" + self.error(msg) + raise RuntimeError, msg + + return devices[0] @property - def others_to_wait(self): - others = set() - device = self.device - if device: others.add(device) - return others + def _rms_to_wait(self): + rms = set() + rms.add(self.device) + return rms def _connect_object(self): device = self.device - if device and device.uuid not in self.connected: + if device.uuid not in self.connected: self.simulator.invoke(device.uuid, "SetReceiveErrorModel", self.uuid) self._connected.add(device.uuid) diff --git a/src/nepi/resources/ns3/ns3errorratemodel.py b/src/nepi/resources/ns3/ns3errorratemodel.py index 3de95682..f1b283a4 100644 --- a/src/nepi/resources/ns3/ns3errorratemodel.py +++ b/src/nepi/resources/ns3/ns3errorratemodel.py @@ -19,7 +19,6 @@ from nepi.execution.resource import clsinit_copy from nepi.resources.ns3.ns3base import NS3Base -from nepi.resources.ns3.ns3wifiphy import NS3BaseWifiPhy @clsinit_copy class NS3BaseErrorRateModel(NS3Base): @@ -27,20 +26,25 @@ class NS3BaseErrorRateModel(NS3Base): @property def phy(self): + from nepi.resources.ns3.ns3wifiphy import NS3BaseWifiPhy phys = self.get_connected(NS3BaseWifiPhy.get_rtype()) - if phys: return phys[0] - return None + + if not phys: + msg = "ErrorRateModel not connected to phy" + self.error(msg) + raise RuntimeError, msg + + return phys[0] @property - def others_to_wait(self): - others = set() - phy = self.phy - if phy: others.add(phy) - return others + def _rms_to_wait(self): + rms = set() + rms.add(self.phy) + return rms def _connect_object(self): phy = self.phy - if phy and phy.uuid not in self.connected: + if phy.uuid not in self.connected: self.simulator.invoke(phy.uuid, "SetErrorRateModel", self.uuid) self._connected.add(phy.uuid) diff --git a/src/nepi/resources/ns3/ns3icmpv4l4protocol.py b/src/nepi/resources/ns3/ns3icmpv4l4protocol.py new file mode 100644 index 00000000..94f81281 --- /dev/null +++ b/src/nepi/resources/ns3/ns3icmpv4l4protocol.py @@ -0,0 +1,44 @@ +# +# NEPI, a framework to manage network experiments +# Copyright (C) 2014 INRIA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Author: Alina Quereilhac + +from nepi.execution.resource import clsinit_copy +from nepi.resources.ns3.ns3base import NS3Base + +@clsinit_copy +class NS3BaseIcmpv4L4Protocol(NS3Base): + _rtype = "abstract::ns3::Icmpv4L4Protocol" + + @property + def node(self): + from nepi.resources.ns3.ns3node import NS3BaseNode + nodes = self.get_connected(NS3BaseNode.get_rtype()) + + if not nodes: + msg = "Icmp4L4Protocol not connected to node" + self.error(msg) + raise RuntimeError, msg + + return nodes[0] + + @property + def _rms_to_wait(self): + rms = set() + rms.add(self.node) + return rms + diff --git a/src/nepi/resources/ns3/ns3ipv4l3protocol.py b/src/nepi/resources/ns3/ns3ipv4l3protocol.py index 67fe21dd..f8f3670b 100644 --- a/src/nepi/resources/ns3/ns3ipv4l3protocol.py +++ b/src/nepi/resources/ns3/ns3ipv4l3protocol.py @@ -24,6 +24,24 @@ from nepi.resources.ns3.ns3base import NS3Base class NS3BaseIpv4L3Protocol(NS3Base): _rtype = "abstract::ns3::Ipv4L3Protocol" + @property + def node(self): + from nepi.resources.ns3.ns3node import NS3BaseNode + nodes = self.get_connected(NS3BaseNode.get_rtype()) + + if not nodes: + msg = "Ipv4L3Protocol not connected to node" + self.error(msg) + raise RuntimeError, msg + + return nodes[0] + + @property + def _rms_to_wait(self): + rms = set() + rms.add(self.node) + return rms + def _configure_object(self): simulator = self.simulator diff --git a/src/nepi/resources/ns3/ns3netdevice.py b/src/nepi/resources/ns3/ns3netdevice.py index 009d14cf..66366cbd 100644 --- a/src/nepi/resources/ns3/ns3netdevice.py +++ b/src/nepi/resources/ns3/ns3netdevice.py @@ -42,21 +42,42 @@ class NS3BaseNetDevice(NS3Base): cls._register_attribute(ip) cls._register_attribute(prefix) + @property + def node(self): + from nepi.resources.ns3.ns3node import NS3BaseNode + nodes = self.get_connected(NS3BaseNode.get_rtype()) + + if not nodes: + msg = "Device not connected to node" + self.error(msg) + raise RuntimeError, msg + + return nodes[0] + @property def channel(self): from nepi.resources.ns3.ns3channel import NS3BaseChannel channels = self.get_connected(NS3BaseChannel.get_rtype()) - if channels: return channels[0] - return None + + if not channels: + msg = "Device not connected to channel" + self.error(msg) + raise RuntimeError, msg + + return channels[0] @property - def others_to_wait(self): + def _rms_to_wait(self): others = set() - node = self.node - if node: others.add(node) - channel = self.channel - if channel: others.add(channel) + node = self.node + others.add(node) + + ipv4 = node.ipv4 + if node.ipv4: + others.add(ipv4) + + others.add(self.channel) return others def _configure_object(self): diff --git a/src/nepi/resources/ns3/ns3node.py b/src/nepi/resources/ns3/ns3node.py index 0cecfa7c..62d2a38d 100644 --- a/src/nepi/resources/ns3/ns3node.py +++ b/src/nepi/resources/ns3/ns3node.py @@ -32,8 +32,10 @@ class NS3BaseNode(NS3Base): if isinstance(rm, NS3Simulator): return rm - return None - + msg = "Node not connected to simulator" + self.error(msg) + raise RuntimeError, msg + @property def ipv4(self): from nepi.resources.ns3.ns3ipv4l3protocol import NS3BaseIpv4L3Protocol @@ -42,8 +44,10 @@ class NS3BaseNode(NS3Base): return None @property - def others_to_wait(self): - return set() + def _rms_to_wait(self): + rms = set() + rms.add(self.simulator) + return rms def _configure_object(self): ### node.AggregateObject(PacketSocketFactory()) diff --git a/src/nepi/resources/ns3/ns3propagationdelaymodel.py b/src/nepi/resources/ns3/ns3propagationdelaymodel.py index 58842b70..6c5ee861 100644 --- a/src/nepi/resources/ns3/ns3propagationdelaymodel.py +++ b/src/nepi/resources/ns3/ns3propagationdelaymodel.py @@ -19,7 +19,6 @@ from nepi.execution.resource import clsinit_copy from nepi.resources.ns3.ns3base import NS3Base -from nepi.resources.ns3.ns3channel import NS3BaseChannel @clsinit_copy class NS3BasePropagationDelayModel(NS3Base): @@ -27,26 +26,29 @@ class NS3BasePropagationDelayModel(NS3Base): @property def simulator(self): - channel = self.channel - if channel: return channel.simulator - return None + return self.channel.simulator @property def channel(self): + from nepi.resources.ns3.ns3channel import NS3BaseChannel channels = self.get_connected(NS3BaseChannel.get_rtype()) - if channels: return channels[0] - return None + + if not channels: + msg = "PropagationDelayModel not connected to channel" + self.error(msg) + raise RuntimeError, msg + + return channels[0] @property - def others_to_wait(self): + def _rms_to_wait(self): others = set() - channel = self.channel - if channel: others.add(channel) + others.add(self.channel) return others def _connect_object(self): channel = self.channel - if channel and channel.uuid not in self.connected: + if channel.uuid not in self.connected: self.simulator.invoke(channel.uuid, "SetPropagationDelayModel", self.uuid) self._connected.add(channel.uuid) diff --git a/src/nepi/resources/ns3/ns3propagationlossmodel.py b/src/nepi/resources/ns3/ns3propagationlossmodel.py index 617f8cfd..fdaef388 100644 --- a/src/nepi/resources/ns3/ns3propagationlossmodel.py +++ b/src/nepi/resources/ns3/ns3propagationlossmodel.py @@ -19,7 +19,6 @@ from nepi.execution.resource import clsinit_copy from nepi.resources.ns3.ns3base import NS3Base -from nepi.resources.ns3.ns3channel import NS3BaseChannel @clsinit_copy class NS3BasePropagationLossModel(NS3Base): @@ -27,26 +26,29 @@ class NS3BasePropagationLossModel(NS3Base): @property def simulator(self): - channel = self.channel - if channel: return channel.simulator - return None + return self.channel.simulator @property def channel(self): + from nepi.resources.ns3.ns3channel import NS3BaseChannel channels = self.get_connected(NS3BaseChannel.get_rtype()) - if channels: return channels[0] - return None + + if not channels: + msg = "PropagationLossModel not connected to channel" + self.error(msg) + raise RuntimeError, msg + + return channels[0] @property - def others_to_wait(self): + def _rms_to_wait(self): others = set() - channel = self.channel - if channel: others.add(channel) + others.add(self.channel) return others def _connect_object(self): channel = self.channel - if channel and channel.uuid not in self.connected: + if channel.uuid not in self.connected: self.simulator.invoke(channel.uuid, "SetPropagationLossModel", self.uuid) self._connected.add(channel.uuid) diff --git a/src/nepi/resources/ns3/ns3queue.py b/src/nepi/resources/ns3/ns3queue.py index a02a96e8..9fd8df9f 100644 --- a/src/nepi/resources/ns3/ns3queue.py +++ b/src/nepi/resources/ns3/ns3queue.py @@ -28,25 +28,27 @@ class NS3BaseQueue(NS3Base): def device(self): from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice devices = self.get_connected(NS3BaseNetDevice.get_rtype()) - if devices: return devices[0] - return None + + if not devices: + msg = "Queue not connected to device" + self.error(msg, out, err) + raise RuntimeError, msg + + return devices[0] @property def node(self): - device = self.device - if device: return device.node - return None + return self.device.node @property - def others_to_wait(self): - others = set() - device = self.device - if device: others.add(device) - return others + def _rms_to_wait(self): + rms = set() + rms.add(self.device) + return rms def _connect_object(self): device = self.device - if device and device.uuid not in self.connected: + if device.uuid not in self.connected: self.simulator.invoke(device.uuid, "SetQueue", self.uuid) self._connected.add(device.uuid) diff --git a/src/nepi/resources/ns3/ns3wifimac.py b/src/nepi/resources/ns3/ns3wifimac.py index 6cc4c166..7e1cf8f8 100644 --- a/src/nepi/resources/ns3/ns3wifimac.py +++ b/src/nepi/resources/ns3/ns3wifimac.py @@ -24,23 +24,31 @@ from nepi.resources.ns3.ns3base import NS3Base class NS3BaseWifiMac(NS3Base): _rtype = "abstract::ns3::WifiMac" + @property + def node(self): + return self.device.node + @property def device(self): from nepi.resources.ns3.ns3device import NS3BaseNetDevice devices = self.get_connected(NS3BaseNetDevice.get_rtype()) - if devices: return devices[0] - return None + + if not devices: + msg = "WifiMac not connected to device" + self.error(msg) + raise RuntimeError, msg + + return devices[0] @property - def others_to_wait(self): - others = set() - device = self.device - if device: others.add(device) - return others + def _rms_to_wait(self): + rms = set() + rms.add(self.device) + return rms def _connect_object(self): device = self.device - if device and device.uuid not in self.connected: + if device.uuid not in self.connected: self.simulator.invoke(device.uuid, "SetMac", self.uuid) self._connected.add(device.uuid) diff --git a/src/nepi/resources/ns3/ns3wifiphy.py b/src/nepi/resources/ns3/ns3wifiphy.py index a1f01b74..936eddc8 100644 --- a/src/nepi/resources/ns3/ns3wifiphy.py +++ b/src/nepi/resources/ns3/ns3wifiphy.py @@ -24,28 +24,34 @@ from nepi.resources.ns3.ns3base import NS3Base class NS3BaseWifiPhy(NS3Base): _rtype = "abstract::ns3::WifiPhy" + @property + def node(self): + return self.device.node + @property def device(self): from nepi.resources.ns3.ns3device import NS3BaseNetDevice devices = self.get_connected(NS3BaseNetDevice.get_rtype()) - if devices: return devices[0] - return None + + if not devices: + msg = "WifiPhy not connected to device" + self.error(msg) + raise RuntimeError, msg + + return devices[0] @property - def others_to_wait(self): - others = set() - device = self.device - if device: others.add(device) - return others + def _rms_to_wait(self): + rms = set() + rms.add(self.device) + return rms def _connect_object(self): device = self.device - if device and device.uuid not in self.connected: + if device.uuid not in self.connected: self.simulator.invoke(device.uuid, "SetPhy", self.uuid) self.simulator.invoke(self.uuid, "SetDevice", device.uuid) self._connected.add(device.uuid) - node = device.node - if node: - self.simulator.invoke(self.uuid, "SetMobility", node.uuid) + self.simulator.invoke(self.uuid, "SetMobility", self.node.uuid) diff --git a/src/nepi/resources/ns3/ns3wifiremotestationmanager.py b/src/nepi/resources/ns3/ns3wifiremotestationmanager.py index 480250d1..a5f4548e 100644 --- a/src/nepi/resources/ns3/ns3wifiremotestationmanager.py +++ b/src/nepi/resources/ns3/ns3wifiremotestationmanager.py @@ -25,28 +25,31 @@ from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice class NS3BaseWifiRemoteStationManager(NS3Base): _rtype = "abstract::ns3::WifiRemoteStationManager" + @property + def node(self): + return self.device.node + @property def device(self): + from nepi.resources.ns3.ns3device import NS3BaseNetDevice devices = self.get_connected(NS3BaseNetDevice.get_rtype()) - if devices: return devices[0] - return None - @property - def node(self): - device = self.device - if device: return device.node - return None + if not devices: + msg = "WifiRemoteStationManager not connected to device" + self.error(msg) + raise RuntimeError, msg + + return devices[0] @property - def others_to_wait(self): - others = set() - device = self.device - if device: others.add(device) - return others + def _rms_to_wait(self): + rms = set() + rms.add(self.device) + return rms def _connect_object(self): device = self.device - if device and device.uuid not in self.connected: + if device.uuid not in self.connected: self.simulator.invoke(device.uuid, "SetRemoteStationManager", self.uuid) self._connected.add(device.uuid) diff --git a/src/nepi/resources/ns3/resource_manager_generator.py b/src/nepi/resources/ns3/resource_manager_generator.py index 5cb7cc18..aa3f51b1 100644 --- a/src/nepi/resources/ns3/resource_manager_generator.py +++ b/src/nepi/resources/ns3/resource_manager_generator.py @@ -23,23 +23,32 @@ from nepi.resources.ns3.ns3wrapper import load_ns3_module import os import re +base_types = ["ns3::Node", + "ns3::Application", + "ns3::NetDevice", + "ns3::Channel", + "ns3::Queue", + "ns3::Icmpv4L4Protocol", + "ns3::ArpL3Protocol", + "ns3::Ipv4L3Protocol", + "ns3::PropagationLossModel", + "ns3::PropagationDelayModel", + "ns3::WifiRemoteStationManager", + "ns3::WifiPhy", + "ns3::WifiMac", + "ns3::ErrorModel", + "ns3::ErrorRateModel"] + def discard(ns3, tid): rtype = tid.GetName() - - words = ["variable", "object", "probe", "adaptor", "wrapper", - "container", "derived", "simple"] - for word in words: - if rtype.lower().find(word) > -1: - return True - - bases = ["ns3::Scheduler", "ns3::SimulatorImpl"] type_id = ns3.TypeId() - for base in bases: - tid_base = type_id.LookupByName(base) - if tid.IsChildOf(tid_base): - return True - return False + for type_name in base_types: + tid_base = type_id.LookupByName(type_name) + if type_name == rtype or tid.IsChildOf(tid_base): + return False + + return True def select_base_class(ns3, tid): base_class_import = "from nepi.resources.ns3.ns3base import NS3Base" @@ -47,34 +56,15 @@ def select_base_class(ns3, tid): rtype = tid.GetName() - if rtype == "ns3::Node": - base_class_import = "from nepi.resources.ns3.ns3node import NS3BaseNode" - base_class = "NS3BaseNode" - elif rtype == "ns3::Ipv4L3Protocol": - base_class_import = "from nepi.resources.ns3.ns3ipv4l3protocol import NS3BaseIpv4L3Protocol" - base_class = "NS3BaseIpv4L3Protocol" - else: - type_id = ns3.TypeId() - - bases = ["ns3::Application", - "ns3::NetDevice", - "ns3::Channel", - "ns3::Queue", - "ns3::PropagationLossModel", - "ns3::PropagationDelayModel", - "ns3::WifiRemoteStationManager", - "ns3::WifiPhy", - "ns3::WifiMac", - "ns3::ErrorModel", - "ns3::ErrorRateModel"] - - for base in bases: - tid_base = type_id.LookupByName(base) - if tid.IsChildOf(tid_base): - base_class = "NS3Base" + base.replace("ns3::", "") - base_module = "ns3" + base.replace("ns3::", "").lower() - base_class_import = "from nepi.resources.ns3.%s import %s " % ( - base_module, base_class) + type_id = ns3.TypeId() + + for type_name in base_types: + tid_base = type_id.LookupByName(type_name) + if type_name == rtype or tid.IsChildOf(tid_base): + base_class = "NS3Base" + type_name.replace("ns3::", "") + base_module = "ns3" + type_name.replace("ns3::", "").lower() + base_class_import = "from nepi.resources.ns3.%s import %s " % ( + base_module, base_class) return (base_class_import, base_class) diff --git a/src/nepi/resources/planetlab/tap.py b/src/nepi/resources/planetlab/tap.py index 6cc490ac..ec724a21 100644 --- a/src/nepi/resources/planetlab/tap.py +++ b/src/nepi/resources/planetlab/tap.py @@ -169,7 +169,6 @@ class PlanetlabTap(LinuxApplication): self.do_discover() self.do_provision() - self.debug("----- READY ---- ") self.set_ready() def do_start(self): diff --git a/test/resources/linux/ns3/ns3simulator.py b/test/resources/linux/ns3/ns3simulator.py index 9f17072c..a4a97e0b 100644 --- a/test/resources/linux/ns3/ns3simulator.py +++ b/test/resources/linux/ns3/ns3simulator.py @@ -83,7 +83,7 @@ class LinuxNS3ClientTest(unittest.TestCase): ec.set(p1, "prefix", "30") ec.register_connection(nsnode1, p1) q1 = ec.register_resource("ns3::DropTailQueue") - ec.register_connection(nsnode1, q1) + ec.register_connection(p1, q1) nsnode2 = ec.register_resource("ns3::Node") ec.register_connection(nsnode2, simu) @@ -102,7 +102,7 @@ class LinuxNS3ClientTest(unittest.TestCase): ec.set(p2, "prefix", "30") ec.register_connection(nsnode2, p2) q2 = ec.register_resource("ns3::DropTailQueue") - ec.register_connection(nsnode2, q2) + ec.register_connection(p2, q2) # Create channel chan = ec.register_resource("ns3::PointToPointChannel") @@ -121,7 +121,7 @@ class LinuxNS3ClientTest(unittest.TestCase): ec.deploy() - time.sleep(5) + time.sleep(30) ec.shutdown() -- 2.43.0