Added LinuxCCNPing
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Fri, 9 Aug 2013 19:23:03 +0000 (12:23 -0700)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Fri, 9 Aug 2013 19:23:03 +0000 (12:23 -0700)
src/nepi/execution/resource.py
src/nepi/resources/linux/ccn/ccnping.py [new file with mode: 0644]
src/nepi/resources/linux/ccn/ccnpingserver.py [new file with mode: 0644]
test/resources/linux/ccn/ccnping.py [new file with mode: 0644]
test/resources/linux/udptest.py

index 2d738c5..f4aa169 100644 (file)
@@ -26,6 +26,7 @@ import functools
 import logging
 import os
 import pkgutil
+import sys
 import weakref
 
 reschedule_delay = "1s"
@@ -791,7 +792,10 @@ def find_types():
         
         try:
             # Notice: Repeated calls to load_module will act as a reload of teh module
-            module = loader.load_module(modname)
+            if modname in sys.modules:
+                module = sys.modules.get(modname)
+            else:
+                module = loader.load_module(modname)
 
             for attrname in dir(module):
                 if attrname.startswith("_"):
@@ -807,6 +811,10 @@ def find_types():
 
                 if issubclass(attr, ResourceManager):
                     types.append(attr)
+
+                    if not modname in sys.modules:
+                        sys.modules[modname] = module
+
         except:
             import traceback
             import logging
