def run(self):
bounds_width = bounds_height = 200
x = y = 100
- speed = 1
+ speed = 7
exp_desc = ExperimentDescription()
def trace(self, guid, trace_id, attribute='value'):
raise NotImplementedError
+ def traces_info(self):
+ """ dictionary of dictionaries:
+ traces_info = dict({
+ guid = dict({
+ trace_id = dict({
+ host = host,
+ filepath = filepath,
+ filesize = size in bytes,
+ })
+ })
+ })"""
+ raise NotImplementedError
+
def shutdown(self):
raise NotImplementedError
return testbed.trace(guid, trace_id, attribute)
raise RuntimeError("No element exists with guid %d" % guid)
+ def traces_info(self):
+ traces_info = dict()
+ for guid, testbed in self._testbeds.iteritems():
+ traces_info[guid] = testbed.traces_info()
+ return traces_info
+
@staticmethod
def _parallel(callables):
excs = []
except:
# Just print exceptions, this is just cleanup
import traceback
- traceback.print_exc(file=sys.stderr)
+ ######## BUG ##########
+ #BUG: If the next line is uncomented pyQt explodes when shutting down the experiment !!!!!!!!
+ #traceback.print_exc(file=sys.stderr)
def stop(self):
for testbed in self._testbeds.values():
TESTBED_STATUS_CROSS_CONNECTED, \
TESTBED_STATUS_CONFIGURED, \
TESTBED_STATUS_STARTED, \
- TESTBED_STATUS_STOPPED
+ TESTBED_STATUS_STOPPED,\
+ CONNECTION_DELAY
import collections
+import copy
class TestbedController(execute.TestbedController):
def __init__(self, testbed_id, testbed_version):
self._status = TESTBED_STATUS_CREATED
def _do_connect(self, init = True):
- for guid1, connections in self._connect.iteritems():
- factory1 = self._get_factory(guid1)
- for connector_type_name1, connections2 in connections.iteritems():
- connector_type1 = factory1.connector_type(connector_type_name1)
- for guid2, connector_type_name2 in connections2.iteritems():
- factory_id2 = self._create[guid2]
- # Connections are executed in a "From -> To" direction only
- # This explicitly ignores the "To -> From" (mirror)
- # connections of every connection pair.
- if init:
- connect_code = connector_type1.connect_to_init_code(
- self._testbed_id, factory_id2,
- connector_type_name2,
- False)
- else:
- connect_code = connector_type1.connect_to_compl_code(
- self._testbed_id, factory_id2,
- connector_type_name2,
- False)
- if connect_code:
- connect_code(self, guid1, guid2)
+ unconnected = copy.deepcopy(self._connect)
+
+ while unconnected:
+ for guid1, connections in unconnected.items():
+ factory1 = self._get_factory(guid1)
+ for connector_type_name1, connections2 in connections.items():
+ connector_type1 = factory1.connector_type(connector_type_name1)
+ for guid2, connector_type_name2 in connections2.items():
+ factory_id2 = self._create[guid2]
+ # Connections are executed in a "From -> To" direction only
+ # This explicitly ignores the "To -> From" (mirror)
+ # connections of every connection pair.
+ if init:
+ connect_code = connector_type1.connect_to_init_code(
+ self._testbed_id, factory_id2,
+ connector_type_name2,
+ False)
+ else:
+ connect_code = connector_type1.connect_to_compl_code(
+ self._testbed_id, factory_id2,
+ connector_type_name2,
+ False)
+ delay = None
+ if connect_code:
+ delay = connect_code(self, guid1, guid2)
+
+ if delay is not CONNECTION_DELAY:
+ del unconnected[guid1][connector_type_name1][guid2]
+ if not unconnected[guid1][connector_type_name1]:
+ del unconnected[guid1][connector_type_name1]
+ if not unconnected[guid1]:
+ del unconnected[guid1]
def do_connect_init(self):
self._do_connect()
def trace(self, guid, trace_id, attribute='value'):
if attribute == 'value':
- fd = open("%s" % self.trace_filename(guid, trace_id), "r")
+ fd = open("%s" % self.trace_filepath(guid, trace_id), "r")
content = fd.read()
fd.close()
elif attribute == 'path':
- content = self.trace_filename(guid, trace_id)
+ content = self.trace_filepath(guid, trace_id)
+ elif attribute == 'size':
+ content = str(self.traces_filesize(guid, trace_id))
else:
content = None
return content
- def trace_filename(self, guid, trace_id):
+ def traces_info(self):
+ traces_info = dict()
+ host = self._attributes.get_attribute_value("deployment_host")
+ for guid, trace_list in self._add_trace.iteritems():
+ traces_info[guid] = dict()
+ for trace_id in trace_list:
+ traces_info[guid][trace_id] = dict()
+ filepath = self.trace(guid, trace_id, attribute = "path")
+ # TODO: Filesize!
+ # filesize = self.trace(guid, trace_id)
+ filesize = -1
+ traces_info[guid][trace_id]["host"] = host
+ traces_info[guid][trace_id]["filepath"] = filepath
+ traces_info[guid][trace_id]["filesize"] = str(filesize)
+ return traces_info
+
+ def trace_filepath(self, guid, trace_id):
"""
Return a trace's file path, for TestbedController's default
implementation of trace()
"""
raise NotImplementedError
+ def trace_filesize(self, guid, trace_id):
+ """
+ Return a trace's filesize in bytes
+ """
+ raise NotImplementedError
+
#shutdown: NotImplementedError
def get_connected(self, guid, connector_type_name,
from nepi.core import testbed_impl
from nepi.util.constants import TIME_NOW
import os
+import fcntl
+import threading
class TestbedController(testbed_impl.TestbedController):
from nepi.util.tunchannel_impl import TunChannel
+
+ class HostLock(object):
+ taken = False
+ processcond = threading.Condition()
+
+ def __init__(self, lockfile):
+ processcond = self.__class__.processcond
+
+ processcond.acquire()
+ try:
+ # It's not reentrant
+ while self.__class__.taken:
+ processcond.wait()
+ self.__class__.taken = True
+ finally:
+ processcond.release()
+
+ self.lockfile = lockfile
+ fcntl.flock(self.lockfile, fcntl.LOCK_EX)
+
+ def __del__(self):
+ processcond = self.__class__.processcond
+
+ processcond.acquire()
+ try:
+ assert self.__class__.taken, "HostLock unlocked without being locked!"
+ fcntl.flock(self.lockfile, fcntl.LOCK_UN)
+
+ # It's not reentrant
+ self.__class__.taken = False
+ processcond.notify()
+ finally:
+ processcond.release()
+
def __init__(self, testbed_version):
super(TestbedController, self).__init__(TESTBED_ID, testbed_version)
self._netns = None
self._home_directory = None
self._traces = dict()
+ self._netns_lock = open("/tmp/nepi-netns-lock","a")
+
+ def _lock(self):
+ return self.HostLock(self._netns_lock)
@property
def home_directory(self):
return self._netns
def do_setup(self):
+ lock = self._lock()
+
self._home_directory = self._attributes.\
get_attribute_value("homeDirectory")
+ # create home...
+ home = os.path.normpath(self.home_directory)
+ if not os.path.exists(home):
+ os.makedirs(home, 0755)
+
self._netns = self._load_netns_module()
super(TestbedController, self).do_setup()
+
+ def do_create(self):
+ lock = self._lock()
+ super(TestbedController, self).do_create()
def set(self, guid, name, value, time = TIME_NOW):
super(TestbedController, self).set(guid, name, value, time)
# TODO: take on account schedule time for the task
+ factory_id = self._create[guid]
+ factory = self._factories[factory_id]
+ if factory.box_attributes.is_attribute_design_only(name):
+ return
element = self._elements.get(guid)
if element:
setattr(element, name, value)
raise NotImplementedError
def shutdown(self):
- for trace in self._traces.values():
- trace.close()
+ lock = self._lock()
+
+ for guid, traces in self._traces.iteritems():
+ for trace_id, (trace, filename) in traces.iteritems():
+ if hasattr(trace, "close"):
+ trace.close()
for guid, element in self._elements.iteritems():
if isinstance(element, self.TunChannel):
element.Cleanup()
element.destroy()
self._elements.clear()
- def trace_filename(self, guid, trace_id):
- # TODO: Need to be defined inside a home!!!! with and experiment id_code
- return os.path.join(self.home_directory, "%d_%s" % (guid, trace_id))
+ def trace_filepath(self, guid, trace_id, filename = None):
+ if not filename:
+ (trace, filename) = self._traces[guid][trace_id]
+ return os.path.join(self.home_directory, filename)
- def follow_trace(self, trace_id, trace):
- self._traces[trace_id] = trace
+ def follow_trace(self, guid, trace_id, trace, filename):
+ if not guid in self._traces:
+ self._traces[guid] = dict()
+ self._traces[guid][trace_id] = (trace, filename)
def _load_netns_module(self):
# TODO: Do something with the configuration!!!
NS3_TESTBED_ID = "ns3"
FDNETDEV = "ns3::FileDescriptorNetDevice"
+def _follow_trace(testbed_instance, guid, trace_id, filename):
+ filepath = testbed_instance.trace_filepath(guid, trace_id, filename)
+ trace = open(filepath, "wb")
+ testbed_instance.follow_trace(guid, trace_id, trace, filename)
+ return trace
+
### Connection functions ####
def connect_switch(testbed_instance, switch_guid, interface_guid):
pass
chan.with_pi = with_pi
+### Trace functions ###
+
+def nodepcap_trace(testbed_instance, guid, trace_id):
+ node = testbed_instance._elements[guid]
+ parameters = testbed_instance._get_parameters(guid)
+ filename = "%d-cap.stdout" % guid
+ stdout = _follow_trace(testbed_instance, guid, "pcap_stdout", filename)
+ filename = "%d-pcap.stderr" % guid
+ stderr = _follow_trace(testbed_instance, guid, "pcap_stderr", filename)
+ filename = "%d-node.pcap" % guid
+ filepath = testbed_instance.trace_filepath(guid, trace_id, filename)
+ command = "tcpdump -i 'any' -w %s" % filepath
+ user = "root"
+ trace = node.Popen(command, shell = True, stdout = stdout,
+ stderr = stderr, user = user)
+ testbed_instance.follow_trace(guid, trace_id, trace, filename)
+
+trace_functions = dict({
+ "pcap": nodepcap_trace,
+ })
+
### Creation functions ###
def create_node(testbed_instance, guid):
user = parameters["user"]
stdout = stderr = None
if "stdout" in traces:
- filename = testbed_instance.trace_filename(guid, "stdout")
- stdout = open(filename, "wb")
- testbed_instance.follow_trace("stdout", stdout)
+ filename = "%d-stdout.trace" % guid
+ stdout = _follow_trace(testbed_instance, guid, "stdout", filename)
if "stderr" in traces:
- filename = testbed_instance.trace_filename(guid, "stderr")
- stderr = open(filename, "wb")
- testbed_instance.follow_trace("stderr", stderr)
-
+ filename = "%d-stderr.trace" % guid
+ stderr = _follow_trace(testbed_instance, guid, "stderr", filename)
node_guid = testbed_instance.get_connected(guid, "node", "apps")
if len(node_guid) == 0:
raise RuntimeError("Can't instantiate interface %d outside netns \
stderr = stderr, user = user)
testbed_instance.elements[guid] = element
+def stop_application(testbed_instance, guid):
+ #app = testbed_instance.elements[guid]
+ #app.signal()
+ pass
+
### Status functions ###
def status_application(testbed_instance, guid):
### Configure functions ###
+def configure_traces(testbed_instance, guid):
+ traces = testbed_instance._get_traces(guid)
+ for trace_id in traces:
+ if trace_id not in trace_functions:
+ continue
+ trace_func = trace_functions[trace_id]
+ trace_func(testbed_instance, guid, trace_id)
+
def configure_device(testbed_instance, guid):
+ configure_traces(testbed_instance, guid)
element = testbed_instance._elements[guid]
if not guid in testbed_instance._add_address:
return
element.add_v4_address(address, netprefix)
def configure_node(testbed_instance, guid):
+ configure_traces(testbed_instance, guid)
element = testbed_instance._elements[guid]
if not guid in testbed_instance._add_route:
return
"stderr": dict({
"name": "stderr",
"help": "Application standard error",
+ }),
+ "node_pcap": dict({
+ "name": "pcap",
+ "help": "tcpdump at all node interfaces",
})
})
"create_function": create_node,
"configure_function": configure_node,
"box_attributes": ["forward_X11"],
- "connector_types": ["devs", "apps"]
+ "connector_types": ["devs", "apps"],
+ "traces": ["node_pcap"]
}),
P2PIFACE: dict({
"allow_addresses": True,
"category": "applications",
"create_function": create_application,
"start_function": start_application,
+ "stop_function": stop_application,
"status_function": status_application,
"box_attributes": ["command", "user"],
"connector_types": ["node"],
"name": "Standard",
"validation_function": validation.is_string,
"value": "WIFI_PHY_STANDARD_80211a",
- "flags": Attribute.DesignOnly,
+ "flags": Attribute.DesignOnly | Attribute.HasNoDefaultValue,
"type": Attribute.ENUM,
"allowed": wifi_standards.keys(),
"help": "Wifi PHY standard"
"type": Attribute.ENUM,
"help": "Service flow scheduling type",
}),
+ "WaypointList": dict({
+ "name": "WaypointList",
+ "validation_function": validation.is_string, # TODO: SPECIAL VALIDATION FUNC
+ "value": "",
+ "flags": Attribute.DesignOnly,
+ "type": Attribute.STRING,
+ "help": "Comma separated list of waypoints in format t:x:y:z. Ex: 0s:0:0:0, 1s:1:0:0"
+ }),
})
from constants import TESTBED_ID
import functools
+from nepi.util.constants import CONNECTION_DELAY
from nepi.util.tunchannel_impl import \
crossconnect_tunchannel_peer_init, \
crossconnect_tunchannel_peer_compl
def connect_phy_device(testbed_instance, phy_guid, device_guid):
phy = testbed_instance._elements[phy_guid]
+ if phy.GetErrorRateModel() == None:
+ return CONNECTION_DELAY
device = testbed_instance._elements[device_guid]
device.SetPhy(phy)
phy.SetDevice(device)
"init_code": connect_manager_device,
"can_cross": False
}),
+ dict({
+ "from": ( "ns3", "ns3::AarfcdWifiManager", "dev" ),
+ "to": ( "ns3", "ns3::WifiNetDevice", "manager" ),
+ "init_code": connect_manager_device,
+ "can_cross": False
+ }),
+ dict({
+ "from": ( "ns3", "ns3::AarfWifiManager", "dev" ),
+ "to": ( "ns3", "ns3::WifiNetDevice", "manager" ),
+ "init_code": connect_manager_device,
+ "can_cross": False
+ }),
+ dict({
+ "from": ( "ns3", "ns3::AmrrWifiManager", "dev" ),
+ "to": ( "ns3", "ns3::WifiNetDevice", "manager" ),
+ "init_code": connect_manager_device,
+ "can_cross": False
+ }),
+ dict({
+ "from": ( "ns3", "ns3::CaraWifiManager", "dev" ),
+ "to": ( "ns3", "ns3::WifiNetDevice", "manager" ),
+ "init_code": connect_manager_device,
+ "can_cross": False
+ }),
+ dict({
+ "from": ( "ns3", "ns3::IdealWifiManager", "dev" ),
+ "to": ( "ns3", "ns3::WifiNetDevice", "manager" ),
+ "init_code": connect_manager_device,
+ "can_cross": False
+ }),
+ dict({
+ "from": ( "ns3", "ns3::MinstrelWifiManager", "dev" ),
+ "to": ( "ns3", "ns3::WifiNetDevice", "manager" ),
+ "init_code": connect_manager_device,
+ "can_cross": False
+ }),
+ dict({
+ "from": ( "ns3", "ns3::OnoeWifiManager", "dev" ),
+ "to": ( "ns3", "ns3::WifiNetDevice", "manager" ),
+ "init_code": connect_manager_device,
+ "can_cross": False
+ }),
+ dict({
+ "from": ( "ns3", "ns3::RraaWifiManager", "dev" ),
+ "to": ( "ns3", "ns3::WifiNetDevice", "manager" ),
+ "init_code": connect_manager_device,
+ "can_cross": False
+ }),
dict({
"from": ( "ns3", "ns3::YansWifiPhy", "dev" ),
"to": ( "ns3", "ns3::WifiNetDevice", "phy" ),
"init_code": connect_mac_device,
"can_cross": False
}),
+ dict({
+ "from": ( "ns3", "ns3::NqapWifiMac", "dev" ),
+ "to": ( "ns3", "ns3::WifiNetDevice", "mac" ),
+ "init_code": connect_mac_device,
+ "can_cross": False
+ }),
+ dict({
+ "from": ( "ns3", "ns3::NqstaWifiMac", "dev" ),
+ "to": ( "ns3", "ns3::WifiNetDevice", "mac" ),
+ "init_code": connect_mac_device,
+ "can_cross": False
+ }),
dict({
"from": ( "ns3", "ns3::RateErrorModel", "dev" ),
"to": ( "ns3", "ns3::CsmaNetDevice", "err" ),
"init_code": connect_node_other,
"can_cross": False
}),
+ dict({
+ "from": ( "ns3", "ns3::Node", "mobility" ),
+ "to": ( "ns3", "ns3::WaypointMobilityModel", "node" ),
+ "init_code": connect_node_other,
+ "can_cross": False
+ }),
dict({
"from": ( "ns3", "ns3::SubscriberStationNetDevice", "sflows" ),
"to": ( "ns3", "ns3::ServiceFlow", "dev" ),
self._condition = threading.Condition()
self._simulator_thread = threading.Thread(target = self._simulator_run,
args = [self._condition])
- self._simulator_thread.setDaemon(True)
self._simulator_thread.start()
def stop(self, time = TIME_NOW):
super(TestbedController, self).stop(time)
- # BUG!!!! RealtimeSimulatorImpl never stops simulation with Stop()!!!
- self.ns3.Simulator.Stop()
- #self._stop_simulation(time)
+ #self.ns3.Simulator.Stop()
+ self._stop_simulation(time)
def set(self, guid, name, value, time = TIME_NOW):
super(TestbedController, self).set(guid, name, value, time)
def action(self, time, guid, action):
raise NotImplementedError
- def trace_filename(self, guid, trace_id):
- # TODO: Need to be defined inside a home!!!! with and experiment id_code
+ def trace_filepath(self, guid, trace_id):
filename = self._traces[guid][trace_id]
return os.path.join(self.home_directory, filename)
def follow_trace(self, guid, trace_id, filename):
- if guid not in self._traces:
+ if not guid in self._traces:
self._traces[guid] = dict()
self._traces[guid][trace_id] = filename
element.Cleanup()
self._elements.clear()
if self.ns3:
- self.ns3.Simulator.Stop()
- ##################################################
- # BUG!!!! RealtimeSimulatorImpl never stops simulation with Stop()!!!
- # self._stop_simulation("0s")
- # if self._simulator_thread:
- # print "Joining thread"
- # self._simulator_thread.join()
- #################################################
+ #self.ns3.Simulator.Stop()
+ self._stop_simulation("0s")
+ if self._simulator_thread:
+ self._simulator_thread.join()
self.ns3.Simulator.Destroy()
self._ns3 = None
sys.stdout.flush()
from nepi.util.tunchannel_impl import \
preconfigure_tunchannel, postconfigure_tunchannel, \
wait_tunchannel, create_tunchannel
+import re
wifi_standards = dict({
"WIFI_PHY_STANDARD_holland": 5,
interface_number += 1
return interface_number
+def _follow_trace(testbed_instance, guid, trace_id, filename):
+ testbed_instance.follow_trace(guid, trace_id, filename)
+ filepath = testbed_instance.trace_filepath(guid, trace_id)
+ return filepath
+
### create traces functions ###
def p2pascii_trace(testbed_instance, guid, trace_id):
interface_number = _get_dev_number(testbed_instance, guid)
element = testbed_instance._elements[guid]
filename = "trace-p2p-node-%d-dev-%d.tr" % (node_guid, interface_number)
- testbed_instance.follow_trace(guid, trace_id, filename)
- filepath = testbed_instance.trace_filename(guid, trace_id)
+ filepath = _follow_trace(testbed_instance, guid, trace_id, filename)
helper = testbed_instance.ns3.PointToPointHelper()
asciiHelper = testbed_instance.ns3.AsciiTraceHelper()
- stream = asciiHelper.CreateFileStream (filepath)
+ stream = asciiHelper.CreateFileStream(filepath)
helper.EnableAscii(stream, element)
def p2ppcap_trace(testbed_instance, guid, trace_id):
interface_number = _get_dev_number(testbed_instance, guid)
element = testbed_instance._elements[guid]
filename = "trace-p2p-node-%d-dev-%d.pcap" % (node_guid, interface_number)
- testbed_instance.follow_trace(guid, trace_id, filename)
- filepath = testbed_instance.trace_filename(guid, trace_id)
+ filepath = _follow_trace(testbed_instance, guid, trace_id, filename)
helper = testbed_instance.ns3.PointToPointHelper()
helper.EnablePcap(filepath, element, explicitFilename = True)
interface_number = _get_dev_number(testbed_instance, guid)
element = testbed_instance._elements[guid]
filename = "trace-csma-node-%d-dev-%d.pcap" % (node_guid, interface_number)
- testbed_instance.follow_trace(guid, trace_id, filename)
- filepath = testbed_instance.trace_filename(guid, trace_id)
+ filepath = _follow_trace(testbed_instance, guid, trace_id, filename)
helper = testbed_instance.ns3.CsmaHelper()
helper.EnablePcap(filepath, element, promiscuous = promisc,
explicitFilename = True)
interface_number = _get_dev_number(testbed_instance, guid)
element = testbed_instance._elements[guid]
filename = "trace-fd-node-%d-dev-%d.pcap" % (node_guid, interface_number)
- testbed_instance.follow_trace(guid, trace_id, filename)
- filepath = testbed_instance.trace_filename(guid, trace_id)
+ filepath = _follow_trace(testbed_instance, guid, trace_id, filename)
helper = testbed_instance.ns3.FileDescriptorHelper()
helper.EnablePcap(filepath, element, explicitFilename = True)
interface_number = _get_dev_number(testbed_instance, dev_guid)
element = testbed_instance._elements[dev_guid]
filename = "trace-yanswifi-node-%d-dev-%d.pcap" % (node_guid, interface_number)
- testbed_instance.follow_trace(guid, trace_id, filename)
- filepath = testbed_instance.trace_filename(guid, trace_id)
+ filepath = _follow_trace(testbed_instance, guid, trace_id, filename)
helper = testbed_instance.ns3.YansWifiPhyHelper()
helper.EnablePcap(filepath, element, explicitFilename = True)
interface_number = _get_dev_number(testbed_instance, guid)
element = testbed_instance._elements[guid]
filename = "trace-wimax-node-%d-dev-%d.tr" % (node_guid, interface_number)
- testbed_instance.follow_trace(guid, trace_id, filename)
- filepath = testbed_instance.trace_filename(guid, trace_id)
+ filepath = _follow_trace(testbed_instance, guid, trace_id, filename)
helper = testbed_instance.ns3.WimaxHelper()
asciiHelper = testbed_instance.ns3.AsciiTraceHelper()
stream = asciiHelper.CreateFileStream (filepath)
interface_number = _get_dev_number(testbed_instance, guid)
element = testbed_instance._elements[guid]
filename = "trace-wimax-node-%d-dev-%d.pcap" % (node_guid, interface_number)
- testbed_instance.follow_trace(guid, trace_id, filename)
- filepath = testbed_instance.trace_filename(guid, trace_id)
+ filepath = _follow_trace(testbed_instance, guid, trace_id, filename)
helper = testbed_instance.ns3.WimaxHelper()
helper.EnablePcap(filepath, element, explicitFilename = True)
helper = testbed_instance.ns3.PlotHelper()
prefix = "trace-app-%d" % (guid, )
filename = helper.GetFilenameFromSource(prefix, element, trace_id)
- testbed_instance.follow_trace(guid, trace_id, filename)
- filepath = testbed_instance.trace_filename(guid, trace_id)
+ filepath = _follow_trace(testbed_instance, guid, trace_id, filename)
prefix = filepath[:filepath.find(prefix)+len(prefix)]
helper.EnableTrace(element, trace_id, prefix, "T")
-
trace_functions = dict({
"P2PPcapTrace": p2ppcap_trace,
"P2PAsciiTrace": p2pascii_trace,
create_element(testbed_instance, guid)
element = testbed_instance._elements[guid]
parameters = testbed_instance._get_parameters(guid)
- if "Standard" in parameters:
- standard = parameters["Standard"]
- if standard:
- element.ConfigureStandard(wifi_standards[standard])
+ standard = parameters.get("Standard")
+ if not standard:
+ raise RuntimeError("No wifi standard set for %d" % guid)
+ element.ConfigureStandard(wifi_standards[standard])
+
+def create_waypoint_mobility(testbed_instance, guid):
+ create_element(testbed_instance, guid)
+ element = testbed_instance._elements[guid]
+ parameters = testbed_instance._get_parameters(guid)
+ ns3 = testbed_instance.ns3
+ waypoints = parameters.get("WaypointList", "")
+ waypoints = re.sub(" |\(|\)", "", waypoints)
+ for swp in waypoints.split(","):
+ dwp = swp.split(":")
+ t = str(dwp[0])
+ time = ns3.Time(t)
+ pos = ns3.Vector(float(dwp[1]), float(dwp[2]), float(dwp[3]))
+ waypoint = ns3.Waypoint(time, pos)
+ element.AddWaypoint(waypoint)
def create_ipv4protocol(testbed_instance, guid):
create_element(testbed_instance, guid)
def create_service_flow(testbed_instance, guid):
parameters = testbed_instance._get_parameters(guid)
- direction = None
- if "Direction" in parameters:
- direction = parameters["Direction"]
+ direction = parameters.get("Direction")
if direction == None:
raise RuntimeError("No SchedulingType was found for service flow %d" % guid)
- sched = None
- if "SchedulingType" in parameters:
- sched = parameters["SchedulingType"]
+ sched = parameters.get("SchedulingType")
if sched == None:
raise RuntimeError("No SchedulingType was found for service flow %d" % guid)
ServiceFlow = testbed_instance.ns3.ServiceFlow
def create_ipcs_classifier_record(testbed_instance, guid):
parameters = testbed_instance._get_parameters(guid)
- src_address = None
- if "SrcAddress" in parameters:
- src_address = parameters["SrcAddress"]
+ src_address = parameters.get("SrcAddress")
if src_address == None:
raise RuntimeError("No SrcAddress was found for classifier %d" % guid)
src_address = testbed_instance.ns3.Ipv4Address(src_address)
- src_mask= None
- if "SrcMask" in parameters:
- src_mask = parameters["SrcMask"]
+ src_mask = parameters.get("SrcMask")
if src_mask == None:
raise RuntimeError("No SrcMask was found for classifier %d" % guid)
src_mask = testbed_instance.ns3.Ipv4Mask(src_mask)
- dst_address = None
- if "DstAddress" in parameters:
- dst_address = parameters["DstAddress"]
+ dst_address = parameters.get("DstAddress")
if dst_address == None:
raise RuntimeError("No Dstddress was found for classifier %d" % guid)
dst_address = testbed_instance.ns3.Ipv4Address(dst_address)
- dst_mask= None
- if "DstMask" in parameters:
- dst_mask = parameters["DstMask"]
+ dst_mask = parameters.get("DstMask")
if dst_mask == None:
raise RuntimeError("No DstMask was found for classifier %d" % guid)
dst_mask = testbed_instance.ns3.Ipv4Mask(dst_mask)
- src_port_low = None
- if "SrcPortLow" in parameters:
- src_port_low = parameters["SrcPortLow"]
+ src_port_low = parameters.get("SrcPortLow")
if src_port_low == None:
raise RuntimeError("No SrcPortLow was found for classifier %d" % guid)
- src_port_high= None
- if "SrcPortHigh" in parameters:
- src_port_high = parameters["SrcPortHigh"]
+ src_port_high = parameters.get("SrcPortHigh")
if src_port_high == None:
raise RuntimeError("No SrcPortHigh was found for classifier %d" % guid)
- dst_port_low = None
- if "DstPortLow" in parameters:
- dst_port_low = parameters["DstPortLow"]
+ dst_port_low = parameters.get("DstPortLow")
if dst_port_low == None:
raise RuntimeError("No DstPortLow was found for classifier %d" % guid)
- dst_port_high = None
- if "DstPortHigh" in parameters:
- dst_port_high = parameters["DstPortHigh"]
+ dst_port_high = parameters.get("DstPortHigh")
if dst_port_high == None:
raise RuntimeError("No DstPortHigh was found for classifier %d" % guid)
- protocol = None
- if "Protocol" in parameters:
- protocol = parameters["Protocol"]
+ protocol = parameters.get("Protocol")
if protocol == None or protocol not in l4_protocols:
raise RuntimeError("No Protocol was found for classifier %d" % guid)
- priority = None
- if "Priority" in parameters:
- priority = parameters["Priority"]
+ priority = parameters.get("Priority")
if priority == None:
raise RuntimeError("No Priority was found for classifier %d" % guid)
element = testbed_instance.ns3.IpcsClassifierRecord(src_address, src_mask,
return STATUS_NOT_STARTED
app = testbed_instance.elements[guid]
parameters = testbed_instance._get_parameters(guid)
- if "StartTime" in parameters and parameters["StartTime"]:
- start_value = parameters["StartTime"]
+ start_value = parameters.get("StartTime")
+ if start_value != None:
start_time = testbed_instance.ns3.Time(start_value)
if now.Compare(start_time) < 0:
return STATUS_NOT_STARTED
- if "StopTime" in parameters and parameters["StopTime"]:
- stop_value = parameters["StopTime"]
+ stop_value = parameters.get("StopTime")
+ if stop_value != None:
stop_time = testbed_instance.ns3.Time(stop_value)
if now.Compare(stop_time) < 0:
return STATUS_RUNNING
element = testbed_instance._elements[guid]
parameters = testbed_instance._get_parameters(guid)
- if "macAddress" in parameters:
- address = parameters["macAddress"]
+ address = parameters.get("macAddress")
+ if address:
macaddr = testbed_instance.ns3.Mac48Address(address)
else:
macaddr = testbed_instance.ns3.Mac48Address.Allocate()
"tags": [tags.MOBILE],
}),
"ns3::Node": dict({
- "category": "Topology",
+ "category": "Node",
"create_function": create_node,
"configure_function": configure_node,
"help": "",
"create_function": create_element,
"configure_function": configure_element,
"help": "",
- "connector_types": [],
+ "connector_types": ["dev"],
"box_attributes": ["SuccessK",
"TimerK",
"MaxSuccessThreshold",
}),
"ns3::WaypointMobilityModel": dict({
"category": "Mobility",
- "create_function": create_element,
+ "create_function": create_waypoint_mobility,
"configure_function": configure_element,
- "help": "",
- "connector_types": [],
+ "help": "Waypoint-based mobility model.",
+ "connector_types": ["node"],
"box_attributes": ["WaypointsLeft",
"Position",
- "Velocity"],
+ "Velocity",
+ "WaypointList"],
"tags": [tags.MOBILE],
}),
"ns3::FileDescriptorNetDevice": dict({
}),
"ns3::NqstaWifiMac": dict({
"category": "Mac",
- "create_function": create_element,
+ "create_function": create_wifi_standard_model,
"configure_function": configure_element,
"help": "",
- "connector_types": [],
+ "connector_types": ["dev"],
"box_attributes": ["ProbeRequestTimeout",
"AssocRequestTimeout",
"MaxMissedBeacons",
"create_function": create_element,
"configure_function": configure_element,
"help": "",
- "connector_types": [],
+ "connector_types": ["dev"],
"box_attributes": ["ProbeThreshold",
"FailureThreshold",
"SuccessThreshold",
}),
"ns3::NqapWifiMac": dict({
"category": "Mac",
- "create_function": create_element,
+ "create_function": create_wifi_standard_model,
"configure_function": configure_element,
"help": "",
- "connector_types": [],
+ "connector_types": ["dev"],
"box_attributes": ["BeaconInterval",
"BeaconGeneration",
"CtsTimeout",
"create_function": create_element,
"configure_function": configure_element,
"help": "",
- "connector_types": [],
+ "connector_types": ["dev"],
"box_attributes": ["SuccessK",
"TimerK",
"MaxSuccessThreshold",
"box_attributes": ["DefaultLoss"],
}),
"ns3::WifiNetDevice": dict({
- "category": "Wifi",
+ "category": "Device",
"create_function": create_element,
"configure_function": configure_device,
"help": "",
"box_attributes": ["Mtu"],
}),
"ns3::CsmaChannel": dict({
- "category": "Topology",
+ "category": "Channel",
"create_function": create_element,
"configure_function": configure_element,
"help": "",
"EnableBeaconCollisionAvoidance"],
}),
"ns3::MeshPointDevice": dict({
- "category": "Topology",
+ "category": "Device",
"create_function": create_element,
"configure_function": configure_element,
"help": "",
"create_function": create_element,
"configure_function": configure_element,
"help": "",
- "connector_types": [],
+ "connector_types": ["dev"],
"box_attributes": ["BerThreshold",
"IsLowLatency",
"MaxSsrc",
"create_function": create_element,
"configure_function": configure_element,
"help": "",
- "connector_types": [],
+ "connector_types": ["dev"],
"box_attributes": ["Basic",
"Timeout",
"ewndFor54mbps",
"create_function": create_element,
"configure_function": configure_element,
"help": "",
- "connector_types": [],
+ "connector_types": ["dev"],
"box_attributes": ["UpdateStatistics",
"LookAroundRate",
"EWMA",
"create_function": create_element,
"configure_function": configure_element,
"help": "",
- "connector_types": [],
+ "connector_types": ["dev"],
"box_attributes": ["UpdatePeriod",
"RaiseThreshold",
"AddCreditThreshold",
"create_function": create_element,
"configure_function": configure_element,
"help": "",
- "connector_types": [],
+ "connector_types": ["dev"],
"box_attributes": ["UpdatePeriod",
"FailureRatio",
"SuccessRatio",
content = None
elif attribute == 'path':
content = app.remote_trace_path(trace_id)
+ elif attribute == 'size':
+ # TODO
+ raise NotImplementedError
else:
content = None
return content
TIME_NOW = "0s"
+CONNECTION_DELAY = 0
ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP = "_nepi_testbed_environment_setup"
exp_tag.appendChild(testbeds_tag)
elements_tags = dict()
- for guid in data.guids:
+ for guid in sorted(data.guids):
if data.is_testbed_data(guid):
elements_tag = self.testbed_data_to_xml(doc, testbeds_tag, guid, data)
elements_tags[guid] = elements_tag
def from_data(self, experiment_description, data):
box_guids = list()
- for guid in data.guids:
+ for guid in sorted(data.guids):
if data.is_testbed_data(guid):
self.testbed_from_data(experiment_description, guid, data)
else:
GET_FACTORY_ID = 38
GET_TESTBED_ID = 39
GET_TESTBED_VERSION = 40
+TRACES_INFO = 41
instruction_text = dict({
OK: "OK",
GUIDS: "GUIDS",
TESTBED_ID: "TESTBED_ID",
TESTBED_VERSION: "TESTBED_VERSION",
+ TRACES_INFO: "TRACES_INFO",
})
def log_msg(server, params):
def __init__(self, path):
self.path = path
-def create_controller(xml, access_config = None):
+def create_experiment_controller(xml, access_config = None):
mode = None if not access_config \
else access_config.get_attribute_value(DC.DEPLOYMENT_MODE)
launch = True if not access_config \
def trace(self, guid, trace_id, attribute):
return self._testbed.trace(guid, trace_id, attribute)
+ @Marshalling.handles(TRACES_INFO)
+ @Marshalling.args()
+ @Marshalling.retval( Marshalling.pickled_data )
+ def traces_info(self):
+ return self._testbed.traces_info()
+
@Marshalling.handles(START)
@Marshalling.args()
@Marshalling.retvoid
def __init__(self, root_dir, log_level, experiment_xml):
super(ExperimentControllerServer, self).__init__(root_dir, log_level)
self._experiment_xml = experiment_xml
- self._controller = None
+ self._experiment = None
def post_daemonize(self):
from nepi.core.execute import ExperimentController
- self._controller = ExperimentController(self._experiment_xml,
+ self._experiment = ExperimentController(self._experiment_xml,
root_dir = self._root_dir)
@Marshalling.handles(GUIDS)
@Marshalling.args()
@Marshalling.retval( Marshalling.pickled_data )
def guids(self):
- return self._controller.guids
+ return self._experiment.guids
@Marshalling.handles(XML)
@Marshalling.args()
@Marshalling.retval()
def experiment_xml(self):
- return self._controller.experiment_xml
+ return self._experiment.experiment_xml
@Marshalling.handles(TRACE)
@Marshalling.args(int, str, Marshalling.base64_data)
@Marshalling.retval()
def trace(self, guid, trace_id, attribute):
- return str(self._controller.trace(guid, trace_id, attribute))
+ return str(self._experiment.trace(guid, trace_id, attribute))
+
+ @Marshalling.handles(TRACES_INFO)
+ @Marshalling.args()
+ @Marshalling.retval( Marshalling.pickled_data )
+ def traces_info(self):
+ return self._experiment.traces_info()
@Marshalling.handles(FINISHED)
@Marshalling.args(int)
@Marshalling.retval(Marshalling.bool)
def is_finished(self, guid):
- return self._controller.is_finished(guid)
+ return self._experiment.is_finished(guid)
@Marshalling.handles(GET)
@Marshalling.args(int, Marshalling.base64_data, str)
@Marshalling.retval( Marshalling.pickled_data )
def get(self, guid, name, time):
- return self._controller.get(guid, name, time)
+ return self._experiment.get(guid, name, time)
@Marshalling.handles(SET)
@Marshalling.args(int, Marshalling.base64_data, Marshalling.pickled_data, str)
@Marshalling.retvoid
def set(self, guid, name, value, time):
- self._controller.set(guid, name, value, time)
+ self._experiment.set(guid, name, value, time)
@Marshalling.handles(START)
@Marshalling.args()
@Marshalling.retvoid
def start(self):
- self._controller.start()
+ self._experiment.start()
@Marshalling.handles(STOP)
@Marshalling.args()
@Marshalling.retvoid
def stop(self):
- self._controller.stop()
+ self._experiment.stop()
@Marshalling.handles(RECOVER)
@Marshalling.args()
@Marshalling.retvoid
def recover(self):
- self._controller.recover()
+ self._experiment.recover()
@Marshalling.handles(SHUTDOWN)
@Marshalling.args()
@Marshalling.retvoid
def shutdown(self):
- self._controller.shutdown()
+ self._experiment.shutdown()
@Marshalling.handles(GET_TESTBED_ID)
@Marshalling.args(int)
@Marshalling.retval()
def get_testbed_id(self, guid):
- return self._controller.get_testbed_id(guid)
+ return self._experiment.get_testbed_id(guid)
@Marshalling.handles(GET_FACTORY_ID)
@Marshalling.args(int)
@Marshalling.retval()
def get_factory_id(self, guid):
- return self._controller.get_factory_id(guid)
+ return self._experiment.get_factory_id(guid)
@Marshalling.handles(GET_TESTBED_VERSION)
@Marshalling.args(int)
@Marshalling.retval()
def get_testbed_version(self, guid):
- return self._controller.get_testbed_version(guid)
+ return self._experiment.get_testbed_version(guid)
class BaseProxy(object):
_ServerClass = None
--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
"""
-
self.assertTrue(app_result.startswith(comp_result))
+ traces_info = instance.traces_info()
+ expected_traces_info = dict({
+ 7 : dict({
+ 'fake': dict({
+ 'host': 'localhost',
+ 'filesize': '-1',
+ 'filepath': '<test>'
+ })
+ })
+ })
+ self.assertEquals(traces_info, expected_traces_info)
+
instance.stop()
instance.shutdown()
self.make_cross_test_experiment()
xml = exp_desc.to_xml()
access_config = None
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
controller.start()
cross1 = controller.get(iface12.guid, "cross")
exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
xml = exp_desc.to_xml()
access_config = None
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
controller.start()
while not controller.is_finished(app.guid):
access_config = proxy.AccessConfiguration()
access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
controller.start()
while not controller.is_finished(app.guid):
xml = exp_desc.to_xml()
- controller = proxy.create_controller(xml, access_config = None)
+ controller = proxy.create_experiment_controller(xml, access_config = None)
controller.start()
while not controller.is_finished(app.guid):
access_config = proxy.AccessConfiguration()
access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
controller.start()
while not controller.is_finished(app.guid):
self.assertEquals(controller.get_testbed_version(node1.guid), "01")
self.assertEquals(controller.get_factory_id(node1.guid), "Node")
+ traces_info = controller.traces_info()
+ expected_traces_info = dict({
+ 1: dict({ # testbed guid
+ 6: dict({ # element guid
+ 'fake': dict({ # trace_id
+ 'host': 'localhost',
+ 'filesize': '-1',
+ 'filepath': '<test>'
+ })
+ })
+ })
+ })
+ self.assertEquals(traces_info, expected_traces_info)
+
controller.stop()
controller.shutdown()
access_config = proxy.AccessConfiguration()
access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
controller.start()
while not controller.is_finished(app.guid):
# recover
access_config.set_attribute_value(DC.RECOVER,True)
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
# test recovery
self.assertTrue(controller.is_finished(app.guid))
xml = exp_desc.to_xml()
access_config = None
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
controller.start()
while not controller.is_finished(app.guid):
time.sleep(0.5)
xml = exp_desc.to_xml()
access_config = None
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
controller.start()
while not controller.is_finished(app.guid):
time.sleep(0.5)
access_config.set_attribute_value(DC.DEPLOYMENT_COMMUNICATION, DC.ACCESS_SSH)
access_config.set_attribute_value(DC.DEPLOYMENT_PORT, env.port)
access_config.set_attribute_value(DC.USE_AGENT, True)
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
controller.start()
while not controller.is_finished(app.guid):
self.assertTrue(ping_result.startswith(comp_result))
instance.stop()
instance.shutdown()
-
+
+ @test_util.skipUnless(os.getuid() == 0, "Test requires root privileges")
+ def test_node_pcap_trace(self):
+ user = getpass.getuser()
+ testbed_version = "01"
+ instance = netns.TestbedController(testbed_version)
+ instance.defer_configure("homeDirectory", self.root_dir)
+ instance.defer_create(2, "Node")
+ instance.defer_add_trace(2, "pcap")
+ instance.defer_create(3, "Node")
+ instance.defer_create(4, "P2PNodeInterface")
+ instance.defer_create_set(4, "up", True)
+ instance.defer_connect(2, "devs", 4, "node")
+ instance.defer_add_address(4, "10.0.0.1", 24, None)
+ instance.defer_create(5, "P2PNodeInterface")
+ instance.defer_create_set(5, "up", True)
+ instance.defer_connect(3, "devs", 5, "node")
+ instance.defer_add_address(5, "10.0.0.2", 24, None)
+ instance.defer_connect(4, "p2p", 5, "p2p")
+ instance.defer_create(6, "Application")
+ instance.defer_add_trace(6, "stdout")
+ instance.defer_create_set(6, "command", "ping -qc5 10.0.0.2")
+ instance.defer_create_set(6, "user", user)
+ instance.defer_connect(6, "node", 2, "apps")
+
+ instance.do_setup()
+ instance.do_create()
+ instance.do_connect_init()
+ instance.do_connect_compl()
+ instance.do_preconfigure()
+ instance.do_configure()
+ instance.do_prestart()
+ instance.start()
+ while instance.status(6) != STATUS_FINISHED:
+ time.sleep(0.5)
+ pcap_result = instance.trace(2, "pcap")
+ self.assertEquals(len(pcap_result), 1024)
+ instance.stop()
+ instance.shutdown()
+
def tearDown(self):
try:
shutil.rmtree(self.root_dir)
access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
access_config.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
controller.start()
while not controller.is_finished(app.guid):
access_config.set_attribute_value(DC.DEPLOYMENT_COMMUNICATION, DC.ACCESS_SSH)
access_config.set_attribute_value(DC.DEPLOYMENT_PORT, env.port)
access_config.set_attribute_value(DC.USE_AGENT, True)
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
controller.start()
while not controller.is_finished(app.guid):
access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
access_config.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
- controller = proxy.create_controller(xml, access_config)
+ controller = proxy.create_experiment_controller(xml, access_config)
controller.start()
while not controller.is_finished(app.guid):