mock cross_connect test added to test/core/integration.py
[nepi.git] / src / nepi / testbeds / netns / metadata_v01.py
index b5a8369..2af898d 100644 (file)
@@ -5,7 +5,7 @@ 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 AF_INET, STATUS_NOT_STARTED, STATUS_RUNNING, \
+from nepi.util.constants import STATUS_NOT_STARTED, STATUS_RUNNING, \
         STATUS_FINISHED
 
 NODE = "Node"
@@ -20,16 +20,17 @@ FDNETDEV = "ns3::FileDescriptorNetDevice"
 
 ### Connection functions ####
 
-def connect_switch(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)
    
-#XXX: This connection function cannot be use to transfer a file descriptor
-# to a remote tap device
-def connect_fd_local(tap, fdnd):
+def connect_fd(testbed_instance, tap_guid, cross_data):
     import passfd
     import socket
+    tap = testbed_instance._elements[tap_guid]
     fd = tap.file_descriptor
-    address = fdnd.socket_address
+    address = cross_data["LinuxSocketAddress"]
     sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
     sock.connect(address)
     passfd.sendfd(sock, fd, '0')
@@ -37,7 +38,8 @@ def connect_fd_local(tap, fdnd):
 
 ### Creation functions ###
 
-def create_node(testbed_instance, guid, parameters):
+def create_node(testbed_instance, guid):
+    parameters = testbed_instance._get_parameters(guid)
     forward_X11 = False
     if "forward_X11" in parameters:
         forward_X11 = parameters["forward_X11"]
@@ -45,7 +47,7 @@ def create_node(testbed_instance, guid, parameters):
     element = testbed_instance.netns.Node(forward_X11 = forward_X11)
     testbed_instance.elements[guid] = element
 
-def create_p2piface(testbed_instance, guid, parameters):
+def create_p2piface(testbed_instance, guid):
     if guid in testbed_instance.elements:
         # The interface pair was already instantiated
         return
@@ -71,7 +73,7 @@ def create_p2piface(testbed_instance, guid, parameters):
     testbed_instance.elements[guid] = element1
     testbed_instance.elements[guid2] = element2
 
