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
30 class MyResource(ResourceManager):
34 def _register_attributes(cls):
35 cool_attr = Attribute("my_attr", "is a really nice attribute!")
36 cls._register_attribute(cool_attr)
38 def __init__(self, ec, guid):
39 super(MyResource, self).__init__(ec, guid)
42 class AnotherResource(ResourceManager):
43 _rtype = "AnotherResource"
45 def __init__(self, ec, guid):
46 super(AnotherResource, self).__init__(ec, guid)
48 class ResourceFactoryTestCase(unittest.TestCase):
49 def test_add_resource_factory(self):
50 from nepi.execution.resource import ResourceFactory
52 ResourceFactory.register_type(MyResource)
53 ResourceFactory.register_type(AnotherResource)
55 self.assertEquals(MyResource.rtype(), "MyResource")
56 self.assertEquals(len(MyResource._attributes), 1)
58 self.assertEquals(ResourceManager.rtype(), "Resource")
59 self.assertEquals(len(ResourceManager._attributes), 0)
61 self.assertEquals(AnotherResource.rtype(), "AnotherResource")
62 self.assertEquals(len(AnotherResource._attributes), 0)
64 self.assertEquals(len(ResourceFactory.resource_types()), 2)
66 class Channel(ResourceManager):
69 def __init__(self, ec, guid):
70 super(Channel, self).__init__(ec, guid)
74 super(Channel, self).deploy()
75 self.logger.debug(" -------- DEPLOYED ------- ")
77 class Interface(ResourceManager):
80 def __init__(self, ec, guid):
81 super(Interface, self).__init__(ec, guid)
84 node = self.get_connected(Node.rtype())[0]
85 chan = self.get_connected(Channel.rtype())[0]
87 if node.state < ResourceState.PROVISIONED:
88 self.ec.schedule("0.5s", self.deploy)
89 elif chan.state < ResourceState.READY:
90 self.ec.schedule("0.5s", self.deploy)
93 super(Interface, self).deploy()
94 self.logger.debug(" -------- DEPLOYED ------- ")
96 class Node(ResourceManager):
99 def __init__(self, ec, guid):
100 super(Node, self).__init__(ec, guid)
103 if self.state == ResourceState.NEW:
106 self.logger.debug(" -------- PROVISIONED ------- ")
107 self.ec.schedule("3s", self.deploy)
108 elif self.state == ResourceState.PROVISIONED:
109 ifaces = self.get_connected(Interface.rtype())
111 if rm.state < ResourceState.READY:
112 self.ec.schedule("0.5s", self.deploy)
115 super(Node, self).deploy()
116 self.logger.debug(" -------- DEPLOYED ------- ")
118 class Application(ResourceManager):
119 _rtype = "Application"
121 def __init__(self, ec, guid):
122 super(Application, self).__init__(ec, guid)
125 node = self.get_connected(Node.rtype())[0]
126 if node.state < ResourceState.READY:
127 self.ec.schedule("0.5s", self.deploy)
129 super(Application, self).deploy()
130 self.logger.debug(" -------- DEPLOYED ------- ")
132 class ResourceManagerTestCase(unittest.TestCase):
133 def test_deploy_in_order(self):
135 Test scenario: 2 applications running one on 1 node each.
136 Nodes are connected to Interfaces which are connected
137 through a channel between them.
139 - Application needs to wait until Node is ready to be ready
140 - Node needs to wait until Interface is ready to be ready
141 - Interface needs to wait until Node is provisioned to be ready
142 - Interface needs to wait until Channel is ready to be ready
143 - The channel doesn't wait for any other resource to be ready
146 from nepi.execution.resource import ResourceFactory
148 ResourceFactory.register_type(Application)
149 ResourceFactory.register_type(Node)
150 ResourceFactory.register_type(Interface)
151 ResourceFactory.register_type(Channel)
153 ec = ExperimentController()
155 app1 = ec.register_resource("Application")
156 app2 = ec.register_resource("Application")
157 node1 = ec.register_resource("Node")
158 node2 = ec.register_resource("Node")
159 iface1 = ec.register_resource("Interface")
160 iface2 = ec.register_resource("Interface")
161 chan = ec.register_resource("Channel")
163 ec.register_connection(app1, node1)
164 ec.register_connection(app2, node2)
165 ec.register_connection(iface1, node1)
166 ec.register_connection(iface2, node2)
167 ec.register_connection(iface1, chan)
168 ec.register_connection(iface2, chan)
172 while not all([ ec.state(guid) == ResourceState.STARTED \
173 for guid in [app1, app2, node1, node2, iface1, iface2, chan]]) \
179 rmapp1 = ec.get_resource(app1)
180 rmapp2 = ec.get_resource(app2)
181 rmnode1 = ec.get_resource(node1)
182 rmnode2 = ec.get_resource(node2)
183 rmiface1 = ec.get_resource(iface1)
184 rmiface2 = ec.get_resource(iface2)
185 rmchan = ec.get_resource(chan)
187 ## Validate deploy order
188 # - Application needs to wait until Node is ready to be ready
189 self.assertTrue(rmnode1.ready_time < rmapp1.ready_time)
190 self.assertTrue(rmnode2.ready_time < rmapp2.ready_time)
192 # - Node needs to wait until Interface is ready to be ready
193 self.assertTrue(rmnode1.ready_time > rmiface1.ready_time)
194 self.assertTrue(rmnode2.ready_time > rmiface2.ready_time)
196 # - Interface needs to wait until Node is provisioned to be ready
197 self.assertTrue(rmnode1.provision_time < rmiface1.ready_time)
198 self.assertTrue(rmnode2.provision_time < rmiface2.ready_time)
200 # - Interface needs to wait until Channel is ready to be ready
201 self.assertTrue(rmchan.ready_time < rmiface1.ready_time)
202 self.assertTrue(rmchan.ready_time < rmiface2.ready_time)
204 def test_start_with_condition(self):
208 def test_stop_with_condition(self):
212 def test_set_with_condition(self):
217 if __name__ == '__main__':