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