popolate_factory no longer requires to be invoked explicitly by the user
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Wed, 10 Jul 2013 00:51:22 +0000 (17:51 -0700)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Wed, 10 Jul 2013 00:51:22 +0000 (17:51 -0700)
25 files changed:
Makefile
examples/linux/ccn/ccncat_2_nodes.py
examples/linux/ccn/ccncat_extended_ring_topo.py
examples/linux/scalability.py
examples/linux/transfer/file_transfer.py
examples/omf/automated_vlc_experiment_plexus.py
src/nepi/__init__.py
src/nepi/execution/ec.py
src/nepi/execution/resource.py
src/nepi/resources/all/collector.py
src/nepi/resources/linux/application.py
src/nepi/resources/linux/ccn/ccnapplication.py
src/nepi/resources/linux/ccn/ccncontent.py
src/nepi/resources/linux/ccn/ccnr.py
src/nepi/resources/linux/ccn/fibentry.py
src/nepi/resources/linux/interface.py
src/nepi/resources/linux/node.py
src/nepi/resources/omf/application.py
src/nepi/resources/omf/interface.py
src/nepi/resources/planetlab/tap.py
test/execution/resource.py
test/lib/test_utils.py
test/resources/linux/application.py
test/resources/planetlab/tap.py
test/resources/planetlab/tun.py [changed mode: 0644->0755]

index 1a3420c..c2fb951 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -30,12 +30,12 @@ install: all
 test: all
        retval=0; \
               for i in `find "$(TESTDIR)" -iname '*.py' -perm -u+x -type f`; do \
-              @echo $$i; \
+              echo $$i; \
               PYTHONPATH="$(PYPATH)" $$i -v || retval=$$?; \
               done; exit $$retval
 
 test-one: all
-       @echo $(file) $(case)
+       echo $(file) $(case)
        PYTHONPATH="$(PYPATH)" python $(file) $(case)
 
 coverage: all
index 60d4362..2e0af0e 100755 (executable)
@@ -38,8 +38,7 @@
 #           
 
 from nepi.execution.ec import ExperimentController, ECState 
-from nepi.execution.resource import ResourceState, ResourceAction, \
-        populate_factory
+from nepi.execution.resource import ResourceState, ResourceAction 
 from nepi.resources.linux.node import OSType
 
 from optparse import OptionParser, SUPPRESS_HELP
@@ -188,9 +187,6 @@ if __name__ == '__main__':
     ( pl_host, pl_user, linux_host, linux_user, movie, exp_id, pl_ssh_key 
             ) = get_options()
 
-    # Search for available RMs
-    populate_factory()
-    
     # Create the ExperimentController instance
     ec = ExperimentController(exp_id = exp_id)
 
index 2181563..4bf5dc8 100755 (executable)
@@ -39,8 +39,7 @@
 #
 
 from nepi.execution.ec import ExperimentController, ECState 
-from nepi.execution.resource import ResourceState, ResourceAction, \
-        populate_factory
+from nepi.execution.resource import ResourceState, ResourceAction 
 from nepi.execution.trace import TraceAttr
 
 import subprocess
@@ -137,9 +136,6 @@ if __name__ == '__main__':
     
     ( pl_user, movie, exp_id, pl_ssh_key, results_dir ) = get_options()
 
-    # Search for available RMs
-    populate_factory()
-    
     ec = ExperimentController(exp_id = exp_id)
     
     # hosts in Europe
index 0cd06ec..0972961 100755 (executable)
@@ -19,8 +19,7 @@
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 
 from nepi.execution.ec import ExperimentController, ECState 
-from nepi.execution.resource import ResourceState, ResourceAction, \
-        populate_factory
+from nepi.execution.resource import ResourceState, ResourceAction
 
 from optparse import OptionParser, SUPPRESS_HELP
 
@@ -58,9 +57,6 @@ def get_options():
 if __name__ == '__main__':
     ( pl_slice, exp_id ) = get_options()
 
-    # Search for available RMs
-    populate_factory()
-    
     apps = []
   
     hostnames = [
index b495aa4..3296b07 100755 (executable)
@@ -19,8 +19,7 @@
 # Author: Lucia Guevgeozian <lucia.guevgeozian_odizzio@inria.fr>
 
 from nepi.execution.ec import ExperimentController
-from nepi.execution.resource import ResourceAction, ResourceState, populate_factory
-
+from nepi.execution.resource import ResourceAction, ResourceState
 
 def add_node(ec, host, user):
     node = ec.register_resource("LinuxNode")
@@ -47,8 +46,6 @@ def add_app(ec, command, node, sudo=None, video=None, depends=None, forward_x11=
     ec.register_connection(app, node)
     return app
 
-populate_factory()
-
 exp_id = "transfer_file"
 
 # Create the EC
index 08adde8..e1e99fa 100755 (executable)
@@ -18,7 +18,7 @@
 #
 # Author: Julien Tribino <julien.tribino@inria.fr>
 
-from nepi.execution.resource import ResourceFactory, ResourceAction, ResourceState, populate_factory
+from nepi.execution.resource import ResourceFactory, ResourceAction, ResourceState
 from nepi.execution.ec import ExperimentController
 
 from nepi.resources.omf.node import OMFNode
@@ -34,9 +34,6 @@ logging.basicConfig()
 # Create the EC
 ec = ExperimentController()
 
-# Register the different RM that will be used
-populate_factory()
-
 # Create and Configure the Nodes
 node1 = ec.register_resource("OMFNode")
 ec.set(node1, 'hostname', 'omf.plexus.wlab17')
index 4cf488f..1d1359f 100644 (file)
@@ -49,3 +49,10 @@ else:
     # components
     logging.basicConfig(format = FORMAT, level = LOGLEVEL)
 
+
+# Add RMs to ResourceFactory. Use NEPI_SEARCH_PATH to 
+# override the default path to search for RMs
+from nepi.execution.resource import populate_factory
+populate_factory()
+
+
index 0a90dec..abcb88d 100644 (file)
@@ -352,14 +352,23 @@ class ExperimentController(object):
             rm = self.get_resource(guid1)
             rm.register_condition(action, group2, state, time)
 
-    def register_trace(self, guid, name):
+    def enable_trace(self, guid, name):
         """ Enable trace
 
         :param name: Name of the trace
         :type name: str
         """
         rm = self.get_resource(guid)
-        rm.register_trace(name)
+        rm.enable_trace(name)
+
+    def trace_enabled(self, guid, name):
+        """ Returns True if trace is enabled
+
+        :param name: Name of the trace
+        :type name: str
+        """
+        rm = self.get_resource(guid)
+        return rm.trace_enabled(name)
 
     def trace(self, guid, name, attr = TraceAttr.ALL, block = 512, offset = 0):
         """ Get information on collected trace
index 80e4a3e..0eebc6f 100644 (file)
@@ -376,7 +376,7 @@ class ResourceManager(Logger):
         attr = self._attrs[name]
         return attr.value
 
-    def register_trace(self, name):
+    def enable_trace(self, name):
         """ Explicitly enable trace generation
 
         :param name: Name of the trace
@@ -384,7 +384,16 @@ class ResourceManager(Logger):
         """
         trace = self._trcs[name]
         trace.enabled = True
+    
+    def trace_enabled(self, name):
+        """Returns True if trace is enables 
 
+        :param name: Name of the trace
+        :type name: str
+        """
+        trace = self._trcs[name]
+        return trace.enabled
     def trace(self, name, attr = TraceAttr.ALL, block = 512, offset = 0):
         """ Get information on collected trace
 
@@ -467,7 +476,7 @@ class ResourceManager(Logger):
                     newgrp.difference_update(intsec)
                     conditions[idx] = (newgrp, state, time)
                  
-    def get_connected(self, rclass = None):
+    def get_connected(self, rtype = None):
         """ Returns the list of RM with the type 'rtype'
 
         :param rtype: Type of the RM we look for
@@ -475,9 +484,10 @@ class ResourceManager(Logger):
         :return: list of guid
         """
         connected = []
+        rclass = ResourceFactory.get_resource_type(rtype)
         for guid in self.connections:
             rm = self.ec.get_resource(guid)
-            if not rclass or isinstance(rm, rclass):
+            if not rtype or isinstance(rm, rclass):
                 connected.append(rm)
         return connected
 
@@ -709,6 +719,11 @@ class ResourceFactory(object):
         """Return the type of the Class"""
         return cls._resource_types
 
+    @classmethod
+    def get_resource_type(cls, rtype):
+        """Return the type of the Class"""
+        return cls._resource_types.get(rtype)
+
     @classmethod
     def register_type(cls, rclass):
         """Register a new Ressource Manager"""
@@ -723,13 +738,14 @@ class ResourceFactory(object):
 def populate_factory():
     """Register all the possible RM that exists in the current version of Nepi.
     """
-    for rclass in find_types():
-        ResourceFactory.register_type(rclass)
+    # Once the factory is populated, don't repopulate
+    if not ResourceFactory.resource_types():
+        for rclass in find_types():
+            ResourceFactory.register_type(rclass)
 
 def find_types():
     """Look into the different folders to find all the 
     availables Resources Managers
-
     """
     search_path = os.environ.get("NEPI_SEARCH_PATH", "")
     search_path = set(search_path.split(" "))
@@ -741,10 +757,15 @@ def find_types():
 
     types = []
 
-    for importer, modname, ispkg in pkgutil.walk_packages(search_path):
+    for importer, modname, ispkg in pkgutil.walk_packages(search_path, 
+            prefix = "nepi.resources."):
+
         loader = importer.find_module(modname)
+        
         try:
-            module = loader.load_module(loader.fullname)
+            # Notice: Repeated calls to load_module will act as a reload of teh module
+            module = loader.load_module(modname)
+
             for attrname in dir(module):
                 if attrname.startswith("_"):
                     continue
index 407d0bb..2dfd200 100644 (file)
@@ -50,9 +50,12 @@ class Collector(ResourceManager):
         store_dir = Attribute("storeDir", "Path to local directory to store trace results", 
                 default = tempfile.gettempdir(),
                 flags = Flags.ExecReadOnly)
+        sub_dir = Attribute("subDir", "Sub directory to collect traces into", 
+                flags = Flags.ExecReadOnly)
 
         cls._register_attribute(trace_name)
         cls._register_attribute(store_dir)
+        cls._register_attribute(sub_dir)
 
     def __init__(self, ec, guid):
         super(Collector, self).__init__(ec, guid)
@@ -73,6 +76,10 @@ class Collector(ResourceManager):
 
         store_dir = self.get("storeDir")
         self._store_path = os.path.join(store_dir, self.ec.exp_id, self.ec.run_id)
+
+        subdir = self.get("subDir")
+        if subdir:
+            self._store_path = os.path.join(self._store_path, subdir)
         
         msg = "Creating local directory at %s to store %s traces " % (
             store_dir, trace_name)
index 9111cc1..117392d 100644 (file)
@@ -191,7 +191,7 @@ class LinuxApplication(ResourceManager):
 
     @property
     def node(self):
-        node = self.get_connected(LinuxNode)
+        node = self.get_connected(LinuxNode.rtype())
         if node: return node[0]
         return None
 
index 5e4a832..8a09122 100644 (file)
@@ -35,7 +35,7 @@ class LinuxCCNApplication(LinuxApplication):
 
     @property
     def ccnd(self):
-        ccnd = self.get_connected(LinuxCCND)
+        ccnd = self.get_connected(LinuxCCND.rtype())
         if ccnd: return ccnd[0]
         return None
 
index e72d6a9..febcefc 100644 (file)
@@ -49,7 +49,7 @@ class LinuxCCNContent(LinuxApplication):
         
     @property
     def ccnr(self):
-        ccnr = self.get_connected(LinuxCCNR)
+        ccnr = self.get_connected(LinuxCCNR.rtype())
         if ccnr: return ccnr[0]
         return None
 
index f0ca21b..7ed260c 100644 (file)
@@ -185,7 +185,7 @@ class LinuxCCNR(LinuxApplication):
 
     @property
     def ccnd(self):
-        ccnd = self.get_connected(LinuxCCND)
+        ccnd = self.get_connected(LinuxCCND.rtype())
         if ccnd: return ccnd[0]
         return None
 
index 46bfae1..3c82a03 100644 (file)
@@ -64,13 +64,19 @@ class LinuxFIBEntry(LinuxApplication):
         cls._register_attribute(host)
         cls._register_attribute(port)
 
+    @classmethod
+    def _register_traces(cls):
+        ping = Trace("ping", "Continuous ping to the peer end")
+
+        cls._register_trace(ping)
+
     def __init__(self, ec, guid):
         super(LinuxFIBEntry, self).__init__(ec, guid)
         self._home = "fib-%s" % self.guid
 
     @property
     def ccnd(self):
-        ccnd = self.get_connected(LinuxCCND)
+        ccnd = self.get_connected(LinuxCCND.rtype())
         if ccnd: return ccnd[0]
         return None
 
@@ -98,6 +104,7 @@ class LinuxFIBEntry(LinuxApplication):
 
                 self.discover()
                 self.provision()
+                self.configure()
             except:
                 self.fail()
                 raise
@@ -127,6 +134,32 @@ class LinuxFIBEntry(LinuxApplication):
                 self.error(msg, out, err)
                 raise RuntimeError, msg
 
+    def configure(self):
+        if not self.trace_enabled("ping"):
+            return
+
+        command = """ping %s""" % self.get("host")
+        (out, err), proc = self.node.run(command, self.run_home, 
+            stdout = "ping",
+            stderr = "ping_stderr",
+            pidfile = "ping_pidfile")
+
+        # Wait for pid file to be generated
+        pid, ppid = self.node.wait_pid(self.run_home, "ping_pidfile")
+
+        # If the process is not running, check for error information
+        # on the remote machine
+        if not pid or not ppid:
+            (out, err), proc = self.node.check_errors(self.run_home,
+                    stderr = "ping_pidfile") 
+
+            # Out is what was written in the stderr file
+            if err:
+                self.fail()
+                msg = " Failed to deploy ping trace command '%s' " % command
+                self.error(msg, out, err)
+                raise RuntimeError, msg
     def start(self):
         if self._state in [ResourceState.READY, ResourceState.STARTED]:
             command = self.get("command")
@@ -153,6 +186,11 @@ class LinuxFIBEntry(LinuxApplication):
             if proc.poll():
                 pass
 
+            # now stop the ping trace
+            if self.trace_enabled("ping"):
+               pid, ppid = self.node.wait_pid(self.run_home, "ping_pidfile")
+               (out, err), proc = self.node.kill(pid, ppid)
+
             self._stop_time = tnow()
             self._state = ResourceState.STOPPED
 
index f0497e8..f5f7025 100644 (file)
@@ -90,13 +90,13 @@ class LinuxInterface(ResourceManager):
 
     @property
     def node(self):
-        node = self.get_connected(LinuxNode)
+        node = self.get_connected(LinuxNode.rtype())
         if node: return node[0]
         return None
 
     @property
     def channel(self):
-        chan = self.get_connected(LinuxChannel)
+        chan = self.get_connected(LinuxChannel.rtype())
         if chan: return chan[0]
         return None
 
index 0410b16..6157b71 100644 (file)
@@ -336,7 +336,7 @@ class LinuxNode(ResourceManager):
         # Node needs to wait until all associated interfaces are 
         # ready before it can finalize deployment
         from nepi.resources.linux.interface import LinuxInterface
-        ifaces = self.get_connected(LinuxInterface)
+        ifaces = self.get_connected(LinuxInterface.rtype())
         for iface in ifaces:
             if iface.state < ResourceState.READY:
                 self.ec.schedule(reschedule_delay, self.deploy)
index e57b374..ba2fddd 100644 (file)
@@ -135,7 +135,7 @@ class OMFApplication(ResourceManager):
                 self.get('appid') + " : " + self.get('path') + " : " + \
                 self.get('args') + " : " + self.get('env')
             self.info(msg)
-            rm_list = self.get_connected(OMFNode)
+            rm_list = self.get_connected(OMFNode.rtype())
             try:
                 for rm_node in rm_list:
                     if rm_node.get('hostname') :
index 3151362..5d2c7fb 100644 (file)
@@ -118,7 +118,7 @@ class OMFWifiInterface(ResourceManager):
             self.debug(" " + self.rtype() + " ( Guid : " + str(self._guid) +") : " + \
                 self.get('mode') + " : " + self.get('type') + " : " + \
                 self.get('essid') + " : " + self.get('ip'))
-            rm_list = self.get_connected(OMFNode) 
+            rm_list = self.get_connected(OMFNode.rtype()
             for rm_node in rm_list:
                 if rm_node.state < ResourceState.READY:
                     self.ec.schedule(reschedule_delay, self.deploy)
index a60961f..7d8cd3e 100644 (file)
@@ -86,7 +86,7 @@ class PlanetlabTap(LinuxApplication):
 
     @property
     def node(self):
-        node = self.get_connected(PlanetlabNode)
+        node = self.get_connected(PlanetlabNode.rtype())
         if node: return node[0]
         return None
 
index 5db230a..365ca08 100755 (executable)
@@ -66,8 +66,8 @@ class Interface(ResourceManager):
         super(Interface, self).__init__(ec, guid)
 
     def deploy(self):
-        node = self.get_connected(Node)[0]
-        chan = self.get_connected(Channel)[0]
+        node = self.get_connected(Node.rtype())[0]
+        chan = self.get_connected(Channel.rtype())[0]
 
         if node.state < ResourceState.PROVISIONED:
             self.ec.schedule("0.5s", self.deploy)
@@ -91,7 +91,7 @@ class Node(ResourceManager):
             self.logger.debug(" -------- PROVISIONED ------- ")
             self.ec.schedule("3s", self.deploy)
         elif self.state == ResourceState.PROVISIONED:
-            ifaces = self.get_connected(Interface)
+            ifaces = self.get_connected(Interface.rtype())
             for rm in ifaces:
                 if rm.state < ResourceState.READY:
                     self.ec.schedule("0.5s", self.deploy)
@@ -107,7 +107,7 @@ class Application(ResourceManager):
         super(Application, self).__init__(ec, guid)
 
     def deploy(self):
-        node = self.get_connected(Node)[0]
+        node = self.get_connected(Node.rtype())[0]
         if node.state < ResourceState.READY:
             self.ec.schedule("0.5s", self.deploy)
         else:
index 414b3f3..d26c9a8 100644 (file)
@@ -17,7 +17,6 @@
 #
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 
-
 from nepi.resources.linux.node import LinuxNode
 
 import os
index 11d5758..6b02d20 100755 (executable)
 #
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 
-
 from nepi.execution.ec import ExperimentController 
 from nepi.execution.resource import ResourceState, ResourceAction
 from nepi.execution.trace import TraceAttr
-from nepi.resources.linux.node import LinuxNode
-from nepi.resources.linux.application import LinuxApplication
 
 from test_utils import skipIfNotAlive, skipInteractive
 
@@ -44,10 +41,6 @@ class LinuxApplicationTestCase(unittest.TestCase):
 
     @skipIfNotAlive
     def t_stdout(self, host, user):
-        from nepi.execution.resource import ResourceFactory
-        
-        ResourceFactory.register_type(LinuxNode)
-        ResourceFactory.register_type(LinuxApplication)
 
         ec = ExperimentController(exp_id = "test-stdout")
         
@@ -76,10 +69,6 @@ class LinuxApplicationTestCase(unittest.TestCase):
 
     @skipIfNotAlive
     def t_ping(self, host, user):
-        from nepi.execution.resource import ResourceFactory
-        
-        ResourceFactory.register_type(LinuxNode)
-        ResourceFactory.register_type(LinuxApplication)
 
         ec = ExperimentController(exp_id = "test-ping")
         
@@ -118,10 +107,6 @@ class LinuxApplicationTestCase(unittest.TestCase):
 
     @skipIfNotAlive
     def t_code(self, host, user):
-        from nepi.execution.resource import ResourceFactory
-        
-        ResourceFactory.register_type(LinuxNode)
-        ResourceFactory.register_type(LinuxApplication)
 
         ec = ExperimentController(exp_id = "tests-code")
         
@@ -161,10 +146,6 @@ main (void)
 
     @skipIfNotAlive
     def t_concurrency(self, host, user):
-        from nepi.execution.resource import ResourceFactory
-        
-        ResourceFactory.register_type(LinuxNode)
-        ResourceFactory.register_type(LinuxApplication)
 
         ec = ExperimentController(exp_id="test-concurrency")
         
@@ -209,10 +190,6 @@ main (void)
 
     @skipIfNotAlive
     def t_condition(self, host, user, depends):
-        from nepi.execution.resource import ResourceFactory
-        
-        ResourceFactory.register_type(LinuxNode)
-        ResourceFactory.register_type(LinuxApplication)
 
         ec = ExperimentController(exp_id="test-condition")
         
@@ -252,10 +229,6 @@ main (void)
 
     @skipIfNotAlive
     def t_http_sources(self, host, user):
-        from nepi.execution.resource import ResourceFactory
-        
-        ResourceFactory.register_type(LinuxNode)
-        ResourceFactory.register_type(LinuxApplication)
 
         ec = ExperimentController(exp_id="test-http-sources")
         
@@ -291,10 +264,6 @@ main (void)
 
     @skipIfNotAlive
     def t_xterm(self, host, user):
-        from nepi.execution.resource import ResourceFactory
-        
-        ResourceFactory.register_type(LinuxNode)
-        ResourceFactory.register_type(LinuxApplication)
 
         ec = ExperimentController(exp_id="test-xterm")
         
@@ -361,7 +330,6 @@ main (void)
         self.t_xterm(self.ubuntu_host, self.ubuntu_user)
 
 
-
 if __name__ == '__main__':
     unittest.main()
 
index 091babe..c945ae2 100755 (executable)
@@ -19,9 +19,6 @@
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 
 from nepi.execution.ec import ExperimentController 
-from nepi.resources.planetlab.node import PlanetlabNode
-from nepi.resources.planetlab.tap import PlanetlabTap
-from nepi.resources.linux.application import LinuxApplication
 
 from test_utils import skipIfNotAlive, skipInteractive
 
@@ -36,11 +33,6 @@ class PlanetlabTapTestCase(unittest.TestCase):
 
     @skipIfNotAlive
     def t_tap_create(self, host, user):
-        from nepi.execution.resource import ResourceFactory
-        
-        ResourceFactory.register_type(PlanetlabNode)
-        ResourceFactory.register_type(PlanetlabTap)
-        ResourceFactory.register_type(LinuxApplication)
 
         ec = ExperimentController(exp_id = "test-tap-create")
         
old mode 100644 (file)
new mode 100755 (executable)
index 392f2e9..3d650d6
@@ -19,9 +19,6 @@
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 
 from nepi.execution.ec import ExperimentController 
-from nepi.resources.planetlab.node import PlanetlabNode
-from nepi.resources.planetlab.tun import PlanetlabTun
-from nepi.resources.linux.application import LinuxApplication
 
 from test_utils import skipIfNotAlive, skipInteractive
 
@@ -36,11 +33,6 @@ class PlanetlabTunTestCase(unittest.TestCase):
 
     @skipIfNotAlive
     def t_tun_create(self, host, user):
-        from nepi.execution.resource import ResourceFactory
-        
-        ResourceFactory.register_type(PlanetlabNode)
-        ResourceFactory.register_type(PlanetlabTun)
-        ResourceFactory.register_type(LinuxApplication)
 
         ec = ExperimentController(exp_id = "test-un-create")