def stop(self):
raise NotImplementedError
- def set(self, time, guid, name, value):
+ def set(self, guid, name, value, time = TIME_NOW):
raise NotImplementedError
- def get(self, time, guid, name):
+ def get(self, guid, name, time = TIME_NOW):
raise NotImplementedError
def get_route(self, guid, index, attribute):
return testbed.status(guid) == STATUS_FINISHED
raise RuntimeError("No element exists with guid %d" % guid)
+ def set(self, testbed_guid, guid, name, value, time = TIME_NOW):
+ testbed = self._testbeds[testbed_guid]
+ testbed.set(guid, name, value, time)
+
+ def get(self, testbed_guid, guid, name, time = TIME_NOW):
+ testbed = self._testbeds[testbed_guid]
+ return testbed.get(guid, name, time)
+
def shutdown(self):
for testbed in self._testbeds.values():
testbed.shutdown()
testbed.trace(guid, index, name),
'' :
lambda testbed, guid, index, name:
- testbed.get(TIME_NOW, guid, name),
+ testbed.get(guid, name),
}
for (testbed_guid, guid), attrs in self._netrefs.iteritems():
testbed = self._testbeds[testbed_guid]
for name in attrs:
- value = testbed.get(TIME_NOW, guid, name)
+ value = testbed.get(guid, name)
if isinstance(value, basestring):
match = ATTRIBUTE_PATTERN_BASE.search(value)
if match:
ref_value = COMPONENT_GETTERS[component](
ref_testbed, ref_guid, component_index, attribute)
if ref_value:
- testbed.set(TIME_NOW, guid, name,
- value.replace(match.group(), ref_value))
+ testbed.set(guid, name,
+ value.replace(match.group(), ref_value))
break
else:
# couldn't find value
cross_testbed = self._testbeds[cross_testbed_guid]
cross_testbed_id = cross_testbed.testbed_id
testbed.defer_cross_connect(guid, connector_type_name, cross_guid,
- cross_testbed_id, cross_factory_id,
+ cross_testbed_guid, cross_testbed_id, cross_factory_id,
cross_connector_type_name)
# save cross data for later
self._add_crossdata(testbed_guid, guid, cross_testbed_guid,
if testbed_guid not in self._cross_data:
self._cross_data[testbed_guid] = dict()
if cross_testbed_guid not in self._cross_data[testbed_guid]:
- self._cross_data[testbed_guid][cross_testbed_guid] = list()
- if cross_testbed_guid not in self._cross_data:
- self._cross_data[cross_testbed_guid] = dict()
- if testbed_guid not in self._cross_data[cross_testbed_guid]:
- self._cross_data[cross_testbed_guid][testbed_guid] = list()
- self._cross_data[testbed_guid][cross_testbed_guid].append(cross_guid)
- self._cross_data[cross_testbed_guid][testbed_guid].append(guid)
+ self._cross_data[testbed_guid][cross_testbed_guid] = set()
+ self._cross_data[testbed_guid][cross_testbed_guid].add(cross_guid)
def _get_cross_data(self, testbed_guid):
cross_data = dict()
cross_data[cross_testbed_guid][cross_guid] = elem_cross_data
attributes_list = cross_testbed.get_attribute_list(cross_guid)
for attr_name in attributes_list:
- attr_value = cross_testbed.get(TIME_NOW, cross_guid,
- attr_name)
+ attr_value = cross_testbed.get(cross_guid, attr_name)
elem_cross_data[attr_name] = attr_value
- return elem_cross_data
+ return cross_data
connector_type_name1
def defer_cross_connect(self, guid, connector_type_name, cross_guid,
- cross_testbed_id, cross_factory_id, cross_connector_type_name):
+ cross_testbed_guid, cross_testbed_id, cross_factory_id,
+ cross_connector_type_name):
factory = self._get_factory(guid)
count = self._get_connection_count(guid, connector_type_name)
connector_type = factory.connector_type(connector_type_name)
if not connector_type_name in self._cross_connect[guid]:
self._cross_connect[guid][connector_type_name] = dict()
self._cross_connect[guid][connector_type_name] = \
- (cross_guid, cross_testbed_id, cross_factory_id,
- cross_connector_type_name)
+ (cross_guid, cross_testbed_guid, cross_testbed_id,
+ cross_factory_id, cross_connector_type_name)
def defer_add_trace(self, guid, trace_id):
if not guid in self._create:
factory.create_function(self, guid)
parameters = self._get_parameters(guid)
for name, value in parameters.iteritems():
- self.set(TIME_NOW, guid, name, value)
+ self.set(guid, name, value)
self._status = TESTBED_STATUS_CREATED
def _do_connect(self, init = True):
for guid1, connections in self._connect.iteritems():
- element1 = self._elements[guid1]
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():
- element2 = self._elements[guid2]
factory_id2 = self._create[guid2]
# Connections are executed in a "From -> To" direction only
# This explicitly ignores the "To -> From" (mirror)
self._testbed_id, factory_id2,
connector_type_name2)
if connect_code:
- connect_code(self, element1, element2)
+ connect_code(self, guid1, guid2)
def do_connect_init(self):
self._do_connect()
def _do_cross_connect(self, cross_data, init = True):
for guid, cross_connections in self._cross_connect.iteritems():
- element = self._elements[guid]
factory = self._get_factory(guid)
for connector_type_name, cross_connection in \
cross_connections.iteritems():
connector_type = factory.connector_type(connector_type_name)
- (cross_testbed_id, cross_factory_id,
- cross_connector_type_name) = cross_connection
+ (cross_guid, cross_testbed_guid, cross_testbed_id,
+ cross_factory_id, cross_connector_type_name) = cross_connection
if init:
connect_code = connector_type.connect_to_init_code(
cross_testbed_id, cross_factory_id,
- cross_conector_type_name)
+ cross_connector_type_name)
else:
connect_code = connector_type.connect_to_compl_code(
cross_testbed_id, cross_factory_id,
- cross_conector_type_name)
+ cross_connector_type_name)
if connect_code:
- elem_data_guid = cross_data[cross_testbed_id][cross_guid]
- connect_code(self, element, elem_cross_data)
+ elem_cross_data = cross_data[cross_testbed_guid][cross_guid]
+ connect_code(self, guid, elem_cross_data)
def do_cross_connect_init(self, cross_data):
self._do_cross_connect(cross_data)
self._do_cross_connect(cross_data, init = False)
self._status = TESTBED_STATUS_CROSS_CONNECTED
- def set(self, time, guid, name, value):
+ def set(self, guid, name, value, time = TIME_NOW):
if not guid in self._create:
raise RuntimeError("Element guid %d doesn't exist" % guid)
factory = self._get_factory(guid)
self._setlog[guid][time][name] = value
self._set[guid][name] = value
- def get(self, time, guid, name):
+ def get(self, guid, name, time = TIME_NOW):
"""
gets an attribute from box definitions if available.
Throws KeyError if the GUID wasn't created
if not factory.box_attributes.has_attribute(name):
raise AttributeError, "Invalid attribute %s for element type %s" % \
(name, factory.factory_id)
- if self._status > TESTBED_STATUS_CREATED and \
- factory.box_attributes.is_attribute_design_only(name):
- raise AttributeError, "Attribute %s can only be queried during experiment design" % name
if guid in self._set and name in self._set[guid]:
return self._set[guid][name]
if guid in self._create_set and name in self._create_set[guid]:
from constants import TESTBED_ID
from nepi.core import testbed_impl
-from nepi.util.constants import TESTBED_STATUS_CREATED
+from nepi.util.constants import TIME_NOW
import os
class TestbedController(testbed_impl.TestbedController):
self._netns = self._load_netns_module()
super(TestbedController, self).do_setup()
- def set(self, time, guid, name, value):
- super(TestbedController, self).set(time, guid, name, value)
+ 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
element = self._elements.get(guid)
if element:
setattr(element, name, value)
- def get(self, time, guid, name):
- value = super(TestbedController, self).get(time, guid, name)
+ def get(self, guid, name, time = TIME_NOW):
+ value = super(TestbedController, self).get(guid, name, time)
# TODO: take on account schedule time for the task
factory_id = self._create[guid]
factory = self._factories[factory_id]
### Connection functions ####
-def connect_switch(testbed_instance, switch, interface):
+def connect_switch(testbed_instance, switch_guid, interface_guid):
+ switch = testbed_instance._elements[switch_guid]
+ interface = testbed_instance._elements[interface_guid]
switch.connect(interface)
-def connect_fd(testbed_instance, tap, cross_data):
+def connect_fd(testbed_instance, tap_guid, cross_data):
import passfd
import socket
+ tap = testbed_instance._elements[tap_guid]
fd = tap.file_descriptor
address = cross_data["LinuxSocketAddress"]
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
from constants import TESTBED_ID
from nepi.core import testbed_impl
from nepi.core.attributes import Attribute
-from nepi.util.constants import TESTBED_STATUS_CREATED
+from nepi.util.constants import TIME_NOW
import os
import sys
import threading
args = [self._condition])
self._simulator_thread.start()
- def set(self, time, guid, name, value):
- super(TestbedController, self).set(time, guid, name, value)
+ 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]
ns3_value = self._to_ns3_value(guid, name, value)
element.SetAttribute(name, ns3_value)
- def get(self, time, guid, name):
- value = super(TestbedController, self).get(time, guid, name)
+ def get(self, guid, name, time = TIME_NOW):
+ value = super(TestbedController, self).get(guid, name, time)
# TODO: take on account schedule time for the task
factory_id = self._create[guid]
factory = self._factories[factory_id]
### Connection functions ####
-def connect_node_device(testbed_instance, node, device):
+def connect_node_device(testbed_instance, node_guid, device_guid):
+ node = testbed_instance._elements[node_guid]
+ device = testbed_instance._elements[device_guid]
node.AddDevice(device)
-def connect_queue_device(testbed_instance, queue, device):
+def connect_queue_device(testbed_instance, queue_guid, device_guid):
+ queue = testbed_instance._elements[queue_guid]
+ device = testbed_instance._elements[device_guid]
device.SetQueue(queue)
-def connect_manager_device(testbed_instance, manager, device):
+def connect_manager_device(testbed_instance, manager_guid, device_guid):
+ manager = testbed_instance._elements[manager_guid]
+ device = testbed_instance._elements[device_guid]
device.SetRemoteStationManager(manager)
-def connect_phy_device(testbed_instance, phy, device):
+def connect_phy_device(testbed_instance, phy_guid, device_guid):
+ phy = testbed_instance._elements[phy_guid]
+ device = testbed_instance._elements[device_guid]
device.SetPhy(phy)
phy.SetDevice(device)
# search for the node asociated with the device
node = testbed_instance.elements[node_guid[0]]
phy.SetMobility(node)
-def connect_mac_device(testbed_instance, mac, device):
+def connect_mac_device(testbed_instance, mac_guid, device_guid):
+ mac = testbed_instance._elements[mac_guid]
+ device = testbed_instance._elements[device_guid]
device.SetMac(mac)
-def connect_errormodel_device(testbed_instance, model, device):
+def connect_errormodel_device(testbed_instance, model_guid, device_guid):
+ model = testbed_instance._elements[model_guid]
+ device = testbed_instance._elements[device_guid]
device.SetReceiveErrorModel(model)
-def connect_errormodel_phy(testbed_instance, err, phy):
+def connect_errormodel_phy(testbed_instance, err_guid, phy_guid):
+ err = testbed_instance._elements[err_guid]
+ phy = testbed_instance._elements[phy_guid]
phy.SetErrorRateModel(err)
-def connect_channel_device(testbed_instance, channel, device):
+def connect_channel_device(testbed_instance, channel_guid, device_guid):
+ channel = testbed_instance._elements[channel_guid]
+ device = testbed_instance._elements[device_guid]
device.Attach(channel)
-def connect_simple_channel_device(testbed_instance, channel, device):
+def connect_simple_channel_device(testbed_instance, channel_guid, device_guid):
+ channel = testbed_instance._elements[channel_guid]
+ device = testbed_instance._elements[device_guid]
device.SetChannel(channel)
def connect_loss_channel(testbed_instance, loss, channel):
+ loss = testbed_instance._elements[loss_guid]
+ channel = testbed_instance._elements[channel_guid]
channel.SetPropagationLossModel(loss)
-def connect_next_loss(testbed_instance, prev, next):
+def connect_next_loss(testbed_instance, prev_guid, next_guid):
+ prev = testbed_instance._elements[prev_guid]
+ next = testbed_instance._elements[next_guid]
prev.SetNext(next)
-def connect_delay_channel(testbed_instance, delay, channel):
+def connect_delay_channel(testbed_instance, delay_guid, channel_guid):
+ delay = testbed_instance._elements[delay_guid]
+ channel = testbed_instance._elements[channel_guid]
channel.SetPropagationDelayModel(delay)
-def connect_node_application(testbed_instance, node, application):
+def connect_node_application(testbed_instance, node_guid, application_guid):
+ node = testbed_instance._elements[node_guid]
+ application = testbed_instance._elements[application_guid]
node.AddApplication(application)
# works for ArpL3Protocol, Ipv4L3Protocol, UdpL4Protocol, TcpL4Protocol,
# NscTcpL4Protocol, MobilityModel (every subclass),
# RoutingProtocol (every subclass)
-def connect_node_other(tesbed_instance, node, other):
+def connect_node_other(testbed_instance, node_guid, other_guid):
+ node = testbed_instance._elements[node_guid]
+ other = testbed_instance._elements[other_guid]
node.AggregateObject(other)
-def connect_fd(testbed_instance, fdnd, cross_data):
+def connect_fd(testbed_instance, fdnd_guid, cross_data):
+ fdnd = testbed_instance._elements[fdnd_guid]
address = fdnd.socket_address
fdnd.set_attribute_value("LinuxSocketAddress", address)
from constants import TESTBED_ID
from nepi.core import testbed_impl
+from nepi.util.constants import TIME_NOW
import os
import time
# cleanup
del self._to_provision
- def set(self, time, guid, name, value):
- super(TestbedController, self).set(time, guid, name, value)
+ 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
element = self._elements[guid]
if element:
# invoke attribute refresh hook
element.refresh()
- def get(self, time, guid, name):
- value = super(TestbedController, self).get(time, guid, name)
+ def get(self, guid, name, time = TIME_NOW):
+ value = super(TestbedController, self).get(guid, name, time)
# TODO: take on account schedule time for the task
factory_id = self._create[guid]
factory = self._factories[factory_id]
### Connection functions ####
-def connect_node_iface_node(testbed_instance, node, iface):
+def connect_node_iface_node(testbed_instance, node_guid, iface_guid):
+ node = testbed_instance._elements[node_guid]
+ iface = testbed_instance._elements[iface_guid]
iface.node = node
-def connect_node_iface_inet(testbed_instance, iface, inet):
+def connect_node_iface_inet(testbed_instance, iface_guid, inet_guid):
+ iface = testbed_instance._elements[iface_guid]
iface.has_internet = True
-def connect_tun_iface_node(testbed_instance, node, iface):
+def connect_tun_iface_node(testbed_instance, node_guid, iface_guid):
+ node = testbed_instance._elements[node_guid]
+ iface = testbed_instance._elements[iface_guid]
if not node.emulation:
raise RuntimeError, "Use of TUN interfaces requires emulation"
iface.node = node
node.required_vsys.update(('fd_tuntap', 'vif_up'))
-def connect_tun_iface_peer(proto, testbed_instance, iface, peer_iface):
+def connect_tun_iface_peer(proto, testbed_instance, iface_guid, peer_iface_guid):
+ iface = testbed_instance._elements[iface_guid]
+ peer_iface = testbed_instance._elements[peer_iface_guid]
iface.peer_iface = peer_iface
iface.peer_proto = \
iface.tun_proto = proto
-def connect_dep(testbed_instance, node, app):
+def connect_dep(testbed_instance, node_guid, app_guid):
+ node = testbed_instance._elements[node_guid]
+ app = testbed_instance._elements[app_guid]
app.node = node
if app.depends:
if app.home_path and app.home_path not in node.pythonpath:
node.pythonpath.append(app.home_path)
-def connect_node_netpipe(testbed_instance, node, netpipe):
+def connect_node_netpipe(testbed_instance, node_guid, netpipe_guid):
+ node = testbed_instance._elements[node_guid]
+ netpipe = testbed_instance._elements[netpipe_guid]
if not node.emulation:
raise RuntimeError, "Use of NetPipes requires emulation"
netpipe.node = node
DO_CROSS_CONNECT_COMPL = 34
TESTBED_ID = 35
TESTBED_VERSION = 36
+EXPERIMENT_SET = 37
+EXPERIMENT_GET = 38
# PARAMETER TYPE
STRING = 100
CREATE_SET: "%d|%s" % (CREATE_SET, "%d|%s|%s|%d"),
FACTORY_SET: "%d|%s" % (FACTORY_SET, "%d|%s|%s|%d"),
CONNECT: "%d|%s" % (CONNECT, "%d|%s|%d|%s"),
- CROSS_CONNECT: "%d|%s" % (CROSS_CONNECT, "%d|%s|%d|%d|%s|%s"),
+ CROSS_CONNECT: "%d|%s" % (CROSS_CONNECT, "%d|%s|%d|%d|%s|%s|%s"),
ADD_TRACE: "%d|%s" % (ADD_TRACE, "%d|%s"),
ADD_ADDRESS: "%d|%s" % (ADD_ADDRESS, "%d|%s|%d|%s"),
ADD_ROUTE: "%d|%s" % (ADD_ROUTE, "%d|%s|%d|%s"),
DO_PRECONFIGURE: "%d" % DO_PRECONFIGURE,
DO_CROSS_CONNECT_INIT: "%d|%s" % (DO_CROSS_CONNECT_INIT, "%s"),
DO_CROSS_CONNECT_COMPL: "%d|%s" % (DO_CROSS_CONNECT_COMPL, "%s"),
- GET: "%d|%s" % (GET, "%s|%d|%s"),
- SET: "%d|%s" % (SET, "%s|%d|%s|%s|%d"),
+ GET: "%d|%s" % (GET, "%d|%s|%s"),
+ SET: "%d|%s" % (SET, "%d|%s|%s|%d|%s"),
+ EXPERIMENT_GET: "%d|%s" % (EXPERIMENT_GET, "%d|%d|%s|%s"),
+ EXPERIMENT_SET: "%d|%s" % (EXPERIMENT_SET, "%d|%d|%s|%s|%d|%s"),
GET_ROUTE: "%d|%s" % (GET, "%d|%d|%s"),
GET_ADDRESS: "%d|%s" % (GET, "%d|%d|%s"),
ACTION: "%d|%s" % (ACTION, "%s|%d|%s"),
FLOAT: "FLOAT",
TESTBED_ID: "TESTBED_ID",
TESTBED_VERSION: "TESTBED_VERSION",
+ EXPERIMENT_SET: "EXPERIMENT_SET",
+ EXPERIMENT_GET: "EXPERIMENT_GET",
})
def get_type(value):
cross_guid = int(params[3])
connector_type_name = params[4]
cross_guid = int(params[5])
- cross_testbed_id = params[6]
- cross_factory_id = params[7]
- cross_connector_type_name = params[8]
+ cross_testbed_guid = int(params[6])
+ cross_testbed_id = params[7]
+ cross_factory_id = params[8]
+ cross_connector_type_name = params[9]
self._testbed.defer_cross_connect(guid, connector_type_name, cross_guid,
- cross_testbed_id, cross_factory_id, cross_connector_type_name)
+ cross_testbed_guid, cross_testbed_id, cross_factory_id,
+ cross_connector_type_name)
return "%d|%s" % (OK, "")
def defer_add_trace(self, params):
return "%d|%s" % (OK, "")
def get(self, params):
- time = params[1]
- guid = int(param[2])
- name = base64.b64decode(params[3])
- value = self._testbed.get(time, guid, name)
+ guid = int(param[1])
+ name = base64.b64decode(params[2])
+ value = self._testbed.get(guid, name, time)
+ time = params[3]
result = base64.b64encode(str(value))
return "%d|%s" % (OK, result)
def set(self, params):
- time = params[1]
- guid = int(params[2])
- name = base64.b64decode(params[3])
- value = base64.b64decode(params[4])
- type = int(params[3])
+ guid = int(params[1])
+ name = base64.b64decode(params[2])
+ value = base64.b64decode(params[3])
+ type = int(params[2])
+ time = params[4]
value = set_type(type, value)
- self._testbed.set(time, guid, name, value)
+ self._testbed.set(guid, name, value, time)
return "%d|%s" % (OK, "")
def get_address(self, params):
reply = self.trace(params)
elif instruction == FINISHED:
reply = self.is_finished(params)
+ elif instruction == EXPERIMENT_GET:
+ reply = self.get(params)
+ elif instruction == EXPERIMENT_SET:
+ reply = self.set(params)
elif instruction == START:
reply = self.start(params)
elif instruction == STOP:
result = base64.b64encode(str(status))
return "%d|%s" % (OK, result)
+ def get(self, params):
+ testbed_guid = int(param[1])
+ guid = int(params[2])
+ name = base64.b64decode(params[3])
+ value = self._controller.get(testbed_guid, guid, name, time)
+ time = params[4]
+ result = base64.b64encode(str(value))
+ return "%d|%s" % (OK, result)
+
+ def set(self, params):
+ testbed_guid = int(params[1])
+ guid = int(params[2])
+ name = base64.b64decode(params[3])
+ value = base64.b64decode(params[4])
+ type = int(params[3])
+ time = params[5]
+ value = set_type(type, value)
+ self._controller.set(testbed_guid, guid, name, value, time)
+ return "%d|%s" % (OK, "")
+
def start(self, params):
self._controller.start()
return "%d|%s" % (OK, "")
raise RuntimeError(text)
def defer_cross_connect(self, guid, connector_type_name, cross_guid,
- cross_testbed_id, cross_factory_id, cross_connector_type_name):
+ cross_testbed_guid, cross_testbed_id, cross_factory_id,
+ cross_connector_type_name):
msg = testbed_messages[CROSS_CONNECT]
- msg = msg % (guid, connector_type_name, cross_guid,
+ msg = msg % (guid, connector_type_name, cross_guid, cross_testbed_guid,
cross_testbed_id, cross_factory_id, cross_connector_type_name)
self._client.send_msg(msg)
reply = self._client.read_reply()
if code == ERROR:
raise RuntimeError(text)
- def set(self, time, guid, name, value):
+ def set(self, guid, name, value, time = TIME_NOW):
msg = testbed_messages[SET]
type = get_type(value)
# avoid having "|" in this parameters
name = base64.b64encode(name)
value = base64.b64encode(str(value))
- msg = msg % (time, guid, name, value, type)
+ msg = msg % (guid, name, value, type, time)
self._client.send_msg(msg)
reply = self._client.read_reply()
result = reply.split("|")
if code == ERROR:
raise RuntimeError(text)
- def get(self, time, guid, name):
+ def get(self, guid, name, time = TIME_NOW):
msg = testbed_messages[GET]
# avoid having "|" in this parameters
name = base64.b64encode(name)
- msg = msg % (time, guid, name)
+ msg = msg % (guid, name, time)
self._client.send_msg(msg)
reply = self._client.read_reply()
result = reply.split("|")
raise RuntimeError(text)
return text == "True"
+ def set(self, testbed_guid, guid, name, value, time = TIME_NOW):
+ msg = testbed_messages[EXPERIMENT_SET]
+ type = get_type(value)
+ # avoid having "|" in this parameters
+ name = base64.b64encode(name)
+ value = base64.b64encode(str(value))
+ msg = msg % (testbed_guid, guid, name, value, type, time)
+ self._client.send_msg(msg)
+ reply = self._client.read_reply()
+ result = reply.split("|")
+ code = int(result[0])
+ text = base64.b64decode(result[1])
+ if code == ERROR:
+ raise RuntimeError(text)
+
+ def get(self, testbed_guid, guid, name, time = TIME_NOW):
+ msg = testbed_messages[EXPERIMENT_GET]
+ # avoid having "|" in this parameters
+ name = base64.b64encode(name)
+ msg = msg % (testbed_guid, guid, name, time)
+ self._client.send_msg(msg)
+ reply = self._client.read_reply()
+ result = reply.split("|")
+ code = int(result[0])
+ text = base64.b64decode(result[1])
+ if code == ERROR:
+ raise RuntimeError(text)
+ return text
+
def shutdown(self):
msg = controller_messages[SHUTDOWN]
self._client.send_msg(msg)
instance.do_configure()
instance.start()
attr_list = instance.get_attribute_list(5)
- self.assertEquals(attr_list, ["test", "fake", "label"])
+ self.assertEquals(attr_list, ["test", "fake", "cross", "label"])
while instance.status(7) != STATUS_FINISHED:
time.sleep(0.5)
app_result = instance.trace(7, "fake")
from nepi.util import proxy
import mock
import mock.metadata_v01
+import mock2
+import mock2.metadata_v01
import os
import shutil
import sys
def setUp(self):
sys.modules["nepi.testbeds.mock.metadata_v01"] = mock.metadata_v01
sys.modules["nepi.testbeds.mock"] = mock
+ sys.modules["nepi.testbeds.mock2.metadata_v01"] = mock2.metadata_v01
+ sys.modules["nepi.testbeds.mock2"] = mock2
self.root_dir = tempfile.mkdtemp()
def tearDown(self):
shutil.rmtree(self.root_dir)
-
- def make_test_experiment(self):
- exp_desc = ExperimentDescription()
- testbed_version = "01"
- testbed_id = "mock"
+
+ def make_testbed(self, exp_desc, testbed_id, testbed_version):
provider = FactoriesProvider(testbed_id, testbed_version)
desc = exp_desc.add_testbed_description(provider)
desc.set_attribute_value("fake", True)
return exp_desc, desc, app, node1, node2, iface1, iface2
+ def make_test_experiment(self):
+ exp_desc = ExperimentDescription()
+ testbed_version = "01"
+ testbed_id = "mock"
+ return self.make_testbed(exp_desc, testbed_id, testbed_version)
+
+ def make_cross_test_experiment(self):
+ exp_desc = ExperimentDescription()
+ testbed_version = "01"
+ testbed_id1 = "mock"
+ testbed_id2 = "mock2"
+ exp_desc, desc1, app1, node11, node12, iface11, iface12 = \
+ self.make_testbed(exp_desc, testbed_id1, testbed_version)
+ exp_desc, desc2, app2, node21, node22, iface21, iface22 = \
+ self.make_testbed(exp_desc, testbed_id2, testbed_version)
+ iface12.connector("cross").connect(iface21.connector("cross"))
+
+ return exp_desc, desc1, desc2, iface12, iface21
+
+ def test_single_process_cross_integration(self):
+ exp_desc, desc1, desc2, iface12, iface21 = \
+ self.make_cross_test_experiment()
+ xml = exp_desc.to_xml()
+ access_config = None
+ controller = proxy.create_controller(xml, access_config)
+
+ controller.start()
+ cross1 = controller.get(desc1.guid, iface12.guid, "cross")
+ cross2 = controller.get(desc2.guid, iface21.guid, "cross")
+ self.assertTrue(cross1 == cross2 == True)
+ controller.stop()
+ controller.shutdown()
+
def test_single_process_integration(self):
exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
xml = exp_desc.to_xml()
### Connection functions ####
+def connect_cross(testbed_instance, guid, cross_data):
+ connected = True
+ testbed_instance.set(guid, "cross", True)
+
### Creation functions ###
def create_node(testbed_instance, guid):
- element = NODE
- testbed_instance.elements[guid] = element
+ testbed_instance.elements[guid] = NODE
def create_iface(testbed_instance, guid):
- element = IFACE
- testbed_instance.elements[guid] = element
+ testbed_instance.elements[guid] = IFACE
def create_application(testbed_instance, guid):
- element = APP
- testbed_instance.elements[guid] = element
+ testbed_instance.elements[guid] = APP
### Start/Stop functions ###
"max": 1,
"min": 0
}),
+ "cross": dict({
+ "help": "Connector to an Interface in other testbed",
+ "name": "cross",
+ "max": 1,
+ "min": 0
+ }),
})
connections = [
dict({
"from": (TESTBED_ID, NODE, "devs"),
"to": (TESTBED_ID, IFACE, "node"),
- "code": None,
"can_cross": False
}),
dict({
"from": (TESTBED_ID, IFACE, "iface"),
"to": (TESTBED_ID, IFACE, "iface"),
- "code": None,
"can_cross": False
}),
dict({
"from": (TESTBED_ID, NODE, "apps"),
"to": (TESTBED_ID, APP, "node"),
- "code": None,
"can_cross": False
- })
-]
+ }),
+ dict({
+ "from": (TESTBED_ID, IFACE, "cross"),
+ "to": ("mock2", IFACE, "cross"),
+ "init_code": connect_cross,
+ "can_cross": True,
+ })]
attributes = dict({
"fake": dict({
"help": "fake attribute",
"type": Attribute.BOOL,
"value": False,
- "range": None,
- "allowed": None,
"validation_function": validation.is_bool
}),
"test": dict({
"type": Attribute.STRING,
"validation_function": validation.is_string
}),
+ "cross": dict({
+ "name": "cross",
+ "help": "Attribute that indicates if cross connection was performed",
+ "type": Attribute.BOOL,
+ "value": False,
+ "validation_function": validation.is_bool
+ })
})
traces = dict({
"status_function": None,
"allow_addresses": True,
"factory_attributes": ["fake"],
- "box_attributes": ["fake","test"],
- "connector_types": ["node", "iface"]
+ "box_attributes": ["fake", "test", "cross"],
+ "connector_types": ["node", "iface", "cross"]
}),
APP: dict({
"help": "Fake application",
"start_function": None,
"stop_function": None,
"status_function": status_application,
- "box_attributes": ["fake","test"],
+ "box_attributes": ["fake", "test"],
"connector_types": ["node"],
"traces": ["fake"]
}),
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from constants import TESTBED_ID
+from execute import TestbedController
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+TESTBED_ID = "mock2"
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from constants import TESTBED_ID
+from nepi.core import testbed_impl
+
+class TestbedController(testbed_impl.TestbedController):
+ def __init__(self, testbed_version):
+ super(TestbedController, self).__init__(TESTBED_ID, testbed_version)
+
+ def do_configure(self):
+ pass
+
+ def action(self, time, guid, action):
+ raise NotImplementedError
+
+ def trace(self, guid, trace_id, attribute='value'):
+ if attribute == 'value':
+ return """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
+
+--- 10.0.0.2 ping statistics ---
+1 packets transmitted, 1 received, 0% packet loss, time 0ms
+"""
+ elif attribute == 'path':
+ return '<test>'
+ else:
+ return None
+
+ def shutdown(self):
+ pass
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from constants import TESTBED_ID
+from nepi.core import metadata
+from nepi.core.attributes import Attribute
+from nepi.util import validation
+from nepi.util.constants import STATUS_FINISHED
+
+NODE = "Node"
+IFACE = "Interface"
+APP = "Application"
+
+### Connection functions ####
+
+def connect_cross(testbed_instance, guid, cross_data):
+ connected = cross_data["cross"]
+ testbed_instance.set(guid, "cross", connected)
+
+### Creation functions ###
+
+def create_node(testbed_instance, guid):
+ testbed_instance.elements[guid] = NODE
+
+def create_iface(testbed_instance, guid):
+ testbed_instance.elements[guid] = IFACE
+
+def create_application(testbed_instance, guid):
+ testbed_instance.elements[guid] = APP
+
+### Start/Stop functions ###
+
+### Status functions ###
+
+def status_application(testbed_instance, guid):
+ return STATUS_FINISHED
+
+### Factory information ###
+
+connector_types = dict({
+ "apps": dict({
+ "help": "Connector from node to applications",
+ "name": "apps",
+ "max": -1,
+ "min": 0
+ }),
+ "devs": dict({
+ "help": "Connector from node to network interfaces",
+ "name": "devs",
+ "max": -1,
+ "min": 0
+ }),
+ "node": dict({
+ "help": "Connector to a Node",
+ "name": "node",
+ "max": 1,
+ "min": 1
+ }),
+ "iface": dict({
+ "help": "Connector to a Interface",
+ "name": "iface",
+ "max": 1,
+ "min": 0
+ }),
+ "cross": dict({
+ "help": "Connector to an Interface in other testbed",
+ "name": "cross",
+ "max": 1,
+ "min": 0
+ }),
+ })
+
+connections = [
+ dict({
+ "from": (TESTBED_ID, NODE, "devs"),
+ "to": (TESTBED_ID, IFACE, "node"),
+ "can_cross": False
+ }),
+ dict({
+ "from": (TESTBED_ID, IFACE, "iface"),
+ "to": (TESTBED_ID, IFACE, "iface"),
+ "can_cross": False
+ }),
+ dict({
+ "from": (TESTBED_ID, NODE, "apps"),
+ "to": (TESTBED_ID, APP, "node"),
+ "can_cross": False
+ }),
+ dict({
+ "from": (TESTBED_ID, IFACE, "cross"),
+ "to": ("mock", IFACE, "cross"),
+ "compl_code": connect_cross,
+ "can_cross": True,
+ })]
+
+attributes = dict({
+ "fake": dict({
+ "name": "fake",
+ "help": "fake attribute",
+ "type": Attribute.BOOL,
+ "value": False,
+ "validation_function": validation.is_bool
+ }),
+ "test": dict({
+ "name": "test",
+ "help": "test attribute",
+ "type": Attribute.STRING,
+ "validation_function": validation.is_string
+ }),
+ "cross": dict({
+ "name": "cross",
+ "help": "Attribute that indicates if cross connection was performed",
+ "type": Attribute.BOOL,
+ "value": False,
+ "validation_function": validation.is_bool
+ })
+ })
+
+traces = dict({
+ "fake": dict({
+ "name": "fake",
+ "help": "fake trace"
+ }),
+ })
+
+factories_order = [ NODE, IFACE, APP ]
+
+factories_info = dict({
+ NODE: dict({
+ "help": "Fake node",
+ "category": "topology",
+ "create_function": create_node,
+ "start_function": None,
+ "stop_function": None,
+ "status_function": None,
+ "box_attributes": ["fake","test"],
+ "connector_types": ["devs", "apps"]
+ }),
+ IFACE: dict({
+ "help": "Fake iface",
+ "category": "devices",
+ "create_function": create_iface,
+ "start_function": None,
+ "stop_function": None,
+ "status_function": None,
+ "allow_addresses": True,
+ "factory_attributes": ["fake"],
+ "box_attributes": ["fake", "test", "cross"],
+ "connector_types": ["node", "iface", "cross"]
+ }),
+ APP: dict({
+ "help": "Fake application",
+ "category": "applications",
+ "create_function": create_application,
+ "start_function": None,
+ "stop_function": None,
+ "status_function": status_application,
+ "box_attributes": ["fake", "test"],
+ "connector_types": ["node"],
+ "traces": ["fake"]
+ }),
+})
+
+testbed_attributes = dict({
+ "fake": dict({
+ "name": "fake",
+ "help": "fake attribute",
+ "type": Attribute.BOOL,
+ "value": False,
+ "range": None,
+ "allowed": None,
+ "validation_function": validation.is_bool
+ }),
+ })
+
+class VersionedMetadataInfo(metadata.VersionedMetadataInfo):
+ @property
+ def connector_types(self):
+ return connector_types
+
+ @property
+ def connections(self):
+ return connections
+
+ @property
+ def attributes(self):
+ return attributes
+
+ @property
+ def traces(self):
+ return traces
+
+ @property
+ def create_order(self):
+ return factories_order
+
+ @property
+ def configure_order(self):
+ return factories_order
+
+ @property
+ def factories_info(self):
+ return factories_info
+
+ @property
+ def testbed_attributes(self):
+ return testbed_attributes
+