3 # All rights reserved. This program and the accompanying materials
4 # are made available under the terms of the Apache License, Version 2.0
5 # which accompanies this distribution, and is available at
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # pylint: disable=missing-docstring,protected-access,invalid-name
16 from xtesting.core import testcase
18 from functest.opnfv_tests.openstack.rally import rally
21 class OSRallyTesting(unittest.TestCase):
22 # pylint: disable=too-many-public-methods
24 with mock.patch('os_client_config.make_shade') as mock_make_shade:
25 self.rally_base = rally.RallyBase()
26 self.assertTrue(mock_make_shade.called)
28 def test_build_task_args_missing_floating_network(self):
29 os.environ['OS_AUTH_URL'] = ''
30 self.rally_base.ext_net_name = ''
31 task_args = self.rally_base._build_task_args('test_file_name')
32 self.assertEqual(task_args['floating_network'], '')
34 def test_build_task_args_missing_net_id(self):
35 os.environ['OS_AUTH_URL'] = ''
36 self.rally_base.priv_net_id = ''
37 task_args = self.rally_base._build_task_args('test_file_name')
38 self.assertEqual(task_args['netid'], '')
41 def check_scenario_file(value):
42 yaml_file = 'opnfv-{}.yaml'.format('test_file_name')
43 if yaml_file in value:
47 @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.path.exists')
48 def test_prepare_test_list_missing_scenario_file(self, mock_func):
49 mock_func.side_effect = self.check_scenario_file
50 with self.assertRaises(Exception):
51 self.rally_base._prepare_test_list('test_file_name')
52 mock_func.assert_called()
55 def check_temp_dir(value):
56 yaml_file = 'opnfv-{}.yaml'.format('test_file_name')
57 if yaml_file in value:
61 @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.path.exists')
62 @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.makedirs')
63 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
65 def test_prepare_test_list_missing_temp_dir(
66 self, mock_method, mock_os_makedirs, mock_path_exists):
67 mock_path_exists.side_effect = self.check_temp_dir
69 yaml_file = 'opnfv-{}.yaml'.format('test_file_name')
70 ret_val = os.path.join(self.rally_base.TEMP_DIR, yaml_file)
71 self.assertEqual(self.rally_base._prepare_test_list('test_file_name'),
73 mock_path_exists.assert_called()
74 mock_method.assert_called()
75 mock_os_makedirs.assert_called()
77 def test_get_task_id_default(self):
78 cmd_raw = 'Task 1: started'
79 self.assertEqual(self.rally_base.get_task_id(cmd_raw),
82 def test_get_task_id_missing_id(self):
84 self.assertEqual(self.rally_base.get_task_id(cmd_raw),
87 def test_task_succeed_fail(self):
88 json_raw = json.dumps([None])
89 self.assertEqual(self.rally_base.task_succeed(json_raw),
91 json_raw = json.dumps([{'result': [{'error': ['test_error']}]}])
92 self.assertEqual(self.rally_base.task_succeed(json_raw),
95 def test_task_succeed_success(self):
96 json_raw = json.dumps('')
97 self.assertEqual(self.rally_base.task_succeed(json_raw),
100 def test_get_cmd_output(self):
102 proc.stdout.__iter__ = mock.Mock(return_value=iter(['line1', 'line2']))
103 self.assertEqual(self.rally_base.get_cmd_output(proc),
106 @mock.patch('__builtin__.open', mock.mock_open())
107 @mock.patch('functest.opnfv_tests.openstack.rally.rally.yaml.safe_load',
108 return_value={'scenario': [
109 {'scenarios': ['test_scenario'],
110 'installers': ['test_installer'],
112 {'scenarios': ['other_scenario'],
113 'installers': ['test_installer'],
114 'tests': ['other_test']}]})
115 def test_excl_scenario_default(self, mock_func):
116 os.environ['INSTALLER_TYPE'] = 'test_installer'
117 os.environ['DEPLOY_SCENARIO'] = 'test_scenario'
118 self.assertEqual(self.rally_base.excl_scenario(), ['test'])
119 mock_func.assert_called()
121 @mock.patch('__builtin__.open', mock.mock_open())
122 @mock.patch('functest.opnfv_tests.openstack.rally.rally.yaml.safe_load',
123 return_value={'scenario': [
124 {'scenarios': ['^os-[^-]+-featT-modeT$'],
125 'installers': ['test_installer'],
127 {'scenarios': ['^os-ctrlT-[^-]+-modeT$'],
128 'installers': ['test_installer'],
130 {'scenarios': ['^os-ctrlT-featT-[^-]+$'],
131 'installers': ['test_installer'],
133 {'scenarios': ['^os-'],
134 'installers': ['test_installer'],
136 {'scenarios': ['other_scenario'],
137 'installers': ['test_installer'],
138 'tests': ['test0a']},
139 {'scenarios': [''], # empty scenario
140 'installers': ['test_installer'],
141 'tests': ['test0b']}]})
142 def test_excl_scenario_regex(self, mock_func):
143 os.environ['INSTALLER_TYPE'] = 'test_installer'
144 os.environ['DEPLOY_SCENARIO'] = 'os-ctrlT-featT-modeT'
145 self.assertEqual(self.rally_base.excl_scenario(),
146 ['test1', 'test2', 'test3', 'test4'])
147 mock_func.assert_called()
149 @mock.patch('__builtin__.open', side_effect=Exception)
150 def test_excl_scenario_exception(self, mock_open):
151 self.assertEqual(self.rally_base.excl_scenario(), [])
152 mock_open.assert_called()
154 @mock.patch('__builtin__.open', mock.mock_open())
155 @mock.patch('functest.opnfv_tests.openstack.rally.rally.yaml.safe_load',
156 return_value={'functionality': [
157 {'functions': ['no_migration'], 'tests': ['test']}]})
158 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
159 '_migration_supported', return_value=False)
160 def test_excl_func_default(self, mock_func, mock_yaml_load):
161 os.environ['INSTALLER_TYPE'] = 'test_installer'
162 os.environ['DEPLOY_SCENARIO'] = 'test_scenario'
163 self.assertEqual(self.rally_base.excl_func(), ['test'])
164 mock_func.assert_called()
165 mock_yaml_load.assert_called()
167 @mock.patch('__builtin__.open', side_effect=Exception)
168 def test_excl_func_exception(self, mock_open):
169 self.assertEqual(self.rally_base.excl_func(), [])
170 mock_open.assert_called()
172 @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.stat')
173 def test_file_is_empty_default(self, mock_os_stat):
174 attrs = {'st_size': 10}
175 mock_os_stat.return_value.configure_mock(**attrs)
176 self.assertEqual(self.rally_base.file_is_empty('test_file_name'),
178 mock_os_stat.assert_called()
180 @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.stat',
181 side_effect=Exception)
182 def test_file_is_empty_exception(self, mock_os_stat):
183 self.assertEqual(self.rally_base.file_is_empty('test_file_name'), True)
184 mock_os_stat.assert_called()
186 @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.path.exists',
188 def test_run_task_missing_task_file(self, mock_path_exists):
189 with self.assertRaises(Exception):
190 self.rally_base._run_task('test_name')
191 mock_path_exists.assert_called()
193 @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.path.exists',
195 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
196 '_prepare_test_list', return_value='test_file_name')
197 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
198 'file_is_empty', return_value=True)
199 @mock.patch('functest.opnfv_tests.openstack.rally.rally.LOGGER.info')
200 def test_run_task_no_tests_for_scenario(self, mock_logger_info,
201 mock_file_empty, mock_prep_list,
203 self.rally_base._run_task('test_name')
204 mock_logger_info.assert_any_call('No tests for scenario \"%s\"',
206 mock_file_empty.assert_called()
207 mock_prep_list.assert_called()
208 mock_path_exists.assert_called()
210 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
211 '_prepare_test_list', return_value='test_file_name')
212 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
213 'file_is_empty', return_value=False)
214 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
215 '_build_task_args', return_value={})
216 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
218 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
219 'get_task_id', return_value=None)
220 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
221 'get_cmd_output', return_value='')
222 @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.path.exists',
224 @mock.patch('functest.opnfv_tests.openstack.rally.rally.subprocess.Popen')
225 @mock.patch('functest.opnfv_tests.openstack.rally.rally.LOGGER.error')
226 def test_run_task_taskid_missing(self, mock_logger_error, *args):
227 # pylint: disable=unused-argument
228 self.rally_base._run_task('test_name')
229 text = 'Failed to retrieve task_id, validating task...'
230 mock_logger_error.assert_any_call(text)
232 @mock.patch('__builtin__.open', mock.mock_open())
233 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
234 '_prepare_test_list', return_value='test_file_name')
235 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
236 'file_is_empty', return_value=False)
237 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
238 '_build_task_args', return_value={})
239 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
241 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
242 'get_task_id', return_value='1')
243 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
244 'get_cmd_output', return_value='')
245 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
246 'task_succeed', return_value=True)
247 @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.path.exists',
249 @mock.patch('functest.opnfv_tests.openstack.rally.rally.subprocess.Popen')
250 @mock.patch('functest.opnfv_tests.openstack.rally.rally.os.makedirs')
251 @mock.patch('functest.opnfv_tests.openstack.rally.rally.LOGGER.info')
252 @mock.patch('functest.opnfv_tests.openstack.rally.rally.LOGGER.error')
253 def test_run_task_default(self, mock_logger_error, mock_logger_info,
255 # pylint: disable=unused-argument
256 self.rally_base._run_task('test_name')
257 text = 'Test scenario: "test_name" OK.\n'
258 mock_logger_info.assert_any_call(text)
259 mock_logger_error.assert_not_called()
261 def test_prepare_env_testname_invalid(self):
262 self.rally_base.TESTS = ['test1', 'test2']
263 self.rally_base.test_name = 'test'
264 with self.assertRaises(Exception):
265 self.rally_base._prepare_env()
267 @mock.patch('functest.utils.functest_utils.get_external_network')
268 def test_prepare_env_image_missing(self, *args):
269 # pylint: disable=unused-argument
270 self.rally_base.TESTS = ['test1', 'test2']
271 self.rally_base.test_name = 'test1'
272 with mock.patch.object(self.rally_base.cloud, 'list_hypervisors'), \
273 mock.patch.object(self.rally_base.cloud, 'create_image',
275 with self.assertRaises(Exception):
276 self.rally_base._prepare_env()
278 @mock.patch('functest.utils.functest_utils.get_external_network')
279 def test_prepare_env_network_creation_failed(self, *args):
280 # pylint: disable=unused-argument
281 self.rally_base.TESTS = ['test1', 'test2']
282 self.rally_base.test_name = 'test1'
283 with mock.patch.object(self.rally_base.cloud,
284 'list_hypervisors') as mock_list_hyperv, \
285 mock.patch.object(self.rally_base.cloud,
286 'create_image') as mock_create_img, \
287 mock.patch.object(self.rally_base.cloud, 'create_network',
288 return_value=None) as mock_create_net:
289 with self.assertRaises(Exception):
290 self.rally_base._prepare_env()
291 mock_create_net.assert_called()
292 mock_create_img.assert_called()
293 mock_list_hyperv.assert_called()
295 @mock.patch('functest.utils.functest_utils.get_external_network')
296 def test_prepare_env_subnet_creation_failed(self, *args):
297 # pylint: disable=unused-argument
298 self.rally_base.TESTS = ['test1', 'test2']
299 self.rally_base.test_name = 'test1'
300 with mock.patch.object(self.rally_base.cloud,
301 'list_hypervisors') as mock_list_hyperv, \
302 mock.patch.object(self.rally_base.cloud,
303 'create_image') as mock_create_img, \
304 mock.patch.object(self.rally_base.cloud,
305 'create_network') as mock_create_net, \
306 mock.patch.object(self.rally_base.cloud, 'create_subnet',
307 return_value=None) as mock_create_subnet:
308 with self.assertRaises(Exception):
309 self.rally_base._prepare_env()
310 mock_create_subnet.assert_called()
311 mock_create_net.assert_called()
312 mock_create_img.assert_called()
313 mock_list_hyperv.assert_called()
315 @mock.patch('functest.utils.functest_utils.get_external_network')
316 def test_prepare_env_router_creation_failed(self, *args):
317 # pylint: disable=unused-argument
318 self.rally_base.TESTS = ['test1', 'test2']
319 self.rally_base.test_name = 'test1'
320 with mock.patch.object(self.rally_base.cloud,
321 'list_hypervisors') as mock_list_hyperv, \
322 mock.patch.object(self.rally_base.cloud,
323 'create_image') as mock_create_img, \
324 mock.patch.object(self.rally_base.cloud,
325 'create_network') as mock_create_net, \
326 mock.patch.object(self.rally_base.cloud,
327 'create_subnet') as mock_create_subnet, \
328 mock.patch.object(self.rally_base.cloud, 'create_router',
329 return_value=None) as mock_create_router:
330 with self.assertRaises(Exception):
331 self.rally_base._prepare_env()
332 mock_create_router.assert_called()
333 mock_create_subnet.assert_called()
334 mock_create_net.assert_called()
335 mock_create_img.assert_called()
336 mock_list_hyperv.assert_called()
338 @mock.patch('functest.utils.functest_utils.get_external_network')
339 def test_prepare_env_flavor_creation_failed(self, *args):
340 # pylint: disable=unused-argument
341 self.rally_base.TESTS = ['test1', 'test2']
342 self.rally_base.test_name = 'test1'
343 with mock.patch.object(self.rally_base.cloud,
344 'list_hypervisors') as mock_list_hyperv, \
345 mock.patch.object(self.rally_base.cloud,
346 'create_image') as mock_create_img, \
347 mock.patch.object(self.rally_base.cloud,
348 'create_network') as mock_create_net, \
349 mock.patch.object(self.rally_base.cloud,
350 'create_subnet') as mock_create_subnet, \
351 mock.patch.object(self.rally_base.cloud,
352 'add_router_interface') as mock_add_router_if, \
353 mock.patch.object(self.rally_base.cloud,
354 'create_router') as mock_create_router, \
355 mock.patch.object(self.rally_base.cloud, 'create_flavor',
356 return_value=None) as mock_create_flavor:
357 with self.assertRaises(Exception):
358 self.rally_base._prepare_env()
359 mock_create_flavor.assert_called_once()
360 mock_add_router_if.assert_called()
361 mock_create_router.assert_called()
362 mock_create_subnet.assert_called()
363 mock_create_net.assert_called()
364 mock_create_img.assert_called()
365 mock_list_hyperv.assert_called()
367 @mock.patch('functest.utils.functest_utils.get_external_network')
368 def test_prepare_env_flavor_alt_creation_failed(self, *args):
369 # pylint: disable=unused-argument
370 self.rally_base.TESTS = ['test1', 'test2']
371 self.rally_base.test_name = 'test1'
372 with mock.patch.object(self.rally_base.cloud,
373 'list_hypervisors') as mock_list_hyperv, \
374 mock.patch.object(self.rally_base.cloud,
375 'create_image') as mock_create_img, \
376 mock.patch.object(self.rally_base.cloud,
377 'create_network') as mock_create_net, \
378 mock.patch.object(self.rally_base.cloud,
379 'create_subnet') as mock_create_subnet, \
380 mock.patch.object(self.rally_base.cloud,
381 'add_router_interface') as mock_add_router_if, \
382 mock.patch.object(self.rally_base.cloud,
383 'create_router') as mock_create_router, \
384 mock.patch.object(self.rally_base.cloud,
385 'set_flavor_specs') as mock_set_flavor_specs, \
386 mock.patch.object(self.rally_base.cloud, 'create_flavor',
387 side_effect=[mock.Mock(), None]) \
388 as mock_create_flavor:
389 with self.assertRaises(Exception):
390 self.rally_base._prepare_env()
391 self.assertEqual(mock_create_flavor.call_count, 2)
392 mock_set_flavor_specs.assert_called_once()
393 mock_add_router_if.assert_called()
394 mock_create_router.assert_called()
395 mock_create_subnet.assert_called()
396 mock_create_net.assert_called()
397 mock_create_img.assert_called()
398 mock_list_hyperv.assert_called()
400 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
402 def test_run_tests_all(self, mock_run_task):
403 self.rally_base.TESTS = ['test1', 'test2']
404 self.rally_base.test_name = 'all'
405 self.rally_base._run_tests()
406 mock_run_task.assert_any_call('test1')
407 mock_run_task.assert_any_call('test2')
409 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
411 def test_run_tests_default(self, mock_run_task):
412 self.rally_base.TESTS = ['test1', 'test2']
413 self.rally_base.test_name = 'test1'
414 self.rally_base._run_tests()
415 mock_run_task.assert_any_call('test1')
417 def test_clean_up_default(self):
418 with mock.patch.object(self.rally_base.cloud,
419 'delete_flavor') as mock_delete_flavor, \
420 mock.patch.object(self.rally_base.cloud,
421 'remove_router_interface') \
422 as mock_remove_router_if, \
423 mock.patch.object(self.rally_base.cloud,
424 'delete_router') as mock_delete_router, \
425 mock.patch.object(self.rally_base.cloud,
426 'delete_subnet') as mock_delete_subnet, \
427 mock.patch.object(self.rally_base.cloud,
428 'delete_network') as mock_delete_net, \
429 mock.patch.object(self.rally_base.cloud,
430 'delete_image') as mock_delete_img:
431 self.rally_base.flavor_alt = mock.Mock()
432 self.rally_base.flavor = mock.Mock()
433 self.rally_base.router = mock.Mock()
434 self.rally_base.subnet = mock.Mock()
435 self.rally_base.network = mock.Mock()
436 self.rally_base.image = mock.Mock()
437 self.rally_base._clean_up()
438 self.assertEqual(mock_delete_flavor.call_count, 2)
439 mock_remove_router_if.assert_called()
440 mock_delete_router.assert_called()
441 mock_delete_subnet.assert_called()
442 mock_delete_net.assert_called()
443 mock_delete_img.assert_called()
445 @mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
446 'create_rally_deployment')
447 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
449 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
451 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
453 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
455 def test_run_default(self, *args):
456 self.assertEqual(self.rally_base.run(), testcase.TestCase.EX_OK)
460 @mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
461 'create_rally_deployment', side_effect=Exception)
462 def test_run_exception_create_rally_dep(self, mock_create_rally_dep):
463 self.assertEqual(self.rally_base.run(), testcase.TestCase.EX_RUN_ERROR)
464 mock_create_rally_dep.assert_called()
466 @mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
467 'create_rally_deployment', return_value=mock.Mock())
468 @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
469 '_prepare_env', side_effect=Exception)
470 def test_run_exception_prepare_env(self, mock_prep_env, *args):
471 # pylint: disable=unused-argument
472 self.assertEqual(self.rally_base.run(), testcase.TestCase.EX_RUN_ERROR)
473 mock_prep_env.assert_called()
475 def test_append_summary(self):
476 text = '[{"result":[{"error":[]},{"error":["err"]}],' \
477 '"full_duration": 17.312026}]'
478 self.rally_base._append_summary(text, "foo_test")
479 self.assertEqual(self.rally_base.summary[0]['test_name'], "foo_test")
480 self.assertEqual(self.rally_base.summary[0]['overall_duration'],
482 self.assertEqual(self.rally_base.summary[0]['nb_tests'], 2)
483 self.assertEqual(self.rally_base.summary[0]['nb_success'], 1)
486 if __name__ == "__main__":
487 logging.disable(logging.CRITICAL)
488 unittest.main(verbosity=2)