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