from nepi.util.constants import STATUS_FINISHED
from nepi.util.parser._xml import XmlExperimentParser
import sys
+import re
+
+ATTRIBUTE_PATTERN_BASE = re.compile(r"\{#\[(?P<label>[-a-zA-Z0-9._]*)\](?P<expr>(?P<component>\.addr\[[0-9]+\]|\.route\[[0-9]+\]|\.trace\[[0-9]+\]|).\[(?P<attribute>[-a-zA-Z0-9._]*)\])#}")
+ATTRIBUTE_PATTERN_GUID_SUB = r"{#[%(guid)s]%(expr)s#}"
class ConnectorType(object):
def __init__(self, testbed_id, factory_id, name, max = -1, min = 0):
self._experiment_xml = experiment_xml
self._testbeds = dict()
self._access_config = dict()
+ self._label_guids = dict()
@property
def experiment_xml(self):
parser = XmlExperimentParser()
data = parser.from_xml_to_data(self._experiment_xml)
element_guids = list()
- for guid in data.guids:
+ label_guids = dict()
+ data_guids = data.guids
+ for guid in data_guids:
if data.is_testbed_data(guid):
(testbed_id, testbed_version) = data.get_testbed_data(guid)
access_config = None if guid not in self._access_config else\
self._testbeds[guid] = testbed
else:
element_guids.append(guid)
+ label = data.get_attribute_data(guid, "label")
+ if label is not None:
+ if label in label_guids:
+ raise RuntimeError, "Label %r is not unique" % (label,)
+ label_guids[label] = guid
+ for guid in data_guids:
+ if not data.is_testbed_data(guid):
+ for name, value in data.get_attribute_data(guid):
+ if isinstance(value, basestring):
+ match = ATTRIBUTE_PATTERN_BASE.search(value)
+ if match:
+ label = match.group("label")
+ ref_guid = label_guids.get(label)
+ if ref_guid is not None:
+ print "@", guid, ",", ref_guid, "=", label, ": ", value, "->",
+ value = ATTRIBUTE_PATTERN_BASE.sub(
+ ATTRIBUTE_PATTERN_GUID_SUB % dict(
+ guid=ref_guid,
+ expr=match.group("expr"),
+ label=label),
+ value)
+ print value
+ data.set_attribute_data(guid, name, value)
+ self._label_guids = label_guids
self._program_testbed_instances(element_guids, data)
def _program_testbed_instances(self, element_guids, data):
from nepi.core.attributes import Attribute, AttributesMap
import sys
+from nepi.util import validation
class VersionedMetadataInfo(object):
@property
raise NotImplementedError
class Metadata(object):
+ STANDARD_BOX_ATTRIBUTES = (
+ ("label", dict({
+ "name": "label",
+ "validation_function": validation.is_string,
+ "type": Attribute.STRING,
+ "flags": Attribute.DesignOnly,
+ "help": "A unique identifier for referring to this box"
+ })),
+ )
+
def __init__(self, testbed_id, version):
self._version = version
self._testbed_id = testbed_id
help, category)
self._add_attributes(factory, info, "factory_attributes")
self._add_attributes(factory, info, "box_attributes", True)
+ self._add_standard_attributes(factory, info, True)
self._add_design_traces(factory, info)
self._add_design_connector_types(factory, info)
factories.append(factory)
allow_addresses, allow_routes)
self._add_attributes(factory, info, "factory_attributes")
self._add_attributes(factory, info, "box_attributes", True)
+ self._add_standard_attributes(factory, info, False)
self._add_execute_traces(factory, info)
self._add_execute_connector_types(factory, info)
factories.append(factory)
__import__(mod_name)
return sys.modules[mod_name]
- def _add_attributes(self, factory, info, attr_key, box_attributes = False):
- if attr_key in info:
- for attr_id in info[attr_key]:
- attr_info = self._metadata.attributes[attr_id]
- name = attr_info["name"]
- help = attr_info["help"]
- type = attr_info["type"]
- value = attr_info["value"] if "value" in attr_info else None
- range = attr_info["range"] if "range" in attr_info else None
- allowed = attr_info["allowed"] if "allowed" in attr_info \
- else None
- flags = attr_info["flags"] if "flags" in attr_info \
- and attr_info["flags"] != None \
- else Attribute.NoFlags
- validation_function = attr_info["validation_function"]
- if box_attributes:
- factory.add_box_attribute(name, help, type, value, range,
- allowed, flags, validation_function)
- else:
- factory.add_attribute(name, help, type, value, range,
- allowed, flags, validation_function)
+ def _add_standard_attributes(self, factory, info, design):
+ if design:
+ attr_bundle = self.STANDARD_BOX_ATTRIBUTES
+ else:
+ # Only add non-DesignOnly attributes
+ def nonDesign(attr_info):
+ return not (attr_info[1].get('flags',Attribute.NoFlags) & Attribute.DesignOnly)
+ attr_bundle = filter(nonDesign, self.STANDARD_BOX_ATTRIBUTES)
+ self._add_attributes(factory, info, None, True,
+ attr_bundle = self.STANDARD_BOX_ATTRIBUTES)
+
+ def _add_attributes(self, factory, info, attr_key, box_attributes = False, attr_bundle = ()):
+ if not attr_bundle and attr_key in info:
+ attr_bundle = [ (attr_id, self._metadata.attributes[attr_id])
+ for attr_id in info[attr_key] ]
+ for attr_id, attr_info in attr_bundle:
+ name = attr_info["name"]
+ help = attr_info["help"]
+ type = attr_info["type"]
+ value = attr_info["value"] if "value" in attr_info else None
+ range = attr_info["range"] if "range" in attr_info else None
+ allowed = attr_info["allowed"] if "allowed" in attr_info \
+ else None
+ flags = attr_info["flags"] if "flags" in attr_info \
+ and attr_info["flags"] != None \
+ else Attribute.NoFlags
+ validation_function = attr_info["validation_function"]
+ if box_attributes:
+ factory.add_box_attribute(name, help, type, value, range,
+ allowed, flags, validation_function)
+ else:
+ factory.add_attribute(name, help, type, value, range,
+ allowed, flags, validation_function)
def _add_design_traces(self, factory, info):
if "traces" in info:
return [(name, value) for name, value \
in factory_attributes_data.iteritems()]
- def get_attribute_data(self, guid):
+ def get_attribute_data(self, guid, attribute=None, default=None):
data = self.data[guid]
if not "attributes" in data:
- return []
+ if attribute is None:
+ return []
+ else:
+ return None
attributes_data = data["attributes"]
- return [(name, value) for name, value \
- in attributes_data.iteritems()]
+ if attribute is None:
+ return [(name, value) for name, value \
+ in attributes_data.iteritems()]
+ else:
+ return attributes_data.get(attribute, default)
+
+ def set_attribute_data(self, guid, attribute, value):
+ data = self.data[guid]
+ if not "attributes" in data:
+ raise KeyError, "No attributes in reference OBJECT %r" % (guid,)
+ attributes_data = data["attributes"]
+ attributes_data[attribute] = value
def get_trace_data(self, guid):
data = self.data[guid]
sys.modules["nepi.testbeds.mock.metadata_v01"] = mock.metadata_v01
sys.modules["nepi.testbeds.mock"] = mock
self.root_dir = tempfile.mkdtemp()
-
- def test_single_process_integration(self):
+
+ def make_test_experiment(self):
exp_desc = ExperimentDescription()
testbed_version = "01"
testbed_id = "mock"
app = desc.create("Application")
app.connector("node").connect(node1.connector("apps"))
app.enable_trace("fake")
+
+ return exp_desc, desc, app, node1, node2, iface1, iface2
+ def test_single_process_integration(self):
+ 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.shutdown()
def test_daemonized_controller_integration(self):
- exp_desc = ExperimentDescription()
- testbed_version = "01"
- testbed_id = "mock"
- provider = FactoriesProvider(testbed_id, testbed_version)
- desc = exp_desc.add_testbed_description(provider)
- desc.set_attribute_value("fake", True)
- node1 = desc.create("Node")
- node2 = desc.create("Node")
- iface1 = desc.create("Interface")
- iface1.set_attribute_value("fake", True)
- node1.connector("devs").connect(iface1.connector("node"))
- iface2 = desc.create("Interface")
- iface2.set_attribute_value("fake", True)
- node2.connector("devs").connect(iface2.connector("node"))
- iface1.connector("iface").connect(iface2.connector("iface"))
- app = desc.create("Application")
- app.connector("node").connect(node1.connector("apps"))
- app.enable_trace("fake")
-
+ exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
xml = exp_desc.to_xml()
access_config = proxy.AccessConfiguration()
access_config.set_attribute_value("mode",
controller.shutdown()
def test_daemonized_testbed_integration(self):
- exp_desc = ExperimentDescription()
- testbed_version = "01"
- testbed_id = "mock"
- provider = FactoriesProvider(testbed_id, testbed_version)
- desc = exp_desc.add_testbed_description(provider)
- desc.set_attribute_value("fake", True)
- node1 = desc.create("Node")
- node2 = desc.create("Node")
- iface1 = desc.create("Interface")
- iface1.set_attribute_value("fake", True)
- node1.connector("devs").connect(iface1.connector("node"))
- iface2 = desc.create("Interface")
- iface2.set_attribute_value("fake", True)
- node2.connector("devs").connect(iface2.connector("node"))
- iface1.connector("iface").connect(iface2.connector("iface"))
- app = desc.create("Application")
- app.connector("node").connect(node1.connector("apps"))
- app.enable_trace("fake")
-
+ exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
xml = exp_desc.to_xml()
controller = proxy.create_controller(xml, access_config = None)
access_config = proxy.AccessConfiguration()
controller.shutdown()
def test_daemonized_all_integration(self):
- exp_desc = ExperimentDescription()
- testbed_version = "01"
- testbed_id = "mock"
- provider = FactoriesProvider(testbed_id, testbed_version)
- desc = exp_desc.add_testbed_description(provider)
- desc.set_attribute_value("fake", True)
- node1 = desc.create("Node")
- node2 = desc.create("Node")
- iface1 = desc.create("Interface")
- iface1.set_attribute_value("fake", True)
- node1.connector("devs").connect(iface1.connector("node"))
- iface2 = desc.create("Interface")
- iface2.set_attribute_value("fake", True)
- node2.connector("devs").connect(iface2.connector("node"))
- iface1.connector("iface").connect(iface2.connector("iface"))
- app = desc.create("Application")
- app.connector("node").connect(node1.connector("apps"))
- app.enable_trace("fake")
-
+ exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
xml = exp_desc.to_xml()
access_config = proxy.AccessConfiguration()
access_config.set_attribute_value("mode",
fake_result = controller.trace(desc.guid, app.guid, "fake")
comp_result = """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
+"""
+ self.assertTrue(fake_result.startswith(comp_result))
+ controller.stop()
+ controller.shutdown()
+
+ def test_reference_expressions(self):
+ exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
+
+ iface1.set_attribute_value("label", "some")
+ addr = iface1.add_address()
+ addr.set_attribute_value("Address", "10.0.0.2")
+ iface2.set_attribute_value("test", "{#[some].addr[0].[Address]#}")
+
+ # TODO: Test actual substitution
+
+ xml = exp_desc.to_xml()
+ access_config = None
+ controller = proxy.create_controller(xml, access_config)
+ controller.start()
+ while not controller.is_finished(app.guid):
+ time.sleep(0.5)
+ fake_result = controller.trace(desc.guid, app.guid, "fake")
+ comp_result = """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
"""
# TODO: This test doesn't run because
# sys.modules["nepi.testbeds.mock"] = mock
# is not set in the ssh process
- exp_desc = ExperimentDescription()
- testbed_version = "01"
- testbed_id = "mock"
- env = test_util.test_environment()
- provider = FactoriesProvider(testbed_id, testbed_version)
- desc = exp_desc.add_testbed_description(provider)
- desc.set_attribute_value("fake", True)
- node1 = desc.create("Node")
- node2 = desc.create("Node")
- iface1 = desc.create("Interface")
- iface1.set_attribute_value("fake", True)
- node1.connector("devs").connect(iface1.connector("node"))
- iface2 = desc.create("Interface")
- iface2.set_attribute_value("fake", True)
- node2.connector("devs").connect(iface2.connector("node"))
- iface1.connector("iface").connect(iface2.connector("iface"))
- app = desc.create("Application")
- app.connector("node").connect(node1.connector("apps"))
- app.enable_trace("fake")
-
+ exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
xml = exp_desc.to_xml()
access_config = proxy.AccessConfiguration()
access_config.set_attribute_value("mode",
"allowed": None,
"validation_function": validation.is_bool
}),
+ "test": dict({
+ "name": "test",
+ "help": "test attribute",
+ "type": Attribute.STRING,
+ "validation_function": validation.is_string
+ }),
})
traces = dict({
"start_function": None,
"stop_function": None,
"status_function": None,
- "box_attributes": ["fake"],
+ "box_attributes": ["fake","test"],
"connector_types": ["devs", "apps"]
}),
IFACE: dict({
"start_function": None,
"stop_function": None,
"status_function": None,
+ "allow_addresses": True,
"factory_attributes": ["fake"],
- "box_attributes": ["fake"],
+ "box_attributes": ["fake","test"],
"connector_types": ["node", "iface"]
}),
APP: dict({
"start_function": None,
"stop_function": None,
"status_function": status_application,
- "box_attributes": ["fake"],
+ "box_attributes": ["fake","test"],
"connector_types": ["node"],
"traces": ["fake"]
}),