ns3 integration tests added. 1 test fails.
[nepi.git] / src / nepi / core / execute.py
index b92e85c..857ebb5 100644 (file)
@@ -1,9 +1,10 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
-from nepi.core.attributes import AttributesMap
+from nepi.core.attributes import Attribute, AttributesMap
+from nepi.util import proxy, validation
+from nepi.util.constants import STATUS_FINISHED
 from nepi.util.parser._xml import XmlExperimentParser
-from nepi.util import validation
 import sys
 
 class ConnectorType(object):
@@ -88,8 +89,8 @@ class ConnectorType(object):
 # need a definition!
 class Factory(AttributesMap):
     def __init__(self, factory_id, create_function, start_function, 
-            stop_function, status_function, allow_addresses = False, 
-            allow_routes = False):
+            stop_function, status_function, configure_function,
+            allow_addresses = False, allow_routes = False):
         super(Factory, self).__init__()
         self._factory_id = factory_id
         self._allow_addresses = (allow_addresses == True)
@@ -98,8 +99,10 @@ class Factory(AttributesMap):
         self._start_function = start_function
         self._stop_function = stop_function
         self._status_function = status_function
+        self._configure_function = configure_function
         self._connector_types = dict()
         self._traces = list()
+        self._box_attributes = AttributesMap()
 
     @property
     def factory_id(self):
@@ -113,6 +116,10 @@ class Factory(AttributesMap):
     def allow_routes(self):
         return self._allow_routes
 
+    @property
+    def box_attributes(self):
+        return self._box_attributes
+
     @property
     def create_function(self):
         return self._create_function
@@ -129,6 +136,10 @@ class Factory(AttributesMap):
     def status_function(self):
         return self._status_function
 
+    @property
+    def configure_function(self):
+        return self._configure_function
+
     @property
     def traces(self):
         return self._traces
@@ -142,6 +153,11 @@ class Factory(AttributesMap):
     def add_trace(self, trace_id):
         self._traces.append(trace_id)
 
+    def add_box_attribute(self, name, help, type, value = None, range = None,
+        allowed = None, flags = Attribute.NoFlags, validation_function = None):
+        self._box_attributes.add_attribute(name, help, type, value, range, 
+                allowed, flags, validation_function)
+
 class TestbedInstance(object):
     def __init__(self, testbed_id, testbed_version):
         self._testbed_id = testbed_id
@@ -160,7 +176,11 @@ class TestbedInstance(object):
         raise NotImplementedError
 
     def create_set(self, guid, name, value):
