test: all
retval=0; \
- for i in `find "$(TESTDIR)" -perm -u+x -type f`; do \
+ for i in `find "$(TESTDIR)" -iname '*.py' -perm -u+x -type f`; do \
echo $$i; \
TESTLIBPATH="$(TESTLIB)" PYTHONPATH="$(PYPATH)" $$i -v || retval=$$?; \
done; exit $$retval
name = "nepi",
version = "0.1",
description = "High-level abstraction for running network experiments",
- author = "Alina Quereilhac and Martín Ferrari",
+ author = "Alina Quereilhac, Martín Ferrari and Claudio Freire",
url = "http://yans.pl.sophia.inria.fr/code/hgwebdir.cgi/nepi/",
license = "GPLv2",
platforms = "Linux",
"nepi.testbeds",
"nepi.testbeds.netns",
"nepi.testbeds.ns3",
+ "nepi.testbeds.planetlab",
"nepi.core",
"nepi.util.parser",
"nepi.util" ],
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from constants import TESTBED_ID
+import plcapi
+import operator
+
+class Application(object):
+ def __init__(self, api=None):
+ if not api:
+ api = plcapi.PLCAPI()
+ self._api = api
+
+ # Attributes
+ self.command = None
+ self.sudo = False
+
+ self.stdout = None
+ self.stderr = None
+
+ # Those are filled when an actual node is connected
+ self.node = None
+
+ def validate(self):
+ pass
+
def _make_internet(self, parameters):
return self._node.Internet()
+
+ def _make_application(self, parameters):
+ app = self._app.Application()
+
+ # Note: there is 1-to-1 correspondence between attribute names
+ # If that changes, this has to change as well
+ for attr in parameters.get_attribute_names():
+ setattr(app, attr, parameters.get_attribute_value(attr))
+
+ return app
+
+
# -*- coding: utf-8 -*-
from constants import TESTBED_ID
-import nepi.util.ipaddr
+import nepi.util.ipaddr2 as ipaddr2
import plcapi
class NodeIface(object):
self.address = address
self.netprefix = netprefix
- self.netmask = nepi.util.ipaddr.ipv4_dot2mask(netprefix)
+ self.netmask = ipaddr2.ipv4_dot2mask(netprefix)
def validate(self):
pass
def connect_node_iface_node(testbed_instance, node, iface):
iface.node = node
-def connect_node_iface_inet(testbed_instance, node, internet):
+def connect_node_iface_inet(testbed_instance, iface, inet):
iface.has_internet = True
def connect_tun_iface_node(testbed_instance, node, iface):
iface.node = node
+def connect_app(testbed_instance, node, app):
+ app.node = node
+
### Creation functions ###
def create_node(testbed_instance, guid):
def create_application(testbed_instance, guid):
parameters = testbed_instance._get_parameters(guid)
- element = testbed_instance._make_internet(parameters)
+ element = testbed_instance._make_application(parameters)
testbed_instance.elements[guid] = element
def create_internet(testbed_instance, guid):
parameters = testbed_instance._get_parameters(guid)
- element = None #TODO
+ element = testbed_instance._make_internet(parameters)
testbed_instance.elements[guid] = element
### Start/Stop functions ###
def start_application(testbed_instance, guid):
parameters = testbed_instance._get_parameters(guid)
traces = testbed_instance._get_traces(guid)
- user = parameters["user"]
+ app = testbed_instance.elements[guid]
+ sudo = parameters["sudo"]
command = parameters["command"]
- stdout = stderr = None
- if "stdout" in traces:
- # TODO
- pass
- if "stderr" in traces:
- # TODO
- pass
-
- node_guids = testbed_instance.get_connected(guid, "node", "apps")
- if not node_guid:
- raise RuntimeError, "Can't instantiate interface %d outside planetlab node" % (guid,)
- node = testbed_instance.elements[node_guids[0]]
+ app.stdout = testbed_instance.trace_filename(guid, "stdout")
+ app.stderr = testbed_instance.trace_filename(guid, "stderr")
+
# TODO
pass
dict({
"from": (TESTBED_ID, NODE, "apps"),
"to": (TESTBED_ID, APPLICATION, "node"),
- "code": None,
+ "code": connect_app,
"can_cross": False
})
]
"flags": Attribute.DesignOnly,
"validation_function": validation.is_string
}),
- "user": dict({
+ "sudo": dict({
"name": "user",
"help": "System user",
- "type": Attribute.STRING,
+ "type": Attribute.BOOL,
"flags": Attribute.DesignOnly,
- "validation_function": validation.is_string
+ "value": False,
+ "validation_function": validation.is_bool
}),
"stdin": dict({
"name": "stdin",
"create_function": create_application,
"start_function": start_application,
"status_function": status_application,
- "box_attributes": ["command", "user"],
+ "box_attributes": ["command", "sudo"],
"connector_types": ["node"],
"traces": ["stdout", "stderr"]
}),
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from nepi.core.design import ExperimentDescription, FactoriesProvider
+import os
+import shutil
+import test_util
+import unittest
+import uuid
+
+class NetnsDesignTestCase(unittest.TestCase):
+ def test_design_if(self):
+ exp_desc = ExperimentDescription()
+ testbed_version = "01"
+ testbed_id = "planetlab"
+ provider = FactoriesProvider(testbed_id, testbed_version)
+ tstbd_desc = exp_desc.add_testbed_description(provider)
+ node1 = tstbd_desc.create("Node")
+ node2 = tstbd_desc.create("Node")
+ iface1 = tstbd_desc.create("NodeInterface")
+ node1.connector("devs").connect(iface1.connector("node"))
+ iface2 = tstbd_desc.create("NodeInterface")
+ node2.connector("devs").connect(iface2.connector("node"))
+ switch = tstbd_desc.create("Internet")
+ iface1.connector("inet").connect(switch.connector("devs"))
+ iface2.connector("inet").connect(switch.connector("devs"))
+ app = tstbd_desc.create("Application")
+ app.set_attribute_value("command", "ping -qc10 10.0.0.2")
+ app.connector("node").connect(node1.connector("apps"))
+ xml = exp_desc.to_xml()
+ exp_desc2 = ExperimentDescription()
+ exp_desc2.from_xml(xml)
+ xml2 = exp_desc2.to_xml()
+ self.assertTrue(xml == xml2)
+
+if __name__ == '__main__':
+ unittest.main()
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import getpass
+from nepi.util.constants import STATUS_FINISHED
+from nepi.testbeds import netns
+import os
+import shutil
+import tempfile
+import test_util
+import time
+import unittest
+
+class NetnsExecuteTestCase(unittest.TestCase):
+ def setUp(self):
+ self.root_dir = tempfile.mkdtemp()
+
+ def tearDown(self):
+ shutil.rmtree(self.root_dir)
+
+if __name__ == '__main__':
+ unittest.main()
+
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import getpass
+from nepi.core.design import ExperimentDescription, FactoriesProvider
+from nepi.core.execute import ExperimentController
+from nepi.util import proxy
+import os
+import shutil
+import tempfile
+import test_util
+import time
+import unittest
+
+class NetnsIntegrationTestCase(unittest.TestCase):
+ def setUp(self):
+ self.root_dir = tempfile.mkdtemp()
+
+ def tearDown(self):
+ shutil.rmtree(self.root_dir)
+
+if __name__ == '__main__':
+ unittest.main()
+