-def create_tapiface(testbed_instance, guid, parameters):
+def create_tapiface(testbed_instance, guid):
     node_guid = testbed_instance.get_connected(guid, "node", "devs")
     if len(node_guid) == 0:
         raise RuntimeError("Can't instantiate interface %d outside netns \
@@ -80,7 +82,7 @@ def create_tapiface(testbed_instance, guid, parameters):
     element = node.add_tap()
     testbed_instance.elements[guid] = element
 
-def create_nodeiface(testbed_instance, guid, parameters):
+def create_nodeiface(testbed_instance, guid):
     node_guid = testbed_instance.get_connected(guid, "node", "devs")
     if len(node_guid) == 0:
         raise RuntimeError("Can't instantiate interface %d outside netns \
@@ -89,16 +91,18 @@ def create_nodeiface(testbed_instance, guid, parameters):
     element = node.add_if()
     testbed_instance.elements[guid] = element
 
-def create_switch(testbed_instance, guid, parameters):
+def create_switch(testbed_instance, guid):
     element = testbed_instance.netns.Switch()
     testbed_instance.elements[guid] = element
 
-def create_application(testbed_instance, guid, parameters):
+def create_application(testbed_instance, guid):
     testbed_instance.elements[guid] = None # Delayed construction 
 
 ### Start/Stop functions ###
 
-def start_application(testbed_instance, guid, parameters, traces):
+def start_application(testbed_instance, guid):
+    parameters = testbed_instance._get_parameters(guid)
+    traces = testbed_instance._get_traces(guid)
     user = parameters["user"]
     command = parameters["command"]
     stdout = stderr = None
@@ -130,6 +134,28 @@ def status_application(testbed_instance, guid):
         return STATUS_RUNNING
     return STATUS_FINISHED
 
+### Configure functions ###
+
+def configure_device(testbed_instance, guid):
+    element = testbed_instance._elements[guid]
+    if not guid in testbed_instance._add_address:
+        return
+    addresses = testbed_instance._add_address[guid]
+    for address in addresses:
+        (address, netprefix, broadcast) = address
+        # TODO: Decide if we should add a ipv4 or ipv6 address
+        element.add_v4_address(address, netprefix)
+
+def configure_node(testbed_instance, guid):
+    element = testbed_instance._elements[guid]
+    if not guid in testbed_instance._add_route:
+        return
+    routes = testbed_instance._add_route[guid]
+    for route in routes:
+        (destination, netprefix, nexthop) = route
+        element.add_route(prefix = destination, prefix_len = netprefix,
+            nexthop = nexthop)
+
 ### Factory information ###
 
 connector_types = dict({
@@ -175,43 +201,38 @@ connections = [
     dict({
         "from": (TESTBED_ID, NODE, "devs"),
         "to":   (TESTBED_ID, P2PIFACE, "node"),
-        "code": None,
         "can_cross": False
     }),
     dict({
         "from": (TESTBED_ID, NODE, "devs"),
         "to":   (TESTBED_ID, TAPIFACE, "node"),
-        "code": None,
         "can_cross": False
     }),
     dict({
         "from": (TESTBED_ID, NODE, "devs"),
         "to":   (TESTBED_ID, NODEIFACE, "node"),
-        "code": None,
         "can_cross": False
     }),
     dict({
         "from": (TESTBED_ID, P2PIFACE, "p2p"),
         "to":   (TESTBED_ID, P2PIFACE, "p2p"),
-        "code": None,
         "can_cross": False
     }),
     dict({
         "from": (TESTBED_ID, TAPIFACE, "fd"),
         "to":   (NS3_TESTBED_ID, FDNETDEV, "fd"),
-        "code": connect_fd_local,
+        "compl_code": connect_fd,
         "can_cross": True
     }),
      dict({
         "from": (TESTBED_ID, SWITCH, "devs"),
         "to":   (TESTBED_ID, NODEIFACE, "switch"),
-        "code": connect_switch,
+        "init_code": connect_switch,
         "can_cross": False
     }),
     dict({
         "from": (TESTBED_ID, NODE, "apps"),
         "to":   (TESTBED_ID, APPLICATION, "node"),
-        "code": None,
         "can_cross": False
     })
 ]
@@ -222,21 +243,14 @@ attributes = dict({
                 "help": "Forward x11 from main namespace to the node",
                 "type": Attribute.BOOL, 
                 "value": False,
-                "range": None,
-                "allowed": None,
-                "readonly": False,
-                "visible": True,
+                "flags": Attribute.DesignOnly,
                 "validation_function": validation.is_bool
             }),
     "lladdr": dict({      
                 "name": "lladdr", 
                 "help": "Mac address", 
                 "type": Attribute.STRING,
-                "value": None,
-                "range": None,
-                "allowed": None,
-                "readonly": False,
-                "visible": True,
+                "flags": Attribute.DesignOnly,
                 "validation_function": validation.is_mac_address
             }),
     "up": dict({
@@ -244,43 +258,25 @@ attributes = dict({
                 "help": "Link up",
                 "type": Attribute.BOOL,
                 "value": False,
-                "range": None,
-                "allowed": None,
-                "readonly": False,
-                "visible": True,
                 "validation_function": validation.is_bool
             }),
     "device_name": dict({
                 "name": "name",
                 "help": "Device name",
                 "type": Attribute.STRING,
-                "value": None,
-                "range": None,
-                "allowed": None,
-                "readonly": False,
-                "visible": True,
+                "flags": Attribute.DesignOnly,
                 "validation_function": validation.is_string
             }),
     "mtu":  dict({
                 "name": "mtu", 
                 "help": "Maximum transmition unit for device",
                 "type": Attribute.INTEGER,
-                "value": None, 
-                "range": None, 
-                "allowed": None, 
-                "readonly": False, 
-                "visible": True,
                 "validation_function": validation.is_integer
             }),
     "broadcast": dict({ 
                 "name": "broadcast",
                 "help": "Broadcast address",
                 "type": Attribute.STRING,
-                "value": None,
-                "range": None,
-                "allowed": None,
-                "readonly": False,
-                "visible": True,
                 "validation_function": validation.is_string # TODO: should be is address!
             }),
     "multicast": dict({      
@@ -288,10 +284,6 @@ attributes = dict({
                 "help": "Multicast enabled",
                 "type": Attribute.BOOL,
                 "value": False,
-                "range": None,
-                "allowed": None,
-                "readonly": False,
-                "visible": True,
                 "validation_function": validation.is_bool
             }),
     "arp": dict({
@@ -299,68 +291,29 @@ attributes = dict({
                 "help": "ARP enabled",
                 "type": Attribute.BOOL,
                 "value": False,
-                "range": None,
-                "allowed": None,
-                "readonly": False,
-                "visible": True,
                 "validation_function": validation.is_bool
             }),
     "command": dict({
                 "name": "command",
                 "help": "Command line string",
                 "type": Attribute.STRING,
-                "value": None,
-                "range": None,
-                "allowed": None,
-                "readonly": False,
-                "visible": True,
+                "flags": Attribute.DesignOnly,
                 "validation_function": validation.is_string
             }),
     "user": dict({
                 "name": "user",
                 "help": "System user",
                 "type": Attribute.STRING,
-                "value": None,
-                "range": None,
-                "allowed": None,
-                "readonly": False,
-                "visible": True,
+                "flags": Attribute.DesignOnly,
                 "validation_function": validation.is_string
             }),
     "stdin": dict({
                 "name": "stdin",
                 "help": "Standard input",
                 "type": Attribute.STRING,
-                "value": None,
-                "range": None,
-                "allowed": None,
-                "readonly": False,
-                "visible": True,
+                "flags": Attribute.DesignOnly,
                 "validation_function": validation.is_string
             }),
-     "max_addresses": dict({
-                "name": "MaxAddresses",
-                "help": "Maximum number of addresses allowed by the device",
-                "type": Attribute.INTEGER,
-                "value": None,
-                "range": None,
-                "allowed": None,
-                "readonly": True,
-                "visible": False,
-                "validation_function": validation.is_integer
-            }),
-     "family": dict({
-                "name": "Family",
-                "help": "IP address family",
-                "type": Attribute.INTEGER,
-                "value": AF_INET,
-                "range": None,
-                "allowed": None,
-                "readonly": True,
-                "visible": False,
-                "validation_function": validation.is_integer
-            }),
-
     })
 
 traces = dict({
@@ -374,7 +327,10 @@ traces = dict({
         }) 
     })
 
-factories_order = [ NODE, P2PIFACE, NODEIFACE, TAPIFACE, SWITCH,
+create_order = [ NODE, P2PIFACE, NODEIFACE, TAPIFACE, SWITCH,
+        APPLICATION ]
+
+configure_order = [ P2PIFACE, NODEIFACE, TAPIFACE, SWITCH, NODE,
         APPLICATION ]
 
 factories_info = dict({
@@ -383,9 +339,7 @@ factories_info = dict({
             "help": "Emulated Node with virtualized network stack",
             "category": "topology",
             "create_function": create_node,
-            "start_function": None,
-            "stop_function": None,
-            "status_function": None,
+            "configure_function": configure_node,
             "box_attributes": ["forward_X11"],
             "connector_types": ["devs", "apps"]
        }),
@@ -394,10 +348,7 @@ factories_info = dict({
             "help": "Point to point network interface",
             "category": "devices",
             "create_function": create_p2piface,
-            "start_function": None,
-            "stop_function": None,
-            "status_function": None,
-            "factory_attributes": ["family", "max_addresses"],
+            "configure_function": configure_device,
             "box_attributes": ["lladdr", "up", "device_name", "mtu", 
                 "multicast", "broadcast", "arp"],
             "connector_types": ["node", "p2p"]
@@ -407,10 +358,7 @@ factories_info = dict({
             "help": "Tap device network interface",
             "category": "devices",
             "create_function": create_tapiface,
-            "start_function": None,
-            "stop_function": None,
-            "status_function": None,
-            "factory_attributes": ["family", "max_addresses"],
+            "configure_function": configure_device,
             "box_attributes": ["lladdr", "up", "device_name", "mtu", 
                 "multicast", "broadcast", "arp"],
             "connector_types": ["node", "fd"]
@@ -420,10 +368,7 @@ factories_info = dict({
             "help": "Node network interface",
             "category": "devices",
             "create_function": create_nodeiface,
-            "start_function": None,
-            "stop_function": None,
-            "status_function": None,
-            "factory_attributes": ["family", "max_addresses"],
+            "configure_function": configure_device,
             "box_attributes": ["lladdr", "up", "device_name", "mtu", 
                 "multicast", "broadcast", "arp"],
             "connector_types": ["node", "switch"]
@@ -433,9 +378,6 @@ factories_info = dict({
             "help": "Switch interface",
             "category": "devices",
             "create_function": create_switch,
-            "start_function": None,
-            "stop_function": None,
-            "status_function": None,
             "box_attributes": ["up", "device_name", "mtu", "multicast"],
              #TODO: Add attribute ("Stp", help, type, value, range, allowed, readonly, validation_function),
              #TODO: Add attribute ("ForwarddDelay", help, type, value, range, allowed, readonly, validation_function),
@@ -449,7 +391,6 @@ factories_info = dict({
             "category": "applications",
             "create_function": create_application,
             "start_function": start_application,
-            "stop_function": None,
             "status_function": status_application,
             "box_attributes": ["command", "user"],
             "connector_types": ["node"],
@@ -457,10 +398,20 @@ factories_info = dict({
         }),
 })
 
+testbed_attributes = dict({
+        "enable_debug": dict({
+                "name": "enableDebug",
+                "help": "Enable netns debug output",
+                "type": Attribute.BOOL,
+                "value": False,
+                "validation_function": validation.is_bool
+            }),
+    })
+
 class VersionedMetadataInfo(metadata.VersionedMetadataInfo):
     @property
-    def connections_types(self):
-        return connection_types
+    def connector_types(self):
+        return connector_types
 
     @property
     def connections(self):
@@ -475,10 +426,18 @@ class VersionedMetadataInfo(metadata.VersionedMetadataInfo):
         return traces
 
     @property
-    def factories_order(self):
-        return factories_order
+    def create_order(self):
+        return create_order
+
+    @property
+    def configure_order(self):
+        return configure_order
 
     @property
     def factories_info(self):
         return factories_info
 
+    @property
+    def testbed_attributes(self):
+        return testbed_attributes
+