3 # NEPI, a framework to manage network experiments
4 # Copyright (C) 2013 INRIA
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
22 from nepi.execution.attribute import Attribute
23 from nepi.execution.ec import ExperimentController
24 from nepi.execution.resource import ResourceManager, ResourceState, clsinit
31 class MyResource(ResourceManager):
35 def _register_attributes(cls):
36 cool_attr = Attribute("my_attr", "is a really nice attribute!")
37 cls._register_attribute(cool_attr)
39 def __init__(self, ec, guid):
40 super(MyResource, self).__init__(ec, guid)
43 class AnotherResource(ResourceManager):
44 _rtype = "AnotherResource"
46 def __init__(self, ec, guid):
47 super(AnotherResource, self).__init__(ec, guid)
49 class ResourceFactoryTestCase(unittest.TestCase):
50 def test_add_resource_factory(self):
51 from nepi.execution.resource import ResourceFactory
53 ResourceFactory.register_type(MyResource)
54 ResourceFactory.register_type(AnotherResource)
56 self.assertEquals(MyResource.rtype(), "MyResource")
57 self.assertEquals(len(MyResource._attributes), 1)
59 self.assertEquals(ResourceManager.rtype(), "Resource")
60 self.assertEquals(len(ResourceManager._attributes), 0)
62 self.assertEquals(AnotherResource.rtype(), "AnotherResource")
63 self.assertEquals(len(AnotherResource._attributes), 0)
65 self.assertEquals(len(ResourceFactory.resource_types()), 2)
67 class Channel(ResourceManager):
70 def __init__(self, ec, guid):
71 super(Channel, self).__init__(ec, guid)
75 super(Channel, self).deploy()
76 self.logger.debug(" -------- DEPLOYED ------- ")
78 class Interface(ResourceManager):
81 def __init__(self, ec, guid):
82 super(Interface, self).__init__(ec, guid)
85 node = self.get_connected(Node.rtype())[0]
86 chan = self.get_connected(Channel.rtype())[0]
88 if node.state < ResourceState.PROVISIONED:
89 self.ec.schedule("0.5s", self.deploy)
90 elif chan.state < ResourceState.READY:
91 self.ec.schedule("0.5s", self.deploy)
94 super(Interface, self).deploy()
95 self.logger.debug(" -------- DEPLOYED ------- ")
97 class Node(ResourceManager):
100 def __init__(self, ec, guid):
101 super(Node, self).__init__(ec, guid)
104 if self.state == ResourceState.NEW:
107 self.logger.debug(" -------- PROVISIONED ------- ")
108 self.ec.schedule("3s", self.deploy)
109 elif self.state == ResourceState.PROVISIONED:
110 ifaces = self.get_connected(Interface.rtype())
112 if rm.state < ResourceState.READY:
113 self.ec.schedule("0.5s", self.deploy)
116 super(Node, self).deploy()
117 self.logger.debug(" -------- DEPLOYED ------- ")
119 class Application(ResourceManager):
120 _rtype = "Application"
122 def __init__(self, ec, guid):
123 super(Application, self).__init__(ec, guid)
126 node = self.get_connected(Node.rtype())[0]
127 if node.state < ResourceState.READY:
128 self.ec.schedule("0.5s", self.deploy)
130 time.sleep(random.random() * 5)
131 super(Application, self).deploy()
132 self.logger.debug(" -------- DEPLOYED ------- ")
135 super(Application, self).start()
136 time.sleep(random.random() * 5)
137 self._state = ResourceState.FINISHED
139 class ResourceManagerTestCase(unittest.TestCase):
140 def test_deploy_in_order(self):
142 Test scenario: 2 applications running one on 1 node each.
143 Nodes are connected to Interfaces which are connected
144 through a channel between them.
146 - Application needs to wait until Node is ready to be ready
147 - Node needs to wait until Interface is ready to be ready
148 - Interface needs to wait until Node is provisioned to be ready
149 - Interface needs to wait until Channel is ready to be ready
150 - The channel doesn't wait for any other resource to be ready
153 from nepi.execution.resource import ResourceFactory
155 ResourceFactory.register_type(Application)
156 ResourceFactory.register_type(Node)
157 ResourceFactory.register_type(Interface)
158 ResourceFactory.register_type(Channel)
160 ec = ExperimentController()
162 app1 = ec.register_resource("Application")
163 app2 = ec.register_resource("Application")
164 node1 = ec.register_resource("Node")
165 node2 = ec.register_resource("Node")
166 iface1 = ec.register_resource("Interface")
167 iface2 = ec.register_resource("Interface")
168 chan = ec.register_resource("Channel")
170 ec.register_connection(app1, node1)
171 ec.register_connection(app2, node2)
172 ec.register_connection(iface1, node1)
173 ec.register_connection(iface2, node2)
174 ec.register_connection(iface1, chan)
175 ec.register_connection(iface2, chan)
180 ec.wait_finished(guids)
184 rmapp1 = ec.get_resource(app1)
185 rmapp2 = ec.get_resource(app2)
186 rmnode1 = ec.get_resource(node1)
187 rmnode2 = ec.get_resource(node2)
188 rmiface1 = ec.get_resource(iface1)
189 rmiface2 = ec.get_resource(iface2)
190 rmchan = ec.get_resource(chan)
192 ## Validate deploy order
193 # - Application needs to wait until Node is ready to be ready
194 self.assertTrue(rmnode1.ready_time < rmapp1.ready_time)
195 self.assertTrue(rmnode2.ready_time < rmapp2.ready_time)
197 # - Node needs to wait until Interface is ready to be ready
198 self.assertTrue(rmnode1.ready_time > rmiface1.ready_time)
199 self.assertTrue(rmnode2.ready_time > rmiface2.ready_time)
201 # - Interface needs to wait until Node is provisioned to be ready
202 self.assertTrue(rmnode1.provision_time < rmiface1.ready_time)
203 self.assertTrue(rmnode2.provision_time < rmiface2.ready_time)
205 # - Interface needs to wait until Channel is ready to be ready
206 self.assertTrue(rmchan.ready_time < rmiface1.ready_time)
207 self.assertTrue(rmchan.ready_time < rmiface2.ready_time)
209 def test_concurrency(self):
210 from nepi.execution.resource import ResourceFactory
212 ResourceFactory.register_type(Application)
213 ResourceFactory.register_type(Node)
214 ResourceFactory.register_type(Interface)
215 ResourceFactory.register_type(Channel)
217 ec = ExperimentController()
219 node = ec.register_resource("Node")
222 for i in xrange(5000):
223 app = ec.register_resource("Application")
224 ec.register_connection(app, node)
229 ec.wait_finished(apps)
231 self.assertTrue(ec.state(node) == ResourceState.STARTED)
233 all([ec.state(guid) == ResourceState.FINISHED \
239 def test_start_with_condition(self):
243 def test_stop_with_condition(self):
247 def test_set_with_condition(self):
252 if __name__ == '__main__':