Added unit tests for linux application
[nepi.git] / test / execution / resource.py
1 #!/usr/bin/env python
2 from neco.execution.attribute import Attribute
3 from neco.execution.ec import ExperimentController 
4 from neco.execution.resource import ResourceManager, ResourceState, clsinit
5
6 import time
7 import unittest
8
9 @clsinit
10 class MyResource(ResourceManager):
11     _rtype = "MyResource"
12
13     @classmethod
14     def _register_attributes(cls):
15         cool_attr = Attribute("my_attr", "is a really nice attribute!")
16         cls._register_attribute(cool_attr)
17
18     def __init__(self, ec, guid):
19         super(MyResource, self).__init__(ec, guid)
20
21 @clsinit
22 class AnotherResource(ResourceManager):
23     _rtype = "AnotherResource"
24
25     def __init__(self, ec, guid):
26         super(AnotherResource, self).__init__(ec, guid)
27      
28 class ResourceFactoryTestCase(unittest.TestCase):
29     def test_add_resource_factory(self):
30         from neco.execution.resource import ResourceFactory
31
32         ResourceFactory.register_type(MyResource)
33         ResourceFactory.register_type(AnotherResource)
34
35         self.assertEquals(MyResource.rtype(), "MyResource")
36         self.assertEquals(len(MyResource._attributes), 1)
37
38         self.assertEquals(ResourceManager.rtype(), "Resource")
39         self.assertEquals(len(ResourceManager._attributes), 0)
40
41         self.assertEquals(AnotherResource.rtype(), "AnotherResource")
42         self.assertEquals(len(AnotherResource._attributes), 0)
43
44         self.assertEquals(len(ResourceFactory.resource_types()), 2)
45
46 class Channel(ResourceManager):
47     _rtype = "Channel"
48
49     def __init__(self, ec, guid):
50         super(Channel, self).__init__(ec, guid)
51
52     def deploy(self):
53         time.sleep(1)
54         super(Channel, self).deploy()
55         self.logger.debug(" -------- DEPLOYED ------- ")
56        
57 class Interface(ResourceManager):
58     _rtype = "Interface"
59
60     def __init__(self, ec, guid):
61         super(Interface, self).__init__(ec, guid)
62
63     def deploy(self):
64         node = self.get_connected(Node.rtype())[0]
65         chan = self.get_connected(Channel.rtype())[0]
66
67         if node.state < ResourceState.PROVISIONED:
68             self.ec.schedule("0.5s", self.deploy)
69         elif chan.state < ResourceState.READY:
70             self.ec.schedule("0.5s", self.deploy)
71         else:
72             time.sleep(2)
73             super(Interface, self).deploy()
74             self.logger.debug(" -------- DEPLOYED ------- ")
75
76 class Node(ResourceManager):
77     _rtype = "Node"
78
79     def __init__(self, ec, guid):
80         super(Node, self).__init__(ec, guid)
81
82     def deploy(self):
83         if self.state == ResourceState.NEW:
84             self.discover()
85             self.provision()
86             self.logger.debug(" -------- PROVISIONED ------- ")
87             self.ec.schedule("3s", self.deploy)
88         elif self.state == ResourceState.PROVISIONED:
89             ifaces = self.get_connected(Interface.rtype())
90             for rm in ifaces:
91                 if rm.state < ResourceState.READY:
92                     self.ec.schedule("0.5s", self.deploy)
93                     return 
94
95             super(Node, self).deploy()
96             self.logger.debug(" -------- DEPLOYED ------- ")
97
98 class Application(ResourceManager):
99     _rtype = "Application"
100
101     def __init__(self, ec, guid):
102         super(Application, self).__init__(ec, guid)
103
104     def deploy(self):
105         node = self.get_connected(Node.rtype())[0]
106         if node.state < ResourceState.READY:
107             self.ec.schedule("0.5s", self.deploy)
108         else:
109             super(Application, self).deploy()
110             self.logger.debug(" -------- DEPLOYED ------- ")
111
112 class ResourceManagerTestCase(unittest.TestCase):
113     def test_deploy_in_order(self):
114         """
115         Test scenario: 2 applications running one on 1 node each. 
116         Nodes are connected to Interfaces which are connected
117         through a channel between them.
118
119          - Application needs to wait until Node is ready to be ready
120          - Node needs to wait until Interface is ready to be ready
121          - Interface needs to wait until Node is provisioned to be ready
122          - Interface needs to wait until Channel is ready to be ready
123          - The channel doesn't wait for any other resource to be ready
124
125         """
126         from neco.execution.resource import ResourceFactory
127         
128         ResourceFactory.register_type(Application)
129         ResourceFactory.register_type(Node)
130         ResourceFactory.register_type(Interface)
131         ResourceFactory.register_type(Channel)
132
133         ec = ExperimentController()
134
135         app1 = ec.register_resource("Application")
136         app2 = ec.register_resource("Application")
137         node1 = ec.register_resource("Node")
138         node2 = ec.register_resource("Node")
139         iface1 = ec.register_resource("Interface")
140         iface2 = ec.register_resource("Interface")
141         chan = ec.register_resource("Channel")
142
143         ec.register_connection(app1, node1)
144         ec.register_connection(app2, node2)
145         ec.register_connection(iface1, node1)
146         ec.register_connection(iface2, node2)
147         ec.register_connection(iface1, chan)
148         ec.register_connection(iface2, chan)
149
150         ec.deploy()
151
152         while not all([ ec.state(guid) == ResourceState.STARTED \
153                 for guid in [app1, app2, node1, node2, iface1, iface2, chan]]) \
154                 and not ec.finished:
155             time.sleep(0.5)
156
157         ec.shutdown()
158
159         rmapp1 = ec.get_resource(app1)
160         rmapp2 = ec.get_resource(app2)
161         rmnode1 = ec.get_resource(node1)
162         rmnode2 = ec.get_resource(node2)
163         rmiface1 = ec.get_resource(iface1)
164         rmiface2 = ec.get_resource(iface2)
165         rmchan = ec.get_resource(chan)
166
167         ## Validate deploy order
168         # - Application needs to wait until Node is ready to be ready
169         self.assertTrue(rmnode1.ready_time < rmapp1.ready_time)
170         self.assertTrue(rmnode2.ready_time < rmapp2.ready_time)
171
172          # - Node needs to wait until Interface is ready to be ready
173         self.assertTrue(rmnode1.ready_time > rmiface1.ready_time)
174         self.assertTrue(rmnode2.ready_time > rmiface2.ready_time)
175
176          # - Interface needs to wait until Node is provisioned to be ready
177         self.assertTrue(rmnode1.provision_time < rmiface1.ready_time)
178         self.assertTrue(rmnode2.provision_time < rmiface2.ready_time)
179
180          # - Interface needs to wait until Channel is ready to be ready
181         self.assertTrue(rmchan.ready_time < rmiface1.ready_time)
182         self.assertTrue(rmchan.ready_time < rmiface2.ready_time)
183
184     def test_start_with_condition(self):
185         # TODO!!!
186         pass
187     
188     def test_stop_with_condition(self):
189         # TODO!!!
190         pass
191
192     def test_set_with_condition(self):
193         # TODO!!!
194         pass
195
196
197 if __name__ == '__main__':
198     unittest.main()
199