b06d3832344775e9e96ec727de1e172be728344a
[nepi.git] / test / execution / runner.py
1 #!/usr/bin/env python
2 #
3 #    NEPI, a framework to manage network experiments
4 #    Copyright (C) 2013 INRIA
5 #
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.
10 #
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.
15 #
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/>.
18 #
19 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
20
21 from nepi.execution.ec import ExperimentController
22 from nepi.execution.resource import ResourceManager, ResourceState, \
23         clsinit_copy, ResourceAction, ResourceFactory
24 from nepi.execution.runner import ExperimentRunner
25
26 import functools
27 import os
28 import shutil
29 import tempfile
30 import time
31 import unittest
32
33 reschedule_delay = "0.5s"
34 deploy_time = 0
35 run_time = 0
36
37 class Link(ResourceManager):
38     _rtype = "dummy::Link"
39     def do_deploy(self):
40         time.sleep(deploy_time)
41         super(Link, self).do_deploy()
42         self.logger.debug(" -------- DEPLOYED ------- ")
43
44 class Interface(ResourceManager):
45     _rtype = "dummy::Interface"
46
47     def do_deploy(self):
48         node = self.get_connected(Node.get_rtype())[0]
49         link = self.get_connected(Link.get_rtype())[0]
50
51         if node.state < ResourceState.READY or \
52                 link.state < ResourceState.READY:
53             self.ec.schedule(reschedule_delay, self.deploy)
54             self.logger.debug(" -------- RESCHEDULING ------- ")
55         else:
56             time.sleep(deploy_time)
57             super(Interface, self).do_deploy()
58             self.logger.debug(" -------- DEPLOYED ------- ")
59
60 class Node(ResourceManager):
61     _rtype = "dummy::Node"
62
63     def do_deploy(self):
64         self.logger.debug(" -------- DO_DEPLOY ------- ")
65         time.sleep(deploy_time)
66         super(Node, self).do_deploy()
67         self.logger.debug(" -------- DEPLOYED ------- ")
68
69 class Application(ResourceManager):
70     _rtype = "dummy::Application"
71
72     def do_deploy(self):
73         node = self.get_connected(Node.get_rtype())[0]
74
75         if node.state < ResourceState.READY: 
76             self.ec.schedule(reschedule_delay, self.deploy)
77             self.logger.debug(" -------- RESCHEDULING ------- ")
78         else:
79             time.sleep(deploy_time)
80             super(Application, self).do_deploy()
81             self.logger.debug(" -------- DEPLOYED ------- ")
82
83     def do_start(self):
84         super(Application, self).do_start()
85         time.sleep(run_time)
86         self.ec.schedule("0s", self.stop)
87
88 ResourceFactory.register_type(Application)
89 ResourceFactory.register_type(Node)
90 ResourceFactory.register_type(Interface)
91 ResourceFactory.register_type(Link)
92
93 class RunnerTestCase(unittest.TestCase):
94     def test_runner_max_runs(self):
95         node_count = 4
96         app_count = 2
97
98         ec = ExperimentController(exp_id = "max-runs-test")
99        
100         # Add simulated nodes and applications
101         nodes = list()
102         apps = list()
103         ifaces = list()
104
105         for i in xrange(node_count):
106             node = ec.register_resource("dummy::Node")
107             nodes.append(node)
108             
109             iface = ec.register_resource("dummy::Interface")
110             ec.register_connection(node, iface)
111             ifaces.append(iface)
112
113             for i in xrange(app_count):
114                 app = ec.register_resource("dummy::Application")
115                 ec.register_connection(node, app)
116                 apps.append(app)
117
118         link = ec.register_resource("dummy::Link")
119
120         for iface in ifaces:
121             ec.register_connection(link, iface)
122
123         rnr = ExperimentRunner()
124         runs = rnr.run(ec, min_runs = 5, max_runs = 10, wait_guids = apps, 
125                 wait_time = 0)
126
127         self.assertEquals(runs, 10)
128
129     def test_runner_convergence(self):
130         node_count = 4
131         app_count = 2
132
133         ec = ExperimentController(exp_id = "convergence-test")
134        
135         # Add simulated nodes and applications
136         nodes = list()
137         apps = list()
138         ifaces = list()
139
140         for i in xrange(node_count):
141             node = ec.register_resource("dummy::Node")
142             nodes.append(node)
143             
144             iface = ec.register_resource("dummy::Interface")
145             ec.register_connection(node, iface)
146             ifaces.append(iface)
147
148             for i in xrange(app_count):
149                 app = ec.register_resource("dummy::Application")
150                 ec.register_connection(node, app)
151                 apps.append(app)
152
153         link = ec.register_resource("dummy::Link")
154
155         for iface in ifaces:
156             ec.register_connection(link, iface)
157
158         samples = [10, 10, 10, 10, 12, 10, 12, 10, 10, 11]
159         
160         def compute_metric_callback(samples, ec, run):
161             return samples[run-1]
162
163         metric_callback = functools.partial(compute_metric_callback, samples)
164
165         rnr = ExperimentRunner()
166         runs = rnr.run(ec, min_runs = 5, 
167                 compute_metric_callback = metric_callback,
168                 wait_guids = apps, 
169                 wait_time = 0)
170
171         self.assertEquals(runs, 10)
172                        
173 if __name__ == '__main__':
174     unittest.main()
175