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
13 from functest.ci import prepare_env
14 from functest.tests.unit import test_utils
15 from functest.utils.constants import CONST
16 from opnfv.utils import constants as opnfv_constants
19 class PrepareEnvTesting(unittest.TestCase):
21 logging.disable(logging.CRITICAL)
24 self.prepare_envparser = prepare_env.PrepareEnvParser()
26 @mock.patch('functest.ci.prepare_env.logger.info')
27 def test_print_separator(self, mock_logger_info):
28 str = "=============================================="
29 prepare_env.print_separator()
30 mock_logger_info.assert_called_once_with(str)
32 @mock.patch('functest.ci.prepare_env.logger.info')
33 @mock.patch('functest.ci.prepare_env.logger.warning')
34 def test_check_env_variables_missing_inst_type(self, mock_logger_warn,
36 CONST.__setattr__('INSTALLER_TYPE', None)
37 prepare_env.check_env_variables()
38 mock_logger_info.assert_any_call("Checking environment variables"
40 mock_logger_warn.assert_any_call("The env variable 'INSTALLER_TYPE'"
43 @mock.patch('functest.ci.prepare_env.logger.info')
44 @mock.patch('functest.ci.prepare_env.logger.warning')
45 def test_check_env_variables_missing_inst_ip(self, mock_logger_warn,
47 CONST.__setattr__('INSTALLER_IP', None)
48 prepare_env.check_env_variables()
49 mock_logger_info.assert_any_call("Checking environment variables"
51 mock_logger_warn.assert_any_call("The env variable 'INSTALLER_IP'"
52 " is not defined. It is needed to"
53 " fetch the OpenStack credentials."
54 " If the credentials are not"
55 " provided to the container as a"
56 " volume, please add this env"
57 " variable to the 'docker run'"
60 @mock.patch('functest.ci.prepare_env.logger.info')
61 @mock.patch('functest.ci.prepare_env.logger.warning')
62 def test_check_env_variables_with_inst_ip(self, mock_logger_warn,
64 CONST.__setattr__('INSTALLER_IP', mock.Mock())
65 prepare_env.check_env_variables()
66 mock_logger_info.assert_any_call("Checking environment variables"
68 mock_logger_info.assert_any_call(test_utils.
69 SubstrMatch(" INSTALLER_IP="))
71 @mock.patch('functest.ci.prepare_env.logger.info')
72 @mock.patch('functest.ci.prepare_env.logger.warning')
73 def test_check_env_variables_missing_scenario(self, mock_logger_warn,
75 CONST.__setattr__('DEPLOY_SCENARIO', None)
76 prepare_env.check_env_variables()
77 mock_logger_info.assert_any_call("Checking environment variables"
79 mock_logger_warn.assert_any_call("The env variable"
80 " 'DEPLOY_SCENARIO' is not defined"
81 ". Setting CI_SCENARIO=undefined.")
83 @mock.patch('functest.ci.prepare_env.logger.info')
84 @mock.patch('functest.ci.prepare_env.logger.warning')
85 def test_check_env_variables_with_scenario(self, mock_logger_warn,
87 CONST.__setattr__('DEPLOY_SCENARIO', 'test_scenario')
88 prepare_env.check_env_variables()
89 mock_logger_info.assert_any_call("Checking environment variables"
91 mock_logger_info.assert_any_call(test_utils.
92 SubstrMatch("DEPLOY_SCENARIO="))
94 @mock.patch('functest.ci.prepare_env.logger.info')
95 @mock.patch('functest.ci.prepare_env.logger.warning')
96 def test_check_env_variables_with_ci_debug(self, mock_logger_warn,
98 CONST.__setattr__('CI_DEBUG', mock.Mock())
99 prepare_env.check_env_variables()
100 mock_logger_info.assert_any_call("Checking environment variables"
102 mock_logger_info.assert_any_call(test_utils.
103 SubstrMatch(" CI_DEBUG="))
105 @mock.patch('functest.ci.prepare_env.logger.info')
106 @mock.patch('functest.ci.prepare_env.logger.warning')
107 def test_check_env_variables_with_node(self, mock_logger_warn,
109 CONST.__setattr__('NODE_NAME', mock.Mock())
110 prepare_env.check_env_variables()
111 mock_logger_info.assert_any_call("Checking environment variables"
113 mock_logger_info.assert_any_call(test_utils.
114 SubstrMatch(" NODE_NAME="))
116 @mock.patch('functest.ci.prepare_env.logger.info')
117 @mock.patch('functest.ci.prepare_env.logger.warning')
118 def test_check_env_variables_with_build_tag(self, mock_logger_warn,
120 CONST.__setattr__('BUILD_TAG', mock.Mock())
121 prepare_env.check_env_variables()
122 mock_logger_info.assert_any_call("Checking environment variables"
125 mock_logger_info.assert_any_call(test_utils.
126 SubstrMatch(" BUILD_TAG="))
128 @mock.patch('functest.ci.prepare_env.logger.info')
129 @mock.patch('functest.ci.prepare_env.logger.warning')
130 def test_check_env_variables_with_is_ci_run(self, mock_logger_warn,
132 CONST.__setattr__('IS_CI_RUN', mock.Mock())
133 prepare_env.check_env_variables()
134 mock_logger_info.assert_any_call("Checking environment variables"
137 mock_logger_info.assert_any_call(test_utils.
138 SubstrMatch(" IS_CI_RUN="))
140 def test_get_deployment_handler_missing_const_vars(self):
141 with mock.patch('functest.ci.prepare_env.'
142 'factory.Factory.get_handler') as m:
143 CONST.__setattr__('INSTALLER_IP', None)
144 prepare_env.get_deployment_handler()
145 self.assertFalse(m.called)
147 CONST.__setattr__('INSTALLER_TYPE', None)
148 prepare_env.get_deployment_handler()
149 self.assertFalse(m.called)
151 @mock.patch('functest.ci.prepare_env.logger.debug')
152 def test_get_deployment_handler_missing_print_deploy_info(self,
154 with mock.patch('functest.ci.prepare_env.'
155 'factory.Factory.get_handler') as m, \
156 mock.patch('functest.ci.prepare_env.'
157 'ft_utils.get_parameter_from_yaml',
158 side_effect=ValueError):
159 CONST.__setattr__('INSTALLER_IP', 'test_ip')
160 CONST.__setattr__('INSTALLER_TYPE', 'test_inst_type')
161 opnfv_constants.INSTALLERS = ['test_inst_type']
162 prepare_env.get_deployment_handler()
163 msg = ('Printing deployment info is not supported for '
165 mock_debug.assert_any_call(msg)
166 self.assertFalse(m.called)
168 @mock.patch('functest.ci.prepare_env.logger.debug')
169 def test_get_deployment_handler_exception(self, mock_debug):
170 with mock.patch('functest.ci.prepare_env.'
171 'factory.Factory.get_handler',
172 side_effect=Exception), \
173 mock.patch('functest.ci.prepare_env.'
174 'ft_utils.get_parameter_from_yaml'):
175 CONST.__setattr__('INSTALLER_IP', 'test_ip')
176 CONST.__setattr__('INSTALLER_TYPE', 'test_inst_type')
177 opnfv_constants.INSTALLERS = ['test_inst_type']
178 prepare_env.get_deployment_handler()
179 self.assertTrue(mock_debug.called)
181 @mock.patch('functest.ci.prepare_env.logger.info')
182 @mock.patch('functest.ci.prepare_env.logger.debug')
183 def test_create_directories_missing_dir(self, mock_logger_debug,
185 with mock.patch('functest.ci.prepare_env.os.path.exists',
186 return_value=False), \
187 mock.patch('functest.ci.prepare_env.os.makedirs') \
189 prepare_env.create_directories()
190 mock_logger_info.assert_any_call("Creating needed directories...")
191 mock_method.assert_any_call(
192 CONST.__getattribute__('dir_functest_conf'))
193 mock_method.assert_any_call(
194 CONST.__getattribute__('dir_functest_data'))
195 mock_logger_info.assert_any_call(" %s created." %
196 CONST.__getattribute__(
197 'dir_functest_conf'))
198 mock_logger_info.assert_any_call(" %s created." %
199 CONST.__getattribute__(
200 'dir_functest_data'))
202 @mock.patch('functest.ci.prepare_env.logger.info')
203 @mock.patch('functest.ci.prepare_env.logger.debug')
204 def test_create_directories_with_dir(self, mock_logger_debug,
206 with mock.patch('functest.ci.prepare_env.os.path.exists',
208 prepare_env.create_directories()
209 mock_logger_info.assert_any_call("Creating needed directories...")
210 mock_logger_debug.assert_any_call(" %s already exists." %
211 CONST.__getattribute__(
212 'dir_functest_conf'))
213 mock_logger_debug.assert_any_call(" %s already exists." %
214 CONST.__getattribute__(
215 'dir_functest_data'))
217 def _get_env_cred_dict(self, os_prefix=''):
218 return {'OS_USERNAME': os_prefix + 'username',
219 'OS_PASSWORD': os_prefix + 'password',
220 'OS_AUTH_URL': 'http://test_ip:test_port/v2.0',
221 'OS_TENANT_NAME': os_prefix + 'tenant_name',
222 'OS_USER_DOMAIN_NAME': os_prefix + 'user_domain_name',
223 'OS_PROJECT_DOMAIN_NAME': os_prefix + 'project_domain_name',
224 'OS_PROJECT_NAME': os_prefix + 'project_name',
225 'OS_ENDPOINT_TYPE': os_prefix + 'endpoint_type',
226 'OS_REGION_NAME': os_prefix + 'region_name'}
228 @mock.patch('functest.ci.prepare_env.logger.error')
229 @mock.patch('functest.ci.prepare_env.logger.info')
230 @mock.patch('functest.ci.prepare_env.logger.warning')
231 def test_source_rc_missing_rc_file(self, mock_logger_warn,
234 with mock.patch('functest.ci.prepare_env.os.path.isfile',
235 return_value=True), \
236 mock.patch('functest.ci.prepare_env.os.path.getsize',
238 self.assertRaises(Exception):
239 CONST.__setattr__('openstack_creds', 'test_creds')
240 prepare_env.source_rc_file()
242 def test_source_rc_missing_installer_ip(self):
243 with mock.patch('functest.ci.prepare_env.os.path.isfile',
244 return_value=False), \
245 self.assertRaises(Exception):
246 CONST.__setattr__('INSTALLER_IP', None)
247 CONST.__setattr__('openstack_creds', 'test_creds')
248 prepare_env.source_rc_file()
250 def test_source_rc_missing_installer_type(self):
251 with mock.patch('functest.ci.prepare_env.os.path.isfile',
252 return_value=False), \
253 self.assertRaises(Exception):
254 CONST.__setattr__('INSTALLER_IP', 'test_ip')
255 CONST.__setattr__('openstack_creds', 'test_creds')
256 CONST.__setattr__('INSTALLER_TYPE', 'test_type')
257 opnfv_constants.INSTALLERS = []
258 prepare_env.source_rc_file()
260 def test_source_rc_missing_os_credfile_ci_inst(self):
261 with mock.patch('functest.ci.prepare_env.os.path.isfile',
262 return_value=False), \
263 mock.patch('functest.ci.prepare_env.os.path.getsize'), \
264 mock.patch('functest.ci.prepare_env.os.path.join'), \
265 mock.patch('functest.ci.prepare_env.subprocess.Popen') \
266 as mock_subproc_popen, \
267 self.assertRaises(Exception):
268 CONST.__setattr__('openstack_creds', 'test_creds')
269 CONST.__setattr__('INSTALLER_IP', None)
270 CONST.__setattr__('INSTALLER_TYPE', 'test_type')
271 opnfv_constants.INSTALLERS = ['test_type']
273 process_mock = mock.Mock()
274 attrs = {'communicate.return_value': ('output', 'error'),
276 process_mock.configure_mock(**attrs)
277 mock_subproc_popen.return_value = process_mock
279 prepare_env.source_rc_file()
281 @mock.patch('functest.ci.prepare_env.logger.debug')
282 def test_patch_file(self, mock_logger_debug):
283 with mock.patch("__builtin__.open", mock.mock_open()), \
284 mock.patch('functest.ci.prepare_env.yaml.safe_load',
285 return_value={'test_scenario': {'tkey': 'tvalue'}}), \
286 mock.patch('functest.ci.prepare_env.ft_utils.get_functest_yaml',
287 return_value={'tkey1': 'tvalue1'}), \
288 mock.patch('functest.ci.prepare_env.os.remove') as m, \
289 mock.patch('functest.ci.prepare_env.yaml.dump'):
290 CONST.__setattr__('DEPLOY_SCENARIO', 'test_scenario')
291 prepare_env.patch_file('test_file')
292 self.assertTrue(m.called)
294 @mock.patch('functest.ci.prepare_env.logger.info')
295 def test_verify_deployment_error(self, mock_logger_error):
296 mock_popen = mock.Mock()
297 attrs = {'poll.return_value': None,
298 'stdout.readline.return_value': 'ERROR'}
299 mock_popen.configure_mock(**attrs)
301 with mock.patch('functest.ci.prepare_env.print_separator') as m, \
302 mock.patch('functest.ci.prepare_env.subprocess.Popen',
303 return_value=mock_popen), \
304 self.assertRaises(Exception) as context:
305 prepare_env.verify_deployment()
306 self.assertTrue(m.called)
307 msg = "Problem while running 'check_os.sh'."
308 mock_logger_error.assert_called_once_with('ERROR')
309 self.assertTrue(msg in context)
311 def _get_rally_creds(self):
312 return {"type": "ExistingCloud",
313 "admin": {"username": 'test_user_name',
314 "password": 'test_password',
315 "tenant": 'test_tenant'}}
317 @mock.patch('functest.ci.prepare_env.os_utils.get_credentials_for_rally')
318 @mock.patch('functest.ci.prepare_env.logger.info')
319 @mock.patch('functest.ci.prepare_env.ft_utils.execute_command_raise')
320 @mock.patch('functest.ci.prepare_env.ft_utils.execute_command')
321 def test_install_rally(self, mock_exec, mock_exec_raise, mock_logger_info,
324 mock_os_utils.return_value = self._get_rally_creds()
326 prepare_env.install_rally()
328 cmd = "rally deployment destroy opnfv-rally"
329 error_msg = "Deployment %s does not exist." % \
330 CONST.__getattribute__('rally_deployment_name')
331 mock_logger_info.assert_any_call("Creating Rally environment...")
332 mock_exec.assert_any_call(cmd, error_msg=error_msg, verbose=False)
334 cmd = "rally deployment create --file=rally_conf.json --name="
335 cmd += CONST.__getattribute__('rally_deployment_name')
336 error_msg = "Problem while creating Rally deployment"
337 mock_exec_raise.assert_any_call(cmd, error_msg=error_msg)
339 cmd = "rally deployment check"
340 error_msg = ("OpenStack not responding or "
341 "faulty Rally deployment.")
342 mock_exec_raise.assert_any_call(cmd, error_msg=error_msg)
344 cmd = "rally deployment list"
345 error_msg = ("Problem while listing "
347 mock_exec.assert_any_call(cmd, error_msg=error_msg)
349 cmd = "rally plugin list | head -5"
350 error_msg = ("Problem while showing "
352 mock_exec.assert_any_call(cmd, error_msg=error_msg)
354 @mock.patch('functest.ci.prepare_env.logger.debug')
355 def test_install_tempest(self, mock_logger_debug):
356 mock_popen = mock.Mock()
357 attrs = {'poll.return_value': None,
358 'stdout.readline.return_value': '0'}
359 mock_popen.configure_mock(**attrs)
361 CONST.__setattr__('tempest_deployment_name', 'test_dep_name')
362 with mock.patch('functest.ci.prepare_env.'
363 'ft_utils.execute_command_raise',
364 side_effect=Exception), \
365 mock.patch('functest.ci.prepare_env.subprocess.Popen',
366 return_value=mock_popen), \
367 self.assertRaises(Exception):
368 prepare_env.install_tempest()
369 mock_logger_debug.assert_any_call("Tempest test_dep_name"
372 def test_create_flavor(self):
373 with mock.patch('functest.ci.prepare_env.'
374 'os_utils.get_or_create_flavor',
375 return_value=('test_', None)), \
376 self.assertRaises(Exception) as context:
377 prepare_env.create_flavor()
378 msg = 'Failed to create flavor'
379 self.assertTrue(msg in context)
381 @mock.patch('functest.ci.prepare_env.sys.exit')
382 @mock.patch('functest.ci.prepare_env.logger.error')
383 def test_check_environment_missing_file(self, mock_logger_error,
385 with mock.patch('functest.ci.prepare_env.os.path.isfile',
386 return_value=False), \
387 self.assertRaises(Exception):
388 prepare_env.check_environment()
390 @mock.patch('functest.ci.prepare_env.sys.exit')
391 @mock.patch('functest.ci.prepare_env.logger.error')
392 def test_check_environment_with_error(self, mock_logger_error,
394 with mock.patch('functest.ci.prepare_env.os.path.isfile',
395 return_value=True), \
396 mock.patch("__builtin__.open", mock.mock_open(read_data='0')), \
397 self.assertRaises(Exception):
398 prepare_env.check_environment()
400 @mock.patch('functest.ci.prepare_env.logger.info')
401 def test_check_environment_default(self, mock_logger_info):
402 with mock.patch('functest.ci.prepare_env.os.path.isfile',
404 with mock.patch("__builtin__.open", mock.mock_open(read_data='1')):
405 prepare_env.check_environment()
406 mock_logger_info.assert_any_call("Functest environment"
409 @mock.patch('functest.ci.prepare_env.print_deployment_info')
410 @mock.patch('functest.ci.prepare_env.check_environment')
411 @mock.patch('functest.ci.prepare_env.create_flavor')
412 @mock.patch('functest.ci.prepare_env.install_tempest')
413 @mock.patch('functest.ci.prepare_env.install_rally')
414 @mock.patch('functest.ci.prepare_env.verify_deployment')
415 @mock.patch('functest.ci.prepare_env.patch_config_file')
416 @mock.patch('functest.ci.prepare_env.source_rc_file')
417 @mock.patch('functest.ci.prepare_env.create_directories')
418 @mock.patch('functest.ci.prepare_env.get_deployment_handler')
419 @mock.patch('functest.ci.prepare_env.check_env_variables')
420 @mock.patch('functest.ci.prepare_env.logger.info')
421 def test_main_start(self, mock_logger_info, mock_env_var, mock_dep_handler,
422 mock_create_dir, mock_source_rc, mock_patch_config,
423 mock_verify_depl, mock_install_rally,
424 mock_install_temp, mock_create_flavor,
425 mock_check_env, mock_print_info):
426 with mock.patch("__builtin__.open", mock.mock_open()) as m:
427 args = {'action': 'start'}
428 self.assertEqual(prepare_env.main(**args), 0)
429 mock_logger_info.assert_any_call("######### Preparing Functest "
430 "environment #########\n")
431 self.assertTrue(mock_env_var.called)
432 self.assertTrue(mock_dep_handler.called)
433 self.assertTrue(mock_create_dir.called)
434 self.assertTrue(mock_source_rc.called)
435 self.assertTrue(mock_patch_config.called)
436 self.assertTrue(mock_verify_depl.called)
437 self.assertTrue(mock_install_rally.called)
438 self.assertTrue(mock_install_temp.called)
439 self.assertTrue(mock_create_flavor.called)
440 m.assert_called_once_with(
441 CONST.__getattribute__('env_active'), "w")
442 self.assertTrue(mock_check_env.called)
443 self.assertTrue(mock_print_info.called)
445 @mock.patch('functest.ci.prepare_env.check_environment')
446 def test_main_check(self, mock_check_env):
447 args = {'action': 'check'}
448 self.assertEqual(prepare_env.main(**args), 0)
449 self.assertTrue(mock_check_env.called)
451 @mock.patch('functest.ci.prepare_env.logger.error')
452 def test_main_no_arg(self, mock_logger_error):
453 args = {'action': 'not_valid'}
454 self.assertEqual(prepare_env.main(**args), -1)
455 mock_logger_error.assert_called_once_with('Argument not valid.')
458 if __name__ == "__main__":
459 unittest.main(verbosity=2)