Modified FailureManager to abort only when critical resources fail
[nepi.git] / test / execution / resource.py
index bb1de3e..e594f26 100755 (executable)
 
 
 from nepi.execution.attribute import Attribute
-from nepi.execution.ec import ExperimentController 
-from nepi.execution.resource import ResourceManager, ResourceState, clsinit
+from nepi.execution.ec import ExperimentController, FailureLevel 
+from nepi.execution.resource import ResourceManager, ResourceState, \
+        clsinit_copy, ResourceAction, failtrap
 
 import random
 import time
 import unittest
 
-@clsinit
+@clsinit_copy
 class MyResource(ResourceManager):
     _rtype = "MyResource"
 
@@ -39,30 +40,12 @@ class MyResource(ResourceManager):
     def __init__(self, ec, guid):
         super(MyResource, self).__init__(ec, guid)
 
-@clsinit
+@clsinit_copy
 class AnotherResource(ResourceManager):
     _rtype = "AnotherResource"
 
     def __init__(self, ec, guid):
         super(AnotherResource, self).__init__(ec, guid)
-     
-class ResourceFactoryTestCase(unittest.TestCase):
-    def test_add_resource_factory(self):
-        from nepi.execution.resource import ResourceFactory
-
-        ResourceFactory.register_type(MyResource)
-        ResourceFactory.register_type(AnotherResource)
-
-        self.assertEquals(MyResource.rtype(), "MyResource")
-        self.assertEquals(len(MyResource._attributes), 1)
-
-        self.assertEquals(ResourceManager.rtype(), "Resource")
-        self.assertEquals(len(ResourceManager._attributes), 0)
-
-        self.assertEquals(AnotherResource.rtype(), "AnotherResource")
-        self.assertEquals(len(AnotherResource._attributes), 0)
-
-        self.assertEquals(len(ResourceFactory.resource_types()), 2)
 
 class Channel(ResourceManager):
     _rtype = "Channel"
@@ -105,7 +88,7 @@ class Node(ResourceManager):
             self.discover()
             self.provision()
             self.logger.debug(" -------- PROVISIONED ------- ")
-            self.ec.schedule("3s", self.deploy)
+            self.ec.schedule("1s", self.deploy)
         elif self.state == ResourceState.PROVISIONED:
             ifaces = self.get_connected(Interface.rtype())
             for rm in ifaces:
@@ -127,16 +110,84 @@ class Application(ResourceManager):
         if node.state < ResourceState.READY:
             self.ec.schedule("0.5s", self.deploy)
         else:
-            time.sleep(random.random() * 5)
+            time.sleep(random.random() * 2)
             super(Application, self).deploy()
             self.logger.debug(" -------- DEPLOYED ------- ")
 
     def start(self):
         super(Application, self).start()
-        time.sleep(random.random() * 5)
+        time.sleep(random.random() * 3)
         self._state = ResourceState.FINISHED
 
+class ErrorApplication(ResourceManager):
+    _rtype = "ErrorApplication"
+
+    def __init__(self, ec, guid):
+        super(ErrorApplication, self).__init__(ec, guid)
+
+    @failtrap
+    def deploy(self):
+        node = self.get_connected(Node.rtype())[0]
+        if node.state < ResourceState.READY:
+            self.ec.schedule("0.5s", self.deploy)
+        else:
+            time.sleep(random.random() * 2)
+            raise RuntimeError, "NOT A REAL ERROR. JUST TESTING"
+
+class ResourceFactoryTestCase(unittest.TestCase):
+    def test_add_resource_factory(self):
+        from nepi.execution.resource import ResourceFactory
+
+        ResourceFactory._resource_types = dict()
+        ResourceFactory.register_type(MyResource)
+        ResourceFactory.register_type(AnotherResource)
+
+        self.assertEquals(MyResource.rtype(), "MyResource")
+        self.assertEquals(len(MyResource._attributes), 2)
+
+        self.assertEquals(ResourceManager.rtype(), "Resource")
+        self.assertEquals(len(ResourceManager._attributes), 1)
+
+        self.assertEquals(AnotherResource.rtype(), "AnotherResource")
+        self.assertEquals(len(AnotherResource._attributes), 1)
+
+        self.assertEquals(len(ResourceFactory.resource_types()), 2)
+        
+        # restore factory state for other tests
+        from nepi.execution.resource import populate_factory
+        ResourceFactory._resource_types = dict()
+        populate_factory()
+
 class ResourceManagerTestCase(unittest.TestCase):
+    def test_register_condition(self):
+        ec = ExperimentController()
+        rm = ResourceManager(ec, 15)
+
+        group = [1,3,5,7]
+        rm.register_condition(ResourceAction.START, group,
+                ResourceState.STARTED)
+
+        group = [10,8]
+        rm.register_condition(ResourceAction.START,
+                group, ResourceState.STARTED, time = "10s")
+
+        waiting_for = []
+        conditions = rm.conditions.get(ResourceAction.START)
+        for (group, state, time) in conditions:
+            waiting_for.extend(group)
+
+        self.assertEquals(waiting_for, [1, 3, 5, 7, 10, 8])
+
+        group = [1, 2, 3, 4, 6]
+        rm.unregister_condition(group)
+
+        waiting_for = []
+        conditions = rm.conditions.get(ResourceAction.START)
+        for (group, state, time) in conditions:
+            waiting_for.extend(group)
+
+        self.assertEquals(waiting_for, [5, 7, 10, 8])
+
     def test_deploy_in_order(self):
         """
         Test scenario: 2 applications running one on 1 node each. 
@@ -219,7 +270,7 @@ class ResourceManagerTestCase(unittest.TestCase):
         node = ec.register_resource("Node")
 
         apps = list()
-        for i in xrange(5000):
+        for i in xrange(1000):
             app = ec.register_resource("Application")
             ec.register_connection(app, node)
             apps.append(app)
@@ -236,15 +287,43 @@ class ResourceManagerTestCase(unittest.TestCase):
 
         ec.shutdown()
 
-    def test_start_with_condition(self):
+    def test_exception(self):
+        from nepi.execution.resource import ResourceFactory
+        
+        ResourceFactory.register_type(ErrorApplication)
+        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(10):
+            app = ec.register_resource("ErrorApplication")
+            ec.register_connection(app, node)
+            apps.append(app)
+
+
+        ec.deploy()
+
+        ec.wait_finished(apps)
+
+        ec.shutdown()
+
+        self.assertTrue(ec._fm._failure_level == FailureLevel.RM_FAILURE)
+
+
+    def ztest_start_with_condition(self):
         # TODO!!!
         pass
     
-    def test_stop_with_condition(self):
+    def ztest_stop_with_condition(self):
         # TODO!!!
         pass
 
-    def test_set_with_condition(self):
+    def ztest_set_with_condition(self):
         # TODO!!!
         pass