2 NEPI, a framework to manage network experiments
3 Copyright (C) 2013 INRIA
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 from nepi.execution.attribute import Attribute
22 from nepi.execution.ec import ExperimentController
23 from nepi.execution.resource import ResourceManager, ResourceState, clsinit
29 class MyResource(ResourceManager):
33 def _register_attributes(cls):
34 cool_attr = Attribute("my_attr", "is a really nice attribute!")
35 cls._register_attribute(cool_attr)
37 def __init__(self, ec, guid):
38 super(MyResource, self).__init__(ec, guid)
41 class AnotherResource(ResourceManager):
42 _rtype = "AnotherResource"
44 def __init__(self, ec, guid):
45 super(AnotherResource, self).__init__(ec, guid)
47 class ResourceFactoryTestCase(unittest.TestCase):
48 def test_add_resource_factory(self):
49 from nepi.execution.resource import ResourceFactory
51 ResourceFactory.register_type(MyResource)
52 ResourceFactory.register_type(AnotherResource)
54 self.assertEquals(MyResource.rtype(), "MyResource")
55 self.assertEquals(len(MyResource._attributes), 1)
57 self.assertEquals(ResourceManager.rtype(), "Resource")
58 self.assertEquals(len(ResourceManager._attributes), 0)
60 self.assertEquals(AnotherResource.rtype(), "AnotherResource")
61 self.assertEquals(len(AnotherResource._attributes), 0)
63 self.assertEquals(len(ResourceFactory.resource_types()), 2)
65 class Channel(ResourceManager):
68 def __init__(self, ec, guid):
69 super(Channel, self).__init__(ec, guid)
73 super(Channel, self).deploy()
74 self.logger.debug(" -------- DEPLOYED ------- ")
76 class Interface(ResourceManager):
79 def __init__(self, ec, guid):
80 super(Interface, self).__init__(ec, guid)
83 node = self.get_connected(Node.rtype())[0]
84 chan = self.get_connected(Channel.rtype())[0]
86 if node.state < ResourceState.PROVISIONED:
87 self.ec.schedule("0.5s", self.deploy)
88 elif chan.state < ResourceState.READY:
89 self.ec.schedule("0.5s", self.deploy)
92 super(Interface, self).deploy()
93 self.logger.debug(" -------- DEPLOYED ------- ")
95 class Node(ResourceManager):
98 def __init__(self, ec, guid):
99 super(Node, self).__init__(ec, guid)
102 if self.state == ResourceState.NEW:
105 self.logger.debug(" -------- PROVISIONED ------- ")
106 self.ec.schedule("3s", self.deploy)
107 elif self.state == ResourceState.PROVISIONED:
108 ifaces = self.get_connected(Interface.rtype())
110 if rm.state < ResourceState.READY:
111 self.ec.schedule("0.5s", self.deploy)
114 super(Node, self).deploy()
115 self.logger.debug(" -------- DEPLOYED ------- ")
117 class Application(ResourceManager):
118 _rtype = "Application"
120 def __init__(self, ec, guid):
121 super(Application, self).__init__(ec, guid)
124 node = self.get_connected(Node.rtype())[0]
125 if node.state < ResourceState.READY:
126 self.ec.schedule("0.5s", self.deploy)
128 super(Application, self).deploy()
129 self.logger.debug(" -------- DEPLOYED ------- ")
131 class ResourceManagerTestCase(unittest.TestCase):
132 def test_deploy_in_order(self):
134 Test scenario: 2 applications running one on 1 node each.
135 Nodes are connected to Interfaces which are connected
136 through a channel between them.
138 - Application needs to wait until Node is ready to be ready
139 - Node needs to wait until Interface is ready to be ready
140 - Interface needs to wait until Node is provisioned to be ready
141 - Interface needs to wait until Channel is ready to be ready
142 - The channel doesn't wait for any other resource to be ready
145 from nepi.execution.resource import ResourceFactory
147 ResourceFactory.register_type(Application)
148 ResourceFactory.register_type(Node)
149 ResourceFactory.register_type(Interface)
150 ResourceFactory.register_type(Channel)
152 ec = ExperimentController()
154 app1 = ec.register_resource("Application")
155 app2 = ec.register_resource("Application")
156 node1 = ec.register_resource("Node")
157 node2 = ec.register_resource("Node")
158 iface1 = ec.register_resource("Interface")
159 iface2 = ec.register_resource("Interface")
160 chan = ec.register_resource("Channel")
162 ec.register_connection(app1, node1)
163 ec.register_connection(app2, node2)
164 ec.register_connection(iface1, node1)
165 ec.register_connection(iface2, node2)
166 ec.register_connection(iface1, chan)
167 ec.register_connection(iface2, chan)
171 while not all([ ec.state(guid) == ResourceState.STARTED \
172 for guid in [app1, app2, node1, node2, iface1, iface2, chan]]) \
178 rmapp1 = ec.get_resource(app1)
179 rmapp2 = ec.get_resource(app2)
180 rmnode1 = ec.get_resource(node1)
181 rmnode2 = ec.get_resource(node2)
182 rmiface1 = ec.get_resource(iface1)
183 rmiface2 = ec.get_resource(iface2)
184 rmchan = ec.get_resource(chan)
186 ## Validate deploy order
187 # - Application needs to wait until Node is ready to be ready
188 self.assertTrue(rmnode1.ready_time < rmapp1.ready_time)
189 self.assertTrue(rmnode2.ready_time < rmapp2.ready_time)
191 # - Node needs to wait until Interface is ready to be ready
192 self.assertTrue(rmnode1.ready_time > rmiface1.ready_time)
193 self.assertTrue(rmnode2.ready_time > rmiface2.ready_time)
195 # - Interface needs to wait until Node is provisioned to be ready
196 self.assertTrue(rmnode1.provision_time < rmiface1.ready_time)
197 self.assertTrue(rmnode2.provision_time < rmiface2.ready_time)
199 # - Interface needs to wait until Channel is ready to be ready
200 self.assertTrue(rmchan.ready_time < rmiface1.ready_time)
201 self.assertTrue(rmchan.ready_time < rmiface2.ready_time)
203 def test_start_with_condition(self):
207 def test_stop_with_condition(self):
211 def test_set_with_condition(self):
216 if __name__ == '__main__':