4d76c4d30fee480c89c443bde11062d502c3e335
[nepi.git] / test / core / integration.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 from nepi.core.design import ExperimentDescription, FactoriesProvider
5 from nepi.util import proxy
6 from nepi.util.constants import DeploymentConfiguration as DC
7 import getpass
8 import mock
9 import mock.metadata
10 import mock2
11 import mock2.metadata
12 import os
13 import shutil
14 import sys
15 import tempfile
16 import test_util
17 import time
18 import unittest
19
20 class ExecuteTestCase(unittest.TestCase):
21     def setUp(self):
22         sys.modules["nepi.testbeds.mock.metadata"] = mock.metadata
23         sys.modules["nepi.testbeds.mock"] = mock
24         sys.modules["nepi.testbeds.mock2.metadata"] = mock2.metadata
25         sys.modules["nepi.testbeds.mock2"] = mock2
26         self.root_dir = tempfile.mkdtemp()
27
28     def tearDown(self):
29         try:
30             shutil.rmtree(self.root_dir)
31         except:
32             # retry
33             time.sleep(0.1)
34             shutil.rmtree(self.root_dir)
35
36     def make_testbed(self, exp_desc, testbed_id):
37         provider = FactoriesProvider(testbed_id)
38         desc = exp_desc.add_testbed_description(provider)
39         desc.set_attribute_value("fake", True)
40         node1 = desc.create("Node")
41         node2 = desc.create("Node")
42         iface1 = desc.create("Interface")
43         iface1.set_attribute_value("fake", True)
44         node1.connector("devs").connect(iface1.connector("node"))
45         iface2 = desc.create("Interface")
46         iface2.set_attribute_value("fake", True)
47         node2.connector("devs").connect(iface2.connector("node"))
48         iface1.connector("iface").connect(iface2.connector("iface"))
49         app = desc.create("Application")
50         app.connector("node").connect(node1.connector("apps"))
51         app.enable_trace("fake")
52         
53         return exp_desc, desc, app, node1, node2, iface1, iface2
54
55     def make_test_experiment(self):
56         exp_desc = ExperimentDescription()
57         testbed_id = "mock"
58         return self.make_testbed(exp_desc, testbed_id)
59
60     def make_cross_test_experiment(self):
61         exp_desc = ExperimentDescription()
62         testbed_id1 = "mock"
63         testbed_id2 = "mock2"
64         exp_desc, desc1, app1, node11, node12, iface11, iface12 = \
65                 self.make_testbed(exp_desc, testbed_id1)
66         exp_desc, desc2, app2, node21, node22, iface21, iface22 = \
67                  self.make_testbed(exp_desc, testbed_id2)
68         iface12.connector("cross").connect(iface21.connector("cross"))
69
70         return exp_desc, desc1, desc2, iface12, iface21
71
72     def test_single_process_cross_integration(self):
73         exp_desc, desc1, desc2, iface12, iface21 = \
74                 self.make_cross_test_experiment()
75         xml = exp_desc.to_xml()
76         access_config = None
77         controller = proxy.create_experiment_controller(xml, access_config)
78
79         controller.start()
80         cross1 = controller.get(iface12.guid, "cross")
81         cross2 = controller.get(iface21.guid, "cross")
82         self.assertTrue(cross1 == cross2 == True)
83         controller.stop()
84         controller.shutdown()
85
86     def test_single_process_integration(self):
87         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
88         xml = exp_desc.to_xml()
89         access_config = None
90         controller = proxy.create_experiment_controller(xml, access_config)
91
92         controller.start()
93         while not controller.is_finished(app.guid):
94             time.sleep(0.5)
95         fake_result = controller.trace(app.guid, "fake")
96         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
97
98 --- 10.0.0.2 ping statistics ---
99 1 packets transmitted, 1 received, 0% packet loss, time 0ms
100 """
101         self.assertTrue(fake_result.startswith(comp_result))
102
103         self.assertEquals(controller.get_testbed_id(node1.guid), "mock")
104         self.assertEquals(controller.get_testbed_version(node1.guid), "0.1")
105         self.assertEquals(controller.get_factory_id(node1.guid), "Node")
106
107         controller.stop()
108         controller.shutdown()
109
110     def test_daemonized_controller_integration(self):
111         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
112         xml = exp_desc.to_xml()
113         access_config = proxy.AccessConfiguration()
114         access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
115         access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
116         controller = proxy.create_experiment_controller(xml, access_config)
117
118         controller.start()
119         while not controller.is_finished(app.guid):
120             time.sleep(0.5)
121         fake_result = controller.trace(app.guid, "fake")
122         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
123
124 --- 10.0.0.2 ping statistics ---
125 1 packets transmitted, 1 received, 0% packet loss, time 0ms
126 """
127         self.assertTrue(fake_result.startswith(comp_result))
128
129         self.assertEquals(controller.get_testbed_id(node1.guid), "mock")
130         self.assertEquals(controller.get_testbed_version(node1.guid), "0.1")
131         self.assertEquals(controller.get_factory_id(node1.guid), "Node")
132
133         controller.stop()
134         controller.shutdown()
135
136     def test_daemonized_testbed_integration(self):
137         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
138         
139         desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
140         desc.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
141
142         xml = exp_desc.to_xml()
143         
144         controller = proxy.create_experiment_controller(xml, access_config = None)
145
146         controller.start()
147         while not controller.is_finished(app.guid):
148             time.sleep(0.5)
149         fake_result = controller.trace(app.guid, "fake")
150         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
151
152 --- 10.0.0.2 ping statistics ---
153 1 packets transmitted, 1 received, 0% packet loss, time 0ms
154 """
155         self.assertTrue(fake_result.startswith(comp_result))
156
157         self.assertEquals(controller.get_testbed_id(node1.guid), "mock")
158         self.assertEquals(controller.get_testbed_version(node1.guid), "0.1")
159         self.assertEquals(controller.get_factory_id(node1.guid), "Node")
160
161         controller.stop()
162         controller.shutdown()
163
164     def test_daemonized_all_integration(self):
165         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
166         
167         desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
168         inst_root_dir = os.path.join(self.root_dir, "instance")
169         os.mkdir(inst_root_dir)
170         desc.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
171         
172         xml = exp_desc.to_xml()
173         
174         access_config = proxy.AccessConfiguration()
175         access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
176         access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
177         controller = proxy.create_experiment_controller(xml, access_config)
178
179         controller.start()
180         while not controller.is_finished(app.guid):
181             time.sleep(0.5)
182         fake_result = controller.trace(app.guid, "fake")
183         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
184
185 --- 10.0.0.2 ping statistics ---
186 1 packets transmitted, 1 received, 0% packet loss, time 0ms
187 """
188         self.assertTrue(fake_result.startswith(comp_result))
189
190         self.assertEquals(controller.get_testbed_id(node1.guid), "mock")
191         self.assertEquals(controller.get_testbed_version(node1.guid), "0.1")
192         self.assertEquals(controller.get_factory_id(node1.guid), "Node")
193
194         traces_info = controller.traces_info()
195         expected_traces_info = dict({
196             1: dict({ # testbed guid
197                 6: dict({ # element guid
198                     'fake': dict({ # trace_id
199                         'host': 'localhost', 
200                         'user': getpass.getuser(), 
201                         'filepath': '<test>'
202                         })
203                     })
204                 })
205             })
206         self.assertEquals(traces_info, expected_traces_info)
207
208         controller.stop()
209         controller.shutdown()
210
211     def test_daemonized_all_integration_recovery(self):
212         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
213         
214         desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
215         inst_root_dir = os.path.join(self.root_dir, "instance")
216         os.mkdir(inst_root_dir)
217         desc.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
218         
219         xml = exp_desc.to_xml()
220         
221         access_config = proxy.AccessConfiguration()
222         access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
223         access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
224         controller = proxy.create_experiment_controller(xml, access_config)
225
226         controller.start()
227         while not controller.is_finished(app.guid):
228             time.sleep(0.5)
229         fake_result = controller.trace(app.guid, "fake")
230         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
231
232 --- 10.0.0.2 ping statistics ---
233 1 packets transmitted, 1 received, 0% packet loss, time 0ms
234 """
235         self.assertTrue(fake_result.startswith(comp_result))
236
237         self.assertEquals(controller.get_testbed_id(node1.guid), "mock")
238         self.assertEquals(controller.get_testbed_version(node1.guid), "0.1")
239         self.assertEquals(controller.get_factory_id(node1.guid), "Node")
240
241         # controller dies
242         del controller
243         
244         # recover
245         access_config.set_attribute_value(DC.RECOVER,True)
246         controller = proxy.create_experiment_controller(xml, access_config)
247         
248         # test recovery
249         self.assertTrue(controller.is_finished(app.guid))
250         fake_result = controller.trace(app.guid, "fake")
251         self.assertTrue(fake_result.startswith(comp_result))
252         
253         controller.stop()
254         controller.shutdown()
255
256     def test_reference_expressions(self):
257         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
258         
259         iface1.set_attribute_value("label", "some")
260         addr = iface1.add_address()
261         addr.set_attribute_value("Address", "10.0.0.2")
262         iface2.set_attribute_value("test", "{#[some].addr[0].[Address]#}")
263         
264         xml = exp_desc.to_xml()
265         access_config = None
266         controller = proxy.create_experiment_controller(xml, access_config)
267         controller.start()
268         while not controller.is_finished(app.guid):
269             time.sleep(0.5)
270         fake_result = controller.trace(app.guid, "fake")
271         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
272
273 --- 10.0.0.2 ping statistics ---
274 1 packets transmitted, 1 received, 0% packet loss, time 0ms
275 """
276         
277         self.assertTrue(fake_result.startswith(comp_result))
278         
279         self.assertEqual(
280             controller._testbeds[desc.guid].get(iface2.guid, "test"),
281             addr.get_attribute_value("Address") )
282         
283         controller.stop()
284         controller.shutdown()
285
286     def test_testbed_reference_expressions(self):
287         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
288         
289         iface1.set_attribute_value("label", "some")
290         addr = iface1.add_address()
291         addr.set_attribute_value("Address", "10.0.0.2")
292
293         desc2 = exp_desc.add_testbed_description(
294             FactoriesProvider("mock2") )
295         desc2.set_attribute_value(DC.DEPLOYMENT_HOST, "{#[some].addr[0].[Address]#}")
296         # DC.DEPLOYMENT_HOST should be ignored if DC.DEPLOYMENT_CONNECTION is not set
297         # But it should be resolved anyway
298         
299         xml = exp_desc.to_xml()
300         access_config = None
301         controller = proxy.create_experiment_controller(xml, access_config)
302         controller.start()
303         while not controller.is_finished(app.guid):
304             time.sleep(0.5)
305         fake_result = controller.trace(app.guid, "fake")
306         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
307
308 --- 10.0.0.2 ping statistics ---
309 1 packets transmitted, 1 received, 0% packet loss, time 0ms
310 """
311         self.assertTrue(fake_result.startswith(comp_result))
312
313         self.assertEqual(
314             controller._deployment_config[desc2.guid]
315                 .get_attribute_value(DC.DEPLOYMENT_HOST),
316             addr.get_attribute_value("Address") )
317         
318         controller.stop()
319         controller.shutdown()
320
321     def TODO_test_ssh_daemonized_all_integration(self):
322         # TODO: This test doesn't run because
323         # sys.modules["nepi.testbeds.mock"] = mock
324         # is not set in the ssh process
325         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
326         env = test_util.test_environment()
327         
328         desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
329         inst_root_dir = os.path.join(self.root_dir, "instance")
330         os.mkdir(inst_root_dir)
331         desc.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
332         desc.set_attribute_value(DC.DEPLOYMENT_COMMUNICATION, DC.ACCESS_SSH)
333         desc.set_attribute_value(DC.DEPLOYMENT_PORT, env.port)
334         desc.set_attribute_value(DC.USE_AGENT, True)
335         
336         xml = exp_desc.to_xml()
337         
338         access_config = proxy.AccessConfiguration()
339         access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
340         access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
341         access_config.set_attribute_value(DC.DEPLOYMENT_COMMUNICATION, DC.ACCESS_SSH)
342         access_config.set_attribute_value(DC.DEPLOYMENT_PORT, env.port)
343         access_config.set_attribute_value(DC.USE_AGENT, True)
344         controller = proxy.create_experiment_controller(xml, access_config)
345
346         controller.start()
347         while not controller.is_finished(app.guid):
348             time.sleep(0.5)
349         fake_result = controller.trace(app.guid, "fake")
350         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
351
352 --- 10.0.0.2 ping statistics ---
353 1 packets transmitted, 1 received, 0% packet loss, time 0ms
354 """
355         self.assertTrue(fake_result.startswith(comp_result))
356         controller.stop()
357         controller.shutdown()
358  
359 if __name__ == '__main__':
360     unittest.main()
361