-        """Instructs setting an attribute on an element"""
+        """Instructs setting an initial attribute on an element"""
+        raise NotImplementedError
+
+    def factory_set(self, guid, name, value):
+        """Instructs setting an attribute on a factory"""
         raise NotImplementedError
 
     def connect(self, guid1, connector_type_name1, guid2, 
@@ -174,7 +194,7 @@ class TestbedInstance(object):
     def add_trace(self, guid, trace_id):
         raise NotImplementedError
 
-    def add_adddress(self, guid, family, address, netprefix, broadcast): 
+    def add_address(self, guid, address, netprefix, broadcast): 
         raise NotImplementedError
 
     def add_route(self, guid, destination, netprefix, nexthop):
@@ -203,10 +223,10 @@ class TestbedInstance(object):
         elements are done"""
         raise NotImplementedError
 
-    def start(self, time):
+    def start(self):
         raise NotImplementedError
 
-    def stop(self, time):
+    def stop(self):
         raise NotImplementedError
 
     def set(self, time, guid, name, value):
@@ -237,92 +257,86 @@ class ExperimentController(object):
     def experiment_xml(self):
         return self._experiment_xml
 
-    def testbed_instance(self, guid):
-        return self._testbeds[guid]
-
-    def set_testbed_access_config(self, guid, access_config):
-        self._access_config[guid] = access_config
+    def set_access_configuration(self, testbed_guid, access_config):
+        self._access_config[testbed_guid] = access_config
 
     def trace(self, testbed_guid, guid, trace_id):
         return self._testbeds[testbed_guid].trace(guid, trace_id)
 
     def start(self):
+        self._create_testbed_instances()
+        for testbed in self._testbeds.values():
+            testbed.do_setup()
+        for testbed in self._testbeds.values():
+            testbed.do_create()
+            testbed.do_connect()
+            testbed.do_configure()
+        for testbed in self._testbeds.values():
+            testbed.do_cross_connect()
+        for testbed in self._testbeds.values():
+            testbed.start()
+
+    def stop(self):
+       for testbed in self._testbeds.values():
+           testbed.stop()
+
+    def is_finished(self, guid):
+        for testbed in self._testbeds.values():
+            for guid_ in testbed.guids:
+                if guid_ == guid:
+                    return testbed.status(guid) == STATUS_FINISHED
+        raise RuntimeError("No element exists with guid %d" % guid)    
+
+    def shutdown(self):
+       for testbed in self._testbeds.values():
+           testbed.shutdown()
+
+    def _create_testbed_instances(self):
         parser = XmlExperimentParser()
         data = parser.from_xml_to_data(self._experiment_xml)
         element_guids = list()
         for guid in data.guids:
             if data.is_testbed_data(guid):
                 (testbed_id, testbed_version) = data.get_testbed_data(guid)
-                instance = self._build_testbed_instance(testbed_id, 
-                        testbed_version)
+                access_config = None if guid not in self._access_config else\
+                        self._access_config[guid]
+                testbed = proxy.create_testbed_instance(testbed_id, 
+                        testbed_version, access_config)
                 for (name, value) in data.get_attribute_data(guid):
-                    instance.configure(name, value)
-                self._testbeds[guid] = instance
+                    testbed.configure(name, value)
+                self._testbeds[guid] = testbed
             else:
                 element_guids.append(guid)
+        self._program_testbed_instances(element_guids, data)
 
+    def _program_testbed_instances(self, element_guids, data):
         for guid in element_guids:
             (testbed_guid, factory_id) = data.get_box_data(guid)
-            instance = self._testbeds[testbed_guid]
-            instance.create(guid, factory_id)
+            testbed = self._testbeds[testbed_guid]
+            testbed.create(guid, factory_id)
             for (name, value) in data.get_attribute_data(guid):
-                instance.create_set(guid, name, value)
+                testbed.create_set(guid, name, value)
 
         for guid in element_guids: 
             (testbed_guid, factory_id) = data.get_box_data(guid)
-            instance = self._testbeds[testbed_guid]
+            testbed = self._testbeds[testbed_guid]
             for (connector_type_name, other_guid, other_connector_type_name) \
                     in data.get_connection_data(guid):
                 (testbed_guid, factory_id) = data.get_box_data(guid)
                 (other_testbed_guid, other_factory_id) = data.get_box_data(
                         other_guid)
                 if testbed_guid == other_testbed_guid:
-                    instance.connect(guid, connector_type_name, other_guid, 
+                    testbed.connect(guid, connector_type_name, other_guid, 
                         other_connector_type_name)
                 else:
-                    instance.cross_connect(guid, connector_type_name, other_guid, 
+                    testbed.cross_connect(guid, connector_type_name, other_guid, 
                         other_testbed_id, other_factory_id, other_connector_type_name)
             for trace_id in data.get_trace_data(guid):
-                instance.add_trace(guid, trace_id)
-            for (autoconf, address, family, netprefix, broadcast) in \
+                testbed.add_trace(guid, trace_id)
+            for (autoconf, address, netprefix, broadcast) in \
                     data.get_address_data(guid):
                 if address != None:
-                    instance.add_adddress(guid, family, address, netprefix,
-                        broadcast)
-            for (family, destination, netprefix, nexthop) in \
-                    data.get_route_data(guid):
-                instance.add_route(guid, destination, netprefix, nexthop)
-
-        for instance in self._testbeds.values():
-            instance.do_setup()
-        for instance in self._testbeds.values():
-            instance.do_create()
-            instance.do_connect()
-            instance.do_configure()
-        for instances in self._testbeds.values():
-            instance.do_cross_connect()
-        for instances in self._testbeds.values():
-            instance.start()
-
-    def stop(self):
-       for instance in self._testbeds.values():
-           instance.stop()
-
-    def status(self, guid):
-        for instance in self._testbeds.values():
-            for guid_ in instance.guids:
-                if guid_ == guid:
-                    return instance.status(guid)
-        raise RuntimeError("No element exists with guid %d" % guid)    
-
-    def shutdown(self):
-       for instance in self._testbeds.values():
-           instance.shutdown()
-
-    def _build_testbed_instance(self, testbed_id, testbed_version):
-        mod_name = "nepi.testbeds.%s" % (testbed_id.lower())
-        if not mod_name in sys.modules:
-            __import__(mod_name)
-        module = sys.modules[mod_name]
-        return module.TestbedInstance(testbed_version)
+                    testbed.add_address(guid, address, netprefix, broadcast)
+            for (destination, netprefix, nexthop) in data.get_route_data(guid):
+                testbed.add_route(guid, destination, netprefix, nexthop)