diff --git a/src/nepi/resources/linux/ccn/ccnping.py b/src/nepi/resources/linux/ccn/ccnping.py
new file mode 100644 (file)
index 0000000..2e3f485
--- /dev/null
@@ -0,0 +1,96 @@
+#
+#    NEPI, a framework to manage network experiments
+#    Copyright (C) 2013 INRIA
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.resource import ResourceManager, clsinit_copy, ResourceState, \
+    reschedule_delay
+from nepi.resources.linux.ccn.ccnpingserver import LinuxCCNPingServer
+from nepi.util.timefuncs import tnow, tdiffsec
+
+import os
+
+@clsinit_copy
+class LinuxCCNPing(LinuxCCNPingServer):
+    _rtype = "LinuxCCNPing"
+
+    @classmethod
+    def _register_attributes(cls):
+        interval = Attribute("i",
+            "Set ping interval in seconds (minimum 0.10 second) ",
+            type = Types.Integer,
+            flags = Flags.ExecReadOnly)
+
+        count = Attribute("c",
+            "Total number of pings",
+            type = Types.Integer,
+            flags = Flags.ExecReadOnly)
+
+        number = Attribute("n",
+            "Set the starting number, the number is incremented by 1 after each Interest ",
+            type = Types.Integer,
+            flags = Flags.ExecReadOnly)
+        prefix = Attribute("prefix",
+            "Prefix to serve content (e.g. ccnx:/name/prefix)",
+            flags = Flags.ExecReadOnly)
+
+        cls._register_attribute(interval)
+        cls._register_attribute(count)
+        cls._register_attribute(number)
+        cls._register_attribute(prefix)
+
+    def __init__(self, ec, guid):
+        super(LinuxCCNPing, self).__init__(ec, guid)
+        self._home = "ccnping-%s" % self.guid
+
+    @property
+    def ccnpingserver(self):
+        ccnpingserver = self.get_connected(LinuxCCNPingServer.rtype())
+        if ccnpingserver: return ccnpingserver[0]
+        return None
+
+    def start(self):
+        if not self.ccnpingserver or \
+                self.ccnpingserver.state < ResourceState.STARTED:
+            self.debug("---- RESCHEDULING START----  ccnpingserver state %s " % \
+                    self.ccnpingserver.state )
+            self.ec.schedule(reschedule_delay, self.start)
+        else:
+            super(LinuxCCNPing, self).start()
+    @property
+    def _start_command(self):
+        args = []
+        args.append("ccnping")
+        args.append(self.get("prefix"))
+        if self.get("c"):
+            args.append("-c %d" % self.get("c"))
+        if self.get("n"):
+            args.append("-n %d" % self.get("n"))
+        if self.get("i"):
+            args.append("-i %d" % self.get("i"))
+
+        command = " ".join(args)
+
+        return command
+
+    def valid_connection(self, guid):
+        # TODO: Validate!
+        return True
+
diff --git a/src/nepi/resources/linux/ccn/ccnpingserver.py b/src/nepi/resources/linux/ccn/ccnpingserver.py
new file mode 100644 (file)
index 0000000..b566c78
--- /dev/null
@@ -0,0 +1,135 @@
+#
+#    NEPI, a framework to manage network experiments
+#    Copyright (C) 2013 INRIA
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.resource import ResourceManager, clsinit_copy, ResourceState, \
+    reschedule_delay
+from nepi.resources.linux.ccn.ccnapplication import LinuxCCNApplication
+from nepi.util.timefuncs import tnow, tdiffsec
+
+import os
+
+@clsinit_copy
+class LinuxCCNPingServer(LinuxCCNApplication):
+    _rtype = "LinuxCCNPingServer"
+
+    @classmethod
+    def _register_attributes(cls):
+        daemon = Attribute("d",
+            "Run ccnping server as a daemon in background",
+            type = Types.Bool,
+            default = False,
+            flags = Flags.ExecReadOnly)
+
+        freshness = Attribute("x",
+            "Set FreshnessSeconds",
+            type = Types.Integer,
+            flags = Flags.ExecReadOnly)
+
+        prefix = Attribute("prefix",
+            "Prefix to serve content (e.g. ccnx:/name/prefix)",
+            flags = Flags.ExecReadOnly)
+
+        cls._register_attribute(daemon)
+        cls._register_attribute(freshness)
+        cls._register_attribute(prefix)
+
+    def __init__(self, ec, guid):
+        super(LinuxCCNPingServer, self).__init__(ec, guid)
+        self._home = "ccnping-serv-%s" % self.guid
+
+    def deploy(self):
+        if not self.get("command"):
+            self.set("command", self._start_command)
+
+        if not self.get("env"):
+            self.set("env", self._environment)
+
+        if not self.get("depends"):
+            self.set("depends", self._dependencies)
+
+        if not self.get("build"):
+            self.set("build", self._build)
+
+        if not self.get("install"):
+            self.set("install", self._install)
+
+        super(LinuxCCNPingServer, self).deploy()
+
+    @property
+    def _start_command(self):
+        args = []
+        args.append("ccnpingserver")
+        args.append(self.get("prefix"))
+        if self.get("d") == True:
+            args.append("-d")
+        if self.get("x"):
+            args.append("-x %d" % self.get("x"))
+
+        command = " ".join(args)
+
+        return command
+
+    @property
+    def _dependencies(self):
+        return "git"
+
+    @property
+    def _build(self):
+        return (
+            # Evaluate if ccnx binaries are already installed
+            " ( "
+                " test -f ${BIN}/ccnping && "
+                " echo 'binaries found, nothing to do' "
+            " ) || ( "
+            # If not, untar and build
+                " ( "
+                    " git clone git://github.com/NDN-Routing/ccnping ${SRC}/ccnping "
+                 " ) && "
+                    # build
+                    "cd ${SRC}/ccnping && "
+                    " ( "
+                    " ./configure LDFLAGS=-L${SRC}/ccnx-0.7.2/lib CFLAGS=-I${SRC}/ccnx-0.7.2/include "
+                    " --prefix=${BIN}/ccnping && make "
+                    " ) "
+             " )") 
+
+    @property
+    def _install(self):
+        return (
+            # Evaluate if ccnx binaries are already installed
+            " ( "
+                " test -f ${BIN}/ccnping && "
+                " echo 'binaries found, nothing to do' "
+            " ) || ( "
+            # If not, install
+                "  mkdir -p ${BIN}/ccnping && "
+                "  mv ${SRC}/ccnping/ccnping ${BIN}/ccnping/ && "
+                "  mv ${SRC}/ccnping/ccnpingserver ${BIN}/ccnping/ "
+            " )"
+            )
+
+    @property
+    def _environment(self):
+        return "%s:%s" % (self.ccnd.path, "${BIN}/ccnping")
+       
+    def valid_connection(self, guid):
+        # TODO: Validate!
+        return True
+
diff --git a/test/resources/linux/ccn/ccnping.py b/test/resources/linux/ccn/ccnping.py
new file mode 100644 (file)
index 0000000..a740128
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+#
+#    NEPI, a framework to manage network experiments
+#    Copyright (C) 2013 INRIA
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.ec import ExperimentController 
+from test_utils import skipIfAnyNotAlive
+
+import os
+import time
+import tempfile
+import unittest
+
+class LinuxCCNPingTestCase(unittest.TestCase):
+    def setUp(self):
+        self.fedora_host = "nepi2.pl.sophia.inria.fr"
+        self.fedora_user = "inria_nepi"
+
+        self.ubuntu_host = "roseval.pl.sophia.inria.fr"
+        self.ubuntu_user = "alina"
+        
+        self.target = "nepi5.pl.sophia.inria.fr"
+
+    @skipIfAnyNotAlive
+    def t_count(self, user1, host1, user2, host2):
+
+        ec = ExperimentController(exp_id = "test-ccn-ping-count")
+        
+        node1 = ec.register_resource("LinuxNode")
+        ec.set(node1, "hostname", host1)
+        ec.set(node1, "username", user1)
+        ec.set(node1, "cleanHome", True)
+        ec.set(node1, "cleanProcesses", True)
+
+        ccnd1 = ec.register_resource("LinuxCCND")
+        ec.register_connection(ccnd1, node1)
+
+        entry1 = ec.register_resource("LinuxFIBEntry")
+        ec.set(entry1, "host", host2)
+        ec.register_connection(entry1, ccnd1)
+        server = ec.register_resource("LinuxCCNPingServer")
+        ec.set(server, "prefix", "ccnx:/test")
+        ec.register_connection(server, ccnd1)
+        node2 = ec.register_resource("LinuxNode")
+        ec.set(node2, "hostname", host2)
+        ec.set(node2, "username", user2)
+        ec.set(node2, "cleanHome", True)
+        ec.set(node2, "cleanProcesses", True)
+
+        ccnd2 = ec.register_resource("LinuxCCND")
+        ec.register_connection(ccnd2, node2)
+
+        entry2 = ec.register_resource("LinuxFIBEntry")
+        ec.set(entry2, "host", host1)
+        ec.register_connection(entry2, ccnd2)
+        client = ec.register_resource("LinuxCCNPing")
+        ec.set(client, "c", 15)
+        ec.set(client, "prefix", "ccnx:/test")
+        ec.register_connection(client, ccnd2)
+        ec.register_connection(client, server)
+
+        ec.deploy()
+
+        ec.wait_finished(client)
+
+        stdout = ec.trace(client, "stdout")
+        expected = "15 Interests transmitted"
+        self.assertTrue(stdout.find(expected) > -1)
+
+        ec.shutdown()
+
+    def test_count_fedora(self):
+        self.t_count(self.fedora_user, self.fedora_host, self.fedora_user, 
+                self.target)
+
+    def test_count_ubuntu(self):
+        self.t_count(self.ubuntu_user, self.ubuntu_host, self.fedora_user,
+                self.target)
+
+if __name__ == '__main__':
+    unittest.main()
+
index c4f697a..37bfc88 100755 (executable)
@@ -39,7 +39,7 @@ class LinuxUdpTestTestCase(unittest.TestCase):
     @skipIfAnyNotAlive
     def t_rtt(self, user1, host1, user2, host2):
 
-        ec = ExperimentController(exp_id = "test-usptest-rtt")
+        ec = ExperimentController(exp_id = "test-udptest-rtt")
         
         node1 = ec.register_resource("LinuxNode")
         ec.set(node1, "hostname", host1)
@@ -75,7 +75,7 @@ class LinuxUdpTestTestCase(unittest.TestCase):
         self.t_rtt(self.fedora_user, self.fedora_host, self.fedora_user, 
                 self.target)
 
-    def ztest_rtt_ubuntu(self):
+    def test_rtt_ubuntu(self):
         self.t_rtt(self.ubuntu_user, self.ubuntu_host, self.fedora_user,
                 self.target)