Sometimes when controller process cleanup happens concurrently with testbed teardown...
[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.constants import STATUS_FINISHED, DeploymentConfiguration as DC
6 from nepi.util import proxy
7 import mock
8 import mock.metadata_v01
9 import mock2
10 import mock2.metadata_v01
11 import os
12 import shutil
13 import sys
14 import tempfile
15 import test_util
16 import time
17 import unittest
18
19 class ExecuteTestCase(unittest.TestCase):
20     def setUp(self):
21         sys.modules["nepi.testbeds.mock.metadata_v01"] = mock.metadata_v01
22         sys.modules["nepi.testbeds.mock"] = mock
23         sys.modules["nepi.testbeds.mock2.metadata_v01"] = mock2.metadata_v01
24         sys.modules["nepi.testbeds.mock2"] = mock2
25         self.root_dir = tempfile.mkdtemp()
26
27     def tearDown(self):
28         try:
29             shutil.rmtree(self.root_dir)
30         except:
31             # retry
32             time.sleep(0.1)
33             shutil.rmtree(self.root_dir)
34
35     def make_testbed(self, exp_desc, testbed_id, testbed_version):
36         provider = FactoriesProvider(testbed_id, testbed_version)
37         desc = exp_desc.add_testbed_description(provider)
38         desc.set_attribute_value("fake", True)
39         node1 = desc.create("Node")
40         node2 = desc.create("Node")
41         iface1 = desc.create("Interface")
42         iface1.set_attribute_value("fake", True)
43         node1.connector("devs").connect(iface1.connector("node"))
44         iface2 = desc.create("Interface")
45         iface2.set_attribute_value("fake", True)
46         node2.connector("devs").connect(iface2.connector("node"))
47         iface1.connector("iface").connect(iface2.connector("iface"))
48         app = desc.create("Application")
49         app.connector("node").connect(node1.connector("apps"))
50         app.enable_trace("fake")
51         
52         return exp_desc, desc, app, node1, node2, iface1, iface2
53
54     def make_test_experiment(self):
55         exp_desc = ExperimentDescription()
56         testbed_version = "01"
57         testbed_id = "mock"
58         return self.make_testbed(exp_desc, testbed_id, testbed_version)
59
60     def make_cross_test_experiment(self):
61         exp_desc = ExperimentDescription()
62         testbed_version = "01"
63         testbed_id1 = "mock"
64         testbed_id2 = "mock2"
65         exp_desc, desc1, app1, node11, node12, iface11, iface12 = \
66                 self.make_testbed(exp_desc, testbed_id1, testbed_version)
67         exp_desc, desc2, app2, node21, node22, iface21, iface22 = \
68                  self.make_testbed(exp_desc, testbed_id2, testbed_version)
69         iface12.connector("cross").connect(iface21.connector("cross"))
70
71         return exp_desc, desc1, desc2, iface12, iface21
72
73     def test_single_process_cross_integration(self):
74         exp_desc, desc1, desc2, iface12, iface21 = \
75                 self.make_cross_test_experiment()
76         xml = exp_desc.to_xml()
77         access_config = None
78         controller = proxy.create_controller(xml, access_config)
79
80         controller.start()
81         cross1 = controller.get(desc1.guid, iface12.guid, "cross")
82         cross2 = controller.get(desc2.guid, iface21.guid, "cross")
83         self.assertTrue(cross1 == cross2 == True)
84         controller.stop()
85         controller.shutdown()
86
87     def test_single_process_integration(self):
88         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
89         xml = exp_desc.to_xml()
90         access_config = None
91         controller = proxy.create_controller(xml, access_config)
92
93         controller.start()
94         while not controller.is_finished(app.guid):
95             time.sleep(0.5)
96         fake_result = controller.trace(desc.guid, app.guid, "fake")
97         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
98
99 --- 10.0.0.2 ping statistics ---
100 1 packets transmitted, 1 received, 0% packet loss, time 0ms
101 """
102         self.assertTrue(fake_result.startswith(comp_result))
103         controller.stop()
104         controller.shutdown()
105
106     def test_daemonized_controller_integration(self):
107         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
108         xml = exp_desc.to_xml()
109         access_config = proxy.AccessConfiguration()
110         access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
111         access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
112         controller = proxy.create_controller(xml, access_config)
113
114         controller.start()
115         while not controller.is_finished(app.guid):
116             time.sleep(0.5)
117         fake_result = controller.trace(desc.guid, app.guid, "fake")
118         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
119
120 --- 10.0.0.2 ping statistics ---
121 1 packets transmitted, 1 received, 0% packet loss, time 0ms
122 """
123         self.assertTrue(fake_result.startswith(comp_result))
124         controller.stop()
125         controller.shutdown()
126
127     def test_daemonized_testbed_integration(self):
128         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
129         
130         desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
131         desc.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
132
133         xml = exp_desc.to_xml()
134         
135         controller = proxy.create_controller(xml, access_config = None)
136
137         controller.start()
138         while not controller.is_finished(app.guid):
139             time.sleep(0.5)
140         fake_result = controller.trace(desc.guid, app.guid, "fake")
141         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
142
143 --- 10.0.0.2 ping statistics ---
144 1 packets transmitted, 1 received, 0% packet loss, time 0ms
145 """
146         self.assertTrue(fake_result.startswith(comp_result))
147         controller.stop()
148         controller.shutdown()
149
150     def test_daemonized_all_integration(self):
151         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
152         
153         desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
154         inst_root_dir = os.path.join(self.root_dir, "instance")
155         os.mkdir(inst_root_dir)
156         desc.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
157         
158         xml = exp_desc.to_xml()
159         
160         access_config = proxy.AccessConfiguration()
161         access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
162         access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
163         controller = proxy.create_controller(xml, access_config)
164
165         controller.start()
166         while not controller.is_finished(app.guid):
167             time.sleep(0.5)
168         fake_result = controller.trace(desc.guid, app.guid, "fake")
169         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
170
171 --- 10.0.0.2 ping statistics ---
172 1 packets transmitted, 1 received, 0% packet loss, time 0ms
173 """
174         self.assertTrue(fake_result.startswith(comp_result))
175         controller.stop()
176         controller.shutdown()
177
178     def test_daemonized_all_integration_recovery(self):
179         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
180         
181         desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
182         inst_root_dir = os.path.join(self.root_dir, "instance")
183         os.mkdir(inst_root_dir)
184         desc.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
185         
186         xml = exp_desc.to_xml()
187         
188         access_config = proxy.AccessConfiguration()
189         access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
190         access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
191         controller = proxy.create_controller(xml, access_config)
192
193         controller.start()
194         while not controller.is_finished(app.guid):
195             time.sleep(0.5)
196         fake_result = controller.trace(desc.guid, app.guid, "fake")
197         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
198
199 --- 10.0.0.2 ping statistics ---
200 1 packets transmitted, 1 received, 0% packet loss, time 0ms
201 """
202         self.assertTrue(fake_result.startswith(comp_result))
203         
204         # controller dies
205         del controller
206         
207         # recover
208         access_config.set_attribute_value(DC.RECOVER,True)
209         controller = proxy.create_controller(xml, access_config)
210         
211         # test recovery
212         self.assertTrue(controller.is_finished(app.guid))
213         fake_result = controller.trace(desc.guid, app.guid, "fake")
214         self.assertTrue(fake_result.startswith(comp_result))
215         
216         controller.stop()
217         controller.shutdown()
218
219     def test_reference_expressions(self):
220         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
221         
222         iface1.set_attribute_value("label", "some")
223         addr = iface1.add_address()
224         addr.set_attribute_value("Address", "10.0.0.2")
225         iface2.set_attribute_value("test", "{#[some].addr[0].[Address]#}")
226         
227         # TODO: Test actual substitution
228         
229         xml = exp_desc.to_xml()
230         access_config = None
231         controller = proxy.create_controller(xml, access_config)
232         controller.start()
233         while not controller.is_finished(app.guid):
234             time.sleep(0.5)
235         fake_result = controller.trace(desc.guid, app.guid, "fake")
236         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
237
238 --- 10.0.0.2 ping statistics ---
239 1 packets transmitted, 1 received, 0% packet loss, time 0ms
240 """
241         self.assertTrue(fake_result.startswith(comp_result))
242         controller.stop()
243         controller.shutdown()
244
245     def TODO_test_ssh_daemonized_all_integration(self):
246         # TODO: This test doesn't run because
247         # sys.modules["nepi.testbeds.mock"] = mock
248         # is not set in the ssh process
249         exp_desc, desc, app, node1, node2, iface1, iface2 = self.make_test_experiment()
250         env = test_util.test_environment()
251         
252         desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
253         inst_root_dir = os.path.join(self.root_dir, "instance")
254         os.mkdir(inst_root_dir)
255         desc.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
256         desc.set_attribute_value(DC.DEPLOYMENT_COMMUNICATION, DC.ACCESS_SSH)
257         desc.set_attribute_value(DC.DEPLOYMENT_PORT, env.port)
258         desc.set_attribute_value(DC.USE_AGENT, True)
259         
260         xml = exp_desc.to_xml()
261         
262         access_config = proxy.AccessConfiguration()
263         access_config.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
264         access_config.set_attribute_value(DC.ROOT_DIRECTORY, self.root_dir)
265         access_config.set_attribute_value(DC.DEPLOYMENT_COMMUNICATION, DC.ACCESS_SSH)
266         access_config.set_attribute_value(DC.DEPLOYMENT_PORT, env.port)
267         access_config.set_attribute_value(DC.USE_AGENT, True)
268         controller = proxy.create_controller(xml, access_config)
269
270         controller.start()
271         while not controller.is_finished(app.guid):
272             time.sleep(0.5)
273         fake_result = controller.trace(desc.guid, app.guid, "fake")
274         comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
275
276 --- 10.0.0.2 ping statistics ---
277 1 packets transmitted, 1 received, 0% packet loss, time 0ms
278 """
279         self.assertTrue(fake_result.startswith(comp_result))
280         controller.stop()
281         controller.shutdown()
282  
283 if __name__ == '__main__':
284     unittest.main()
285