6979932ef526695fc0d1a69ca6d093b9b8bb0694
[functest.git] / functest / tests / unit / utils / test_functest_utils.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2016 Orange and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 import logging
11 import pkg_resources
12 import os
13 import time
14 import unittest
15
16 import mock
17 from six.moves import urllib
18
19 from functest.utils import functest_utils
20
21
22 class FunctestUtilsTesting(unittest.TestCase):
23
24     readline = 0
25     test_ip = ['10.1.23.4', '10.1.14.15', '10.1.16.15']
26
27     def setUp(self):
28         self.url = 'http://www.opnfv.org/'
29         self.timeout = 5
30         self.dest_path = 'test_path'
31         self.repo_path = 'test_repo_path'
32         self.installer = 'test_installer'
33         self.scenario = 'test_scenario'
34         self.build_tag = 'jenkins-functest-fuel-opnfv-jump-2-daily-master-190'
35         self.build_tag_week = 'jenkins-functest-fuel-baremetal-weekly-master-8'
36         self.version = 'master'
37         self.node_name = 'test_node_name'
38         self.project = 'test_project'
39         self.case_name = 'test_case_name'
40         self.status = 'test_status'
41         self.details = 'test_details'
42         self.db_url = 'test_db_url'
43         self.criteria = 50
44         self.result = 75
45         self.start_date = 1482624000
46         self.stop_date = 1482624000
47         self.start_time = time.time()
48         self.stop_time = time.time()
49         self.readline = -1
50         self.test_ip = ['10.1.23.4', '10.1.14.15', '10.1.16.15']
51         self.test_file = 'test_file'
52         self.error_msg = 'test_error_msg'
53         self.cmd = 'test_cmd'
54         self.output_file = 'test_output_file'
55         self.testname = 'testname'
56         self.testcase_dict = {'case_name': 'testname',
57                               'criteria': self.criteria}
58         self.parameter = 'general.openstack.image_name'
59         self.config_yaml = pkg_resources.resource_filename(
60             'functest', 'ci/config_functest.yaml')
61         self.db_url_env = 'http://foo/testdb'
62         self.testcases_yaml = "test_testcases_yaml"
63         self.file_yaml = {'general': {'openstack': {'image_name':
64                                                     'test_image_name'}}}
65
66     @mock.patch('six.moves.urllib.request.urlopen',
67                 side_effect=urllib.error.URLError('no host given'))
68     def test_check_internet_connectivity_failed(self, mock_method):
69         self.assertFalse(functest_utils.check_internet_connectivity())
70         mock_method.assert_called_once_with(self.url, timeout=self.timeout)
71
72     @mock.patch('six.moves.urllib.request.urlopen')
73     def test_check_internet_connectivity_default(self, mock_method):
74         self.assertTrue(functest_utils.check_internet_connectivity())
75         mock_method.assert_called_once_with(self.url, timeout=self.timeout)
76
77     @mock.patch('six.moves.urllib.request.urlopen')
78     def test_check_internet_connectivity_debian(self, mock_method):
79         self.url = "https://www.debian.org/"
80         self.assertTrue(functest_utils.check_internet_connectivity(self.url))
81         mock_method.assert_called_once_with(self.url, timeout=self.timeout)
82
83     @mock.patch('six.moves.urllib.request.urlopen',
84                 side_effect=urllib.error.URLError('no host given'))
85     def test_download_url_failed(self, mock_url):
86         self.assertFalse(functest_utils.download_url(self.url, self.dest_path))
87
88     @mock.patch('six.moves.urllib.request.urlopen')
89     def test_download_url_default(self, mock_url):
90         with mock.patch("six.moves.builtins.open", mock.mock_open()) as m, \
91                 mock.patch('functest.utils.functest_utils.shutil.copyfileobj')\
92                 as mock_sh:
93             name = self.url.rsplit('/')[-1]
94             dest = self.dest_path + "/" + name
95             self.assertTrue(functest_utils.download_url(self.url,
96                                                         self.dest_path))
97             m.assert_called_once_with(dest, 'wb')
98             self.assertTrue(mock_sh.called)
99
100     def _get_env_dict(self, var):
101         dic = {'INSTALLER_TYPE': self.installer,
102                'DEPLOY_SCENARIO': self.scenario,
103                'NODE_NAME': self.node_name,
104                'BUILD_TAG': self.build_tag}
105         dic.pop(var, None)
106         return dic
107
108     @staticmethod
109     def readline_side():
110         if FunctestUtilsTesting.readline == \
111                 len(FunctestUtilsTesting.test_ip) - 1:
112             return False
113         FunctestUtilsTesting.readline += 1
114         return FunctestUtilsTesting.test_ip[FunctestUtilsTesting.readline]
115
116     # TODO: get_resolvconf_ns
117     @mock.patch('functest.utils.functest_utils.dns.resolver.Resolver')
118     def test_get_resolvconf_ns_default(self, mock_dns_resolve):
119         attrs = {'query.return_value': ["test"]}
120         mock_dns_resolve.configure_mock(**attrs)
121
122         m = mock.Mock()
123         attrs = {'readline.side_effect': self.readline_side}
124         m.configure_mock(**attrs)
125
126         with mock.patch("six.moves.builtins.open") as mo:
127             mo.return_value = m
128             self.assertEqual(functest_utils.get_resolvconf_ns(),
129                              self.test_ip[1:])
130
131     def _get_environ(self, var):
132         if var == 'INSTALLER_TYPE':
133             return self.installer
134         elif var == 'DEPLOY_SCENARIO':
135             return self.scenario
136         return var
137
138     def test_get_ci_envvars_default(self):
139         with mock.patch('os.environ.get',
140                         side_effect=self._get_environ):
141             dic = {"installer": self.installer,
142                    "scenario": self.scenario}
143             self.assertDictEqual(functest_utils.get_ci_envvars(), dic)
144
145     def cmd_readline(self):
146         return 'test_value\n'
147
148     @mock.patch('functest.utils.functest_utils.logger.error')
149     @mock.patch('functest.utils.functest_utils.logger.info')
150     def test_execute_command_args_present_with_error(self, mock_logger_info,
151                                                      mock_logger_error):
152         with mock.patch('functest.utils.functest_utils.subprocess.Popen') \
153                 as mock_subproc_open, \
154                 mock.patch('six.moves.builtins.open',
155                            mock.mock_open()) as mopen:
156
157             FunctestUtilsTesting.readline = 0
158
159             mock_obj = mock.Mock()
160             attrs = {'readline.side_effect': self.cmd_readline()}
161             mock_obj.configure_mock(**attrs)
162
163             mock_obj2 = mock.Mock()
164             attrs = {'stdout': mock_obj, 'wait.return_value': 1}
165             mock_obj2.configure_mock(**attrs)
166
167             mock_subproc_open.return_value = mock_obj2
168
169             resp = functest_utils.execute_command(self.cmd, info=True,
170                                                   error_msg=self.error_msg,
171                                                   verbose=True,
172                                                   output_file=self.output_file)
173             self.assertEqual(resp, 1)
174             msg_exec = ("Executing command: '%s'" % self.cmd)
175             mock_logger_info.assert_called_once_with(msg_exec)
176             mopen.assert_called_once_with(self.output_file, "w")
177             mock_logger_error.assert_called_once_with(self.error_msg)
178
179     @mock.patch('functest.utils.functest_utils.logger.info')
180     def test_execute_command_args_present_with_success(self, mock_logger_info,
181                                                        ):
182         with mock.patch('functest.utils.functest_utils.subprocess.Popen') \
183                 as mock_subproc_open, \
184                 mock.patch('six.moves.builtins.open',
185                            mock.mock_open()) as mopen:
186
187             FunctestUtilsTesting.readline = 0
188
189             mock_obj = mock.Mock()
190             attrs = {'readline.side_effect': self.cmd_readline()}
191             mock_obj.configure_mock(**attrs)
192
193             mock_obj2 = mock.Mock()
194             attrs = {'stdout': mock_obj, 'wait.return_value': 0}
195             mock_obj2.configure_mock(**attrs)
196
197             mock_subproc_open.return_value = mock_obj2
198
199             resp = functest_utils.execute_command(self.cmd, info=True,
200                                                   error_msg=self.error_msg,
201                                                   verbose=True,
202                                                   output_file=self.output_file)
203             self.assertEqual(resp, 0)
204             msg_exec = ("Executing command: '%s'" % self.cmd)
205             mock_logger_info.assert_called_once_with(msg_exec)
206             mopen.assert_called_once_with(self.output_file, "w")
207
208     @mock.patch('sys.stdout')
209     def test_execute_command_args_missing_with_success(self, stdout=None):
210         with mock.patch('functest.utils.functest_utils.subprocess.Popen') \
211                 as mock_subproc_open:
212
213             FunctestUtilsTesting.readline = 2
214
215             mock_obj = mock.Mock()
216             attrs = {'readline.side_effect': self.cmd_readline()}
217             mock_obj.configure_mock(**attrs)
218
219             mock_obj2 = mock.Mock()
220             attrs = {'stdout': mock_obj, 'wait.return_value': 0}
221             mock_obj2.configure_mock(**attrs)
222
223             mock_subproc_open.return_value = mock_obj2
224
225             resp = functest_utils.execute_command(self.cmd, info=False,
226                                                   error_msg="",
227                                                   verbose=False,
228                                                   output_file=None)
229             self.assertEqual(resp, 0)
230
231     @mock.patch('sys.stdout')
232     def test_execute_command_args_missing_with_error(self, stdout=None):
233         with mock.patch('functest.utils.functest_utils.subprocess.Popen') \
234                 as mock_subproc_open:
235
236             FunctestUtilsTesting.readline = 2
237             mock_obj = mock.Mock()
238             attrs = {'readline.side_effect': self.cmd_readline()}
239             mock_obj.configure_mock(**attrs)
240
241             mock_obj2 = mock.Mock()
242             attrs = {'stdout': mock_obj, 'wait.return_value': 1}
243             mock_obj2.configure_mock(**attrs)
244
245             mock_subproc_open.return_value = mock_obj2
246
247             resp = functest_utils.execute_command(self.cmd, info=False,
248                                                   error_msg="",
249                                                   verbose=False,
250                                                   output_file=None)
251             self.assertEqual(resp, 1)
252
253     def _get_functest_config(self, var):
254         return var
255
256     @mock.patch('functest.utils.functest_utils.logger.error')
257     def test_get_dict_by_test(self, mock_logger_error):
258         with mock.patch('six.moves.builtins.open', mock.mock_open()), \
259                 mock.patch('functest.utils.functest_utils.yaml.safe_load') \
260                 as mock_yaml:
261             mock_obj = mock.Mock()
262             attrs = {'get.return_value': [{'testcases': [self.testcase_dict]}]}
263             mock_obj.configure_mock(**attrs)
264
265             mock_yaml.return_value = mock_obj
266
267             self.assertDictEqual(functest_utils.
268                                  get_dict_by_test(self.testname),
269                                  self.testcase_dict)
270
271     @mock.patch('functest.utils.functest_utils.get_dict_by_test')
272     def test_get_criteria_by_test_default(self, mock_get_dict_by_test):
273         mock_get_dict_by_test.return_value = self.testcase_dict
274         self.assertEqual(functest_utils.get_criteria_by_test(self.testname),
275                          self.criteria)
276
277     @mock.patch('functest.utils.functest_utils.get_dict_by_test')
278     def test_get_criteria_by_test_failed(self, mock_get_dict_by_test):
279         mock_get_dict_by_test.return_value = None
280         self.assertIsNone(functest_utils.get_criteria_by_test(self.testname))
281
282     def test_get_parameter_from_yaml_failed(self):
283         self.file_yaml['general'] = None
284         with mock.patch('six.moves.builtins.open', mock.mock_open()), \
285                 mock.patch('functest.utils.functest_utils.yaml.safe_load') \
286                 as mock_yaml, \
287                 self.assertRaises(ValueError) as excep:
288             mock_yaml.return_value = self.file_yaml
289             functest_utils.get_parameter_from_yaml(self.parameter,
290                                                    self.test_file)
291             self.assertTrue(("The parameter %s is not"
292                              " defined in config_functest.yaml" %
293                              self.parameter) in excep.exception)
294
295     def test_get_parameter_from_yaml_default(self):
296         with mock.patch('six.moves.builtins.open', mock.mock_open()), \
297                 mock.patch('functest.utils.functest_utils.yaml.safe_load') \
298                 as mock_yaml:
299             mock_yaml.return_value = self.file_yaml
300             self.assertEqual(functest_utils.
301                              get_parameter_from_yaml(self.parameter,
302                                                      self.test_file),
303                              'test_image_name')
304
305     @mock.patch('functest.utils.functest_utils.get_parameter_from_yaml')
306     def test_get_functest_config_default(self, mock_get_parameter_from_yaml):
307         with mock.patch.dict(os.environ,
308                              {'CONFIG_FUNCTEST_YAML': self.config_yaml}):
309             functest_utils.get_functest_config(self.parameter)
310             mock_get_parameter_from_yaml. \
311                 assert_called_once_with(self.parameter,
312                                         self.config_yaml)
313
314     def test_get_functest_yaml(self):
315         with mock.patch('six.moves.builtins.open', mock.mock_open()), \
316                 mock.patch('functest.utils.functest_utils.yaml.safe_load') \
317                 as mock_yaml:
318             mock_yaml.return_value = self.file_yaml
319             resp = functest_utils.get_functest_yaml()
320             self.assertEqual(resp, self.file_yaml)
321
322     @mock.patch('functest.utils.functest_utils.logger.info')
323     def test_print_separator(self, mock_logger_info):
324         functest_utils.print_separator()
325         mock_logger_info.assert_called_once_with("======================="
326                                                  "=======================")
327
328
329 if __name__ == "__main__":
330     logging.disable(logging.CRITICAL)
331     unittest.main(verbosity=2)