Improved LinuxApplication behavior
[nepi.git] / test / execution / resource.py
index d90b137..7122b92 100755 (executable)
@@ -1,8 +1,29 @@
 #!/usr/bin/env python
-from neco.execution.attribute import Attribute
-from neco.execution.ec import ExperimentController 
-from neco.execution.resource import ResourceManager, ResourceState, clsinit
-
+#
+#    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
+from nepi.execution.ec import ExperimentController 
+from nepi.execution.resource import ResourceManager, ResourceState, clsinit
+
+import random
 import time
 import unittest
 
@@ -27,7 +48,7 @@ class AnotherResource(ResourceManager):
      
 class ResourceFactoryTestCase(unittest.TestCase):
     def test_add_resource_factory(self):
-        from neco.execution.resource import ResourceFactory
+        from nepi.execution.resource import ResourceFactory
 
         ResourceFactory.register_type(MyResource)
         ResourceFactory.register_type(AnotherResource)
@@ -43,14 +64,6 @@ class ResourceFactoryTestCase(unittest.TestCase):
 
         self.assertEquals(len(ResourceFactory.resource_types()), 2)
 
-def get_connected(connections, rtype, ec):
-    connected = []
-    for guid in connections:
-        rm = ec.get_resource(guid)
-        if rm.rtype() == rtype:
-            connected.append(rm)
-    return connected
-
 class Channel(ResourceManager):
     _rtype = "Channel"
 
@@ -69,8 +82,8 @@ class Interface(ResourceManager):
         super(Interface, self).__init__(ec, guid)
 
     def deploy(self):
-        node = get_connected(self.connections, Node.rtype(), self.ec)[0]
-        chan = get_connected(self.connections, Channel.rtype(), self.ec)[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)
@@ -94,7 +107,7 @@ class Node(ResourceManager):
             self.logger.debug(" -------- PROVISIONED ------- ")
             self.ec.schedule("3s", self.deploy)
         elif self.state == ResourceState.PROVISIONED:
-            ifaces = get_connected(self.connections, Interface.rtype(), self.ec)
+            ifaces = self.get_connected(Interface.rtype())
             for rm in ifaces:
                 if rm.state < ResourceState.READY:
                     self.ec.schedule("0.5s", self.deploy)
@@ -110,13 +123,19 @@ class Application(ResourceManager):
         super(Application, self).__init__(ec, guid)
 
     def deploy(self):
-        node = get_connected(self.connections, Node.rtype(), self.ec)[0]
+        node = self.get_connected(Node.rtype())[0]
         if node.state < ResourceState.READY:
             self.ec.schedule("0.5s", self.deploy)
         else:
+            time.sleep(random.random() * 5)
             super(Application, self).deploy()
             self.logger.debug(" -------- DEPLOYED ------- ")
 
+    def start(self):
+        super(Application, self).start()
+        time.sleep(random.random() * 5)
+        self._state = ResourceState.FINISHED
+
 class ResourceManagerTestCase(unittest.TestCase):
     def test_deploy_in_order(self):
         """
@@ -131,7 +150,7 @@ class ResourceManagerTestCase(unittest.TestCase):
          - The channel doesn't wait for any other resource to be ready
 
         """
-        from neco.execution.resource import ResourceFactory
+        from nepi.execution.resource import ResourceFactory
         
         ResourceFactory.register_type(Application)
         ResourceFactory.register_type(Node)
@@ -155,15 +174,12 @@ class ResourceManagerTestCase(unittest.TestCase):
         ec.register_connection(iface1, chan)
         ec.register_connection(iface2, chan)
 
-        try:
-            ec.deploy()
+        ec.deploy()
 
-            while not all([ ec.state(guid) == ResourceState.STARTED \
-                    for guid in [app1, app2, node1, node2, iface1, iface2, chan]]):
-                time.sleep(0.5)
+        guids = [app1, app2]
+        ec.wait_finished(guids)
 
-        finally:
-            ec.shutdown()
+        ec.shutdown()
 
         rmapp1 = ec.get_resource(app1)
         rmapp2 = ec.get_resource(app2)
@@ -190,6 +206,36 @@ class ResourceManagerTestCase(unittest.TestCase):
         self.assertTrue(rmchan.ready_time < rmiface1.ready_time)
         self.assertTrue(rmchan.ready_time < rmiface2.ready_time)
 
+    def test_concurrency(self):
+        from nepi.execution.resource import ResourceFactory
+        
+        ResourceFactory.register_type(Application)
+        ResourceFactory.register_type(Node)
+        ResourceFactory.register_type(Interface)
+        ResourceFactory.register_type(Channel)
+
+        ec = ExperimentController()
+
+        node = ec.register_resource("Node")
+
+        apps = list()
+        for i in xrange(1000):
+            app = ec.register_resource("Application")
+            ec.register_connection(app, node)
+            apps.append(app)
+
+        ec.deploy()
+
+        ec.wait_finished(apps)
+        
+        self.assertTrue(ec.state(node) == ResourceState.STARTED)
+        self.assertTrue(
+               all([ec.state(guid) == ResourceState.FINISHED \
+                for guid in apps])
+                )
+
+        ec.shutdown()
+
     def test_start_with_condition(self):
         # TODO!!!
         pass