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):
22 self.prepare_envparser = prepare_env.PrepareEnvParser()
24 @mock.patch('functest.ci.prepare_env.logger.info')
25 def test_print_separator(self, mock_logger_info):
26 str = "=============================================="
27 prepare_env.print_separator()
28 mock_logger_info.assert_called_once_with(str)
30 @mock.patch('functest.ci.prepare_env.logger.info')
31 @mock.patch('functest.ci.prepare_env.logger.warning')
32 def test_check_env_variables_missing_inst_type(self, mock_logger_warn,
34 CONST.__setattr__('INSTALLER_TYPE', None)
35 prepare_env.check_env_variables()
36 mock_logger_info.assert_any_call("Checking environment variables"
38 mock_logger_warn.assert_any_call("The env variable 'INSTALLER_TYPE'"
41 @mock.patch('functest.ci.prepare_env.logger.info')
42 @mock.patch('functest.ci.prepare_env.logger.warning')
43 def test_check_env_variables_missing_inst_ip(self, mock_logger_warn,
45 CONST.__setattr__('INSTALLER_IP', None)
46 prepare_env.check_env_variables()
47 mock_logger_info.assert_any_call("Checking environment variables"
49 mock_logger_warn.assert_any_call("The env variable 'INSTALLER_IP'"
50 " is not defined. It is needed to"
51 " fetch the OpenStack credentials."
52 " If the credentials are not"
53 " provided to the container as a"
54 " volume, please add this env"
55 " variable to the 'docker run'"
58 @mock.patch('functest.ci.prepare_env.logger.info')
59 @mock.patch('functest.ci.prepare_env.logger.warning')
60 def test_check_env_variables_with_inst_ip(self, mock_logger_warn,
62 CONST.__setattr__('INSTALLER_IP', mock.Mock())
63 prepare_env.check_env_variables()
64 mock_logger_info.assert_any_call("Checking environment variables"
66 mock_logger_info.assert_any_call(test_utils.
67 SubstrMatch(" INSTALLER_IP="))
69 @mock.patch('functest.ci.prepare_env.logger.info')
70 @mock.patch('functest.ci.prepare_env.logger.warning')
71 def test_check_env_variables_missing_scenario(self, mock_logger_warn,
73 CONST.__setattr__('DEPLOY_SCENARIO', None)
74 prepare_env.check_env_variables()
75 mock_logger_info.assert_any_call("Checking environment variables"
77 mock_logger_warn.assert_any_call("The env variable"
78 " 'DEPLOY_SCENARIO' is not defined"
79 ". Setting CI_SCENARIO=undefined.")
81 @mock.patch('functest.ci.prepare_env.logger.info')
82 @mock.patch('functest.ci.prepare_env.logger.warning')
83 def test_check_env_variables_with_scenario(self, mock_logger_warn,
85 CONST.__setattr__('DEPLOY_SCENARIO', 'test_scenario')
86 prepare_env.check_env_variables()
87 mock_logger_info.assert_any_call("Checking environment variables"
89 mock_logger_info.assert_any_call(test_utils.
90 SubstrMatch("DEPLOY_SCENARIO="))
92 @mock.patch('functest.ci.prepare_env.logger.info')
93 @mock.patch('functest.ci.prepare_env.logger.warning')
94 def test_check_env_variables_with_ci_debug(self, mock_logger_warn,
96 CONST.__setattr__('CI_DEBUG', mock.Mock())
97 prepare_env.check_env_variables()
98 mock_logger_info.assert_any_call("Checking environment variables"
100 mock_logger_info.assert_any_call(test_utils.
101 SubstrMatch(" CI_DEBUG="))
103 @mock.patch('functest.ci.prepare_env.logger.info')
104 @mock.patch('functest.ci.prepare_env.logger.warning')
105 def test_check_env_variables_with_node(self, mock_logger_warn,
107 CONST.__setattr__('NODE_NAME', mock.Mock())
108 prepare_env.check_env_variables()
109 mock_logger_info.assert_any_call("Checking environment variables"
111 mock_logger_info.assert_any_call(test_utils.
112 SubstrMatch(" NODE_NAME="))
114 @mock.patch('functest.ci.prepare_env.logger.info')
115 @mock.patch('functest.ci.prepare_env.logger.warning')
116 def test_check_env_variables_with_build_tag(self, mock_logger_warn,
118 CONST.__setattr__('BUILD_TAG', mock.Mock())
119 prepare_env.check_env_variables()
120 mock_logger_info.assert_any_call("Checking environment variables"
123 mock_logger_info.assert_any_call(test_utils.
124 SubstrMatch(" BUILD_TAG="))
126 @mock.patch('functest.ci.prepare_env.logger.info')
127 @mock.patch('functest.ci.prepare_env.logger.warning')
128 def test_check_env_variables_with_is_ci_run(self, mock_logger_warn,
130 CONST.__setattr__('IS_CI_RUN', mock.Mock())
131 prepare_env.check_env_variables()
132 mock_logger_info.assert_any_call("Checking environment variables"
135 mock_logger_info.assert_any_call(test_utils.
136 SubstrMatch(" IS_CI_RUN="))
138 def test_get_deployment_handler_missing_const_vars(self):
139 with mock.patch('functest.ci.prepare_env.'
140 'factory.Factory.get_handler') as m:
141 CONST.__setattr__('INSTALLER_IP', None)
142 prepare_env.get_deployment_handler()
143 self.assertFalse(m.called)
145 CONST.__setattr__('INSTALLER_TYPE', None)
146 prepare_env.get_deployment_handler()
147 self.assertFalse(m.called)
149 @mock.patch('functest.ci.prepare_env.logger.debug')
150 def test_get_deployment_handler_missing_print_deploy_info(self,
152 with mock.patch('functest.ci.prepare_env.'
153 'factory.Factory.get_handler') as m, \
154 mock.patch('functest.ci.prepare_env.'
155 'ft_utils.get_parameter_from_yaml',
156 side_effect=ValueError):
157 CONST.__setattr__('INSTALLER_IP', 'test_ip')
158 CONST.__setattr__('INSTALLER_TYPE', 'test_inst_type')
159 opnfv_constants.INSTALLERS = ['test_inst_type']
160 prepare_env.get_deployment_handler()
161 msg = ('Printing deployment info is not supported for '
163 mock_debug.assert_any_call(msg)
164 self.assertFalse(m.called)
166 @mock.patch('functest.ci.prepare_env.logger.debug')
167 def test_get_deployment_handler_exception(self, mock_debug):
168 with mock.patch('functest.ci.prepare_env.'
169 'factory.Factory.get_handler',
170 side_effect=Exception), \
171 mock.patch('functest.ci.prepare_env.'
172 'ft_utils.get_parameter_from_yaml'):
173 CONST.__setattr__('INSTALLER_IP', 'test_ip')
174 CONST.__setattr__('INSTALLER_TYPE', 'test_inst_type')
175 opnfv_constants.INSTALLERS = ['test_inst_type']
176 prepare_env.get_deployment_handler()
177 self.assertTrue(mock_debug.called)
179 @mock.patch('functest.ci.prepare_env.logger.info')
180 @mock.patch('functest.ci.prepare_env.logger.debug')
181 def test_create_directories_missing_dir(self, mock_logger_debug,
183 with mock.patch('functest.ci.prepare_env.os.path.exists',
184 return_value=False), \
185 mock.patch('functest.ci.prepare_env.os.makedirs') \
187 prepare_env.create_directories()
188 mock_logger_info.assert_any_call("Creating needed directories...")
189 mock_method.assert_any_call(
190 CONST.__getattribute__('dir_functest_conf'))
191 mock_method.assert_any_call(
192 CONST.__getattribute__('dir_functest_data'))
193 mock_method.assert_any_call(
194 CONST.__getattribute__('dir_functest_images'))
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'))
201 mock_logger_info.assert_any_call(" %s created." %
202 CONST.__getattribute__(
203 'dir_functest_images'))
205 @mock.patch('functest.ci.prepare_env.logger.info')
206 @mock.patch('functest.ci.prepare_env.logger.debug')
207 def test_create_directories_with_dir(self, mock_logger_debug,
209 with mock.patch('functest.ci.prepare_env.os.path.exists',
211 prepare_env.create_directories()
212 mock_logger_info.assert_any_call("Creating needed directories...")
213 mock_logger_debug.assert_any_call(" %s already exists." %
214 CONST.__getattribute__(
215 'dir_functest_conf'))
216 mock_logger_debug.assert_any_call(" %s already exists." %
217 CONST.__getattribute__(
218 'dir_functest_data'))
219 mock_logger_debug.assert_any_call(" %s already exists." %
220 CONST.__getattribute__(
221 'dir_functest_images'))
223 def _get_env_cred_dict(self, os_prefix=''):
224 return {'OS_USERNAME': os_prefix + 'username',
225 'OS_PASSWORD': os_prefix + 'password',
226 'OS_AUTH_URL': 'http://test_ip:test_port/v2.0',
227 'OS_TENANT_NAME': os_prefix + 'tenant_name',
228 'OS_USER_DOMAIN_NAME': os_prefix + 'user_domain_name',
229 'OS_PROJECT_DOMAIN_NAME': os_prefix + 'project_domain_name',
230 'OS_PROJECT_NAME': os_prefix + 'project_name',
231 'OS_ENDPOINT_TYPE': os_prefix + 'endpoint_type',
232 'OS_REGION_NAME': os_prefix + 'region_name'}
234 @mock.patch('functest.ci.prepare_env.logger.error')
235 @mock.patch('functest.ci.prepare_env.logger.info')
236 @mock.patch('functest.ci.prepare_env.logger.warning')
237 def test_source_rc_missing_rc_file(self, mock_logger_warn,
240 with mock.patch('functest.ci.prepare_env.os.path.isfile',
241 return_value=True), \
242 mock.patch('functest.ci.prepare_env.os.path.getsize',
244 self.assertRaises(Exception):
245 CONST.__setattr__('openstack_creds', 'test_creds')
246 prepare_env.source_rc_file()
248 def test_source_rc_missing_installer_ip(self):
249 with mock.patch('functest.ci.prepare_env.os.path.isfile',
250 return_value=False), \
251 self.assertRaises(Exception):
252 CONST.__setattr__('INSTALLER_IP', None)
253 CONST.__setattr__('openstack_creds', 'test_creds')
254 prepare_env.source_rc_file()
256 def test_source_rc_missing_installer_type(self):
257 with mock.patch('functest.ci.prepare_env.os.path.isfile',
258 return_value=False), \
259 self.assertRaises(Exception):
260 CONST.__setattr__('INSTALLER_IP', 'test_ip')
261 CONST.__setattr__('openstack_creds', 'test_creds')
262 CONST.__setattr__('INSTALLER_TYPE', 'test_type')
263 opnfv_constants.INSTALLERS = []
264 prepare_env.source_rc_file()
266 def test_source_rc_missing_os_credfile_ci_inst(self):
267 with mock.patch('functest.ci.prepare_env.os.path.isfile',
268 return_value=False), \
269 mock.patch('functest.ci.prepare_env.os.path.getsize'), \
270 mock.patch('functest.ci.prepare_env.os.path.join'), \
271 mock.patch('functest.ci.prepare_env.subprocess.Popen') \
272 as mock_subproc_popen, \
273 self.assertRaises(Exception):
274 CONST.__setattr__('openstack_creds', 'test_creds')
275 CONST.__setattr__('INSTALLER_IP', None)
276 CONST.__setattr__('INSTALLER_TYPE', 'test_type')
277 opnfv_constants.INSTALLERS = ['test_type']
279 process_mock = mock.Mock()
280 attrs = {'communicate.return_value': ('output', 'error'),
282 process_mock.configure_mock(**attrs)
283 mock_subproc_popen.return_value = process_mock
285 prepare_env.source_rc_file()
287 @mock.patch('functest.ci.prepare_env.logger.debug')
288 def test_patch_file(self, mock_logger_debug):
289 with mock.patch("__builtin__.open", mock.mock_open()), \
290 mock.patch('functest.ci.prepare_env.yaml.safe_load',
291 return_value={'test_scenario': {'tkey': 'tvalue'}}), \
292 mock.patch('functest.ci.prepare_env.ft_utils.get_functest_yaml',
293 return_value={'tkey1': 'tvalue1'}), \
294 mock.patch('functest.ci.prepare_env.os.remove') as m, \
295 mock.patch('functest.ci.prepare_env.yaml.dump'):
296 CONST.__setattr__('DEPLOY_SCENARIO', 'test_scenario')
297 prepare_env.patch_file('test_file')
298 self.assertTrue(m.called)
300 @mock.patch('functest.ci.prepare_env.logger.info')
301 def test_verify_deployment_error(self, mock_logger_error):
302 mock_popen = mock.Mock()
303 attrs = {'poll.return_value': None,
304 'stdout.readline.return_value': 'ERROR'}
305 mock_popen.configure_mock(**attrs)
307 with mock.patch('functest.ci.prepare_env.print_separator') as m, \
308 mock.patch('functest.ci.prepare_env.subprocess.Popen',
309 return_value=mock_popen), \
310 self.assertRaises(Exception) as context:
311 prepare_env.verify_deployment()
312 self.assertTrue(m.called)
313 msg = "Problem while running 'check_os.sh'."
314 mock_logger_error.assert_called_once_with('ERROR')
315 self.assertTrue(msg in context)
317 def _get_rally_creds(self):
318 return {"type": "ExistingCloud",
319 "admin": {"username": 'test_user_name',
320 "password": 'test_password',
321 "tenant": 'test_tenant'}}
323 @mock.patch('functest.ci.prepare_env.os_utils.get_credentials_for_rally')
324 @mock.patch('functest.ci.prepare_env.logger.info')
325 @mock.patch('functest.ci.prepare_env.ft_utils.execute_command_raise')
326 @mock.patch('functest.ci.prepare_env.ft_utils.execute_command')
327 def test_install_rally(self, mock_exec, mock_exec_raise, mock_logger_info,
330 mock_os_utils.return_value = self._get_rally_creds()
332 prepare_env.install_rally()
334 cmd = "rally deployment destroy opnfv-rally"
335 error_msg = "Deployment %s does not exist." % \
336 CONST.__getattribute__('rally_deployment_name')
337 mock_logger_info.assert_any_call("Creating Rally environment...")
338 mock_exec.assert_any_call(cmd, error_msg=error_msg, verbose=False)
340 cmd = "rally deployment create --file=rally_conf.json --name="
341 cmd += CONST.__getattribute__('rally_deployment_name')
342 error_msg = "Problem while creating Rally deployment"
343 mock_exec_raise.assert_any_call(cmd, error_msg=error_msg)
345 cmd = "rally deployment check"
346 error_msg = ("OpenStack not responding or "
347 "faulty Rally deployment.")
348 mock_exec_raise.assert_any_call(cmd, error_msg=error_msg)
350 cmd = "rally deployment list"
351 error_msg = ("Problem while listing "
353 mock_exec.assert_any_call(cmd, error_msg=error_msg)
355 cmd = "rally plugin list | head -5"
356 error_msg = ("Problem while showing "
358 mock_exec.assert_any_call(cmd, error_msg=error_msg)
360 @mock.patch('functest.ci.prepare_env.logger.debug')
361 def test_install_tempest(self, mock_logger_debug):
362 mock_popen = mock.Mock()
363 attrs = {'poll.return_value': None,
364 'stdout.readline.return_value': '0'}
365 mock_popen.configure_mock(**attrs)
367 CONST.__setattr__('tempest_deployment_name', 'test_dep_name')
368 with mock.patch('functest.ci.prepare_env.'
369 'ft_utils.execute_command_raise',
370 side_effect=Exception), \
371 mock.patch('functest.ci.prepare_env.subprocess.Popen',
372 return_value=mock_popen), \
373 self.assertRaises(Exception):
374 prepare_env.install_tempest()
375 mock_logger_debug.assert_any_call("Tempest test_dep_name"
378 def test_create_flavor(self):
379 with mock.patch('functest.ci.prepare_env.'
380 'os_utils.get_or_create_flavor',
381 return_value=('test_', None)), \
382 self.assertRaises(Exception) as context:
383 prepare_env.create_flavor()
384 msg = 'Failed to create flavor'
385 self.assertTrue(msg in context)
387 @mock.patch('functest.ci.prepare_env.sys.exit')
388 @mock.patch('functest.ci.prepare_env.logger.error')
389 def test_check_environment_missing_file(self, mock_logger_error,
391 with mock.patch('functest.ci.prepare_env.os.path.isfile',
392 return_value=False), \
393 self.assertRaises(Exception):
394 prepare_env.check_environment()
396 @mock.patch('functest.ci.prepare_env.sys.exit')
397 @mock.patch('functest.ci.prepare_env.logger.error')
398 def test_check_environment_with_error(self, mock_logger_error,
400 with mock.patch('functest.ci.prepare_env.os.path.isfile',
401 return_value=True), \
402 mock.patch("__builtin__.open", mock.mock_open(read_data='0')), \
403 self.assertRaises(Exception):
404 prepare_env.check_environment()
406 @mock.patch('functest.ci.prepare_env.logger.info')
407 def test_check_environment_default(self, mock_logger_info):
408 with mock.patch('functest.ci.prepare_env.os.path.isfile',
410 with mock.patch("__builtin__.open", mock.mock_open(read_data='1')):
411 prepare_env.check_environment()
412 mock_logger_info.assert_any_call("Functest environment"
415 @mock.patch('functest.ci.prepare_env.print_deployment_info')
416 @mock.patch('functest.ci.prepare_env.check_environment')
417 @mock.patch('functest.ci.prepare_env.create_flavor')
418 @mock.patch('functest.ci.prepare_env.install_tempest')
419 @mock.patch('functest.ci.prepare_env.install_rally')
420 @mock.patch('functest.ci.prepare_env.verify_deployment')
421 @mock.patch('functest.ci.prepare_env.patch_config_file')
422 @mock.patch('functest.ci.prepare_env.source_rc_file')
423 @mock.patch('functest.ci.prepare_env.create_directories')
424 @mock.patch('functest.ci.prepare_env.get_deployment_handler')
425 @mock.patch('functest.ci.prepare_env.check_env_variables')
426 @mock.patch('functest.ci.prepare_env.logger.info')
427 def test_main_start(self, mock_logger_info, mock_env_var, mock_dep_handler,
428 mock_create_dir, mock_source_rc, mock_patch_config,
429 mock_verify_depl, mock_install_rally,
430 mock_install_temp, mock_create_flavor,
431 mock_check_env, mock_print_info):
432 with mock.patch("__builtin__.open", mock.mock_open()) as m:
433 args = {'action': 'start'}
434 self.assertEqual(prepare_env.main(**args), 0)
435 mock_logger_info.assert_any_call("######### Preparing Functest "
436 "environment #########\n")
437 self.assertTrue(mock_env_var.called)
438 self.assertTrue(mock_dep_handler.called)
439 self.assertTrue(mock_create_dir.called)
440 self.assertTrue(mock_source_rc.called)
441 self.assertTrue(mock_patch_config.called)
442 self.assertTrue(mock_verify_depl.called)
443 self.assertTrue(mock_install_rally.called)
444 self.assertTrue(mock_install_temp.called)
445 self.assertTrue(mock_create_flavor.called)
446 m.assert_called_once_with(
447 CONST.__getattribute__('env_active'), "w")
448 self.assertTrue(mock_check_env.called)
449 self.assertTrue(mock_print_info.called)
451 @mock.patch('functest.ci.prepare_env.check_environment')
452 def test_main_check(self, mock_check_env):
453 args = {'action': 'check'}
454 self.assertEqual(prepare_env.main(**args), 0)
455 self.assertTrue(mock_check_env.called)
457 @mock.patch('functest.ci.prepare_env.logger.error')
458 def test_main_no_arg(self, mock_logger_error):
459 args = {'action': 'not_valid'}
460 self.assertEqual(prepare_env.main(**args), -1)
461 mock_logger_error.assert_called_once_with('Argument not valid.')
464 if __name__ == "__main__":
465 logging.disable(logging.CRITICAL)
466 unittest.main(verbosity=2)