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 run_tests
14 from functest.utils.constants import CONST
15 from functest.core.testcase import TestCase
18 class FakeModule(TestCase):
26 def is_successful(self):
30 class RunTestsTesting(unittest.TestCase):
33 self.runner = run_tests.Runner()
34 mock_test_case = mock.Mock()
35 mock_test_case.is_successful.return_value = TestCase.EX_OK
36 self.runner.executed_test_cases['test1'] = mock_test_case
37 self.runner.executed_test_cases['test2'] = mock_test_case
39 self.creds = {'OS_AUTH_URL': 'http://test_ip:test_port/v2.0',
40 'OS_USERNAME': 'test_os_username',
41 'OS_TENANT_NAME': 'test_tenant',
42 'OS_PASSWORD': 'test_password'}
43 self.test = {'test_name': 'test_name'}
44 self.tier = mock.Mock()
46 test1.get_name.return_value = 'test1'
48 test2.get_name.return_value = 'test2'
49 attrs = {'get_name.return_value': 'test_tier',
50 'get_tests.return_value': [test1, test2],
51 'get_ci_loop.return_value': 'test_ci_loop',
52 'get_test_names.return_value': ['test1', 'test2']}
53 self.tier.configure_mock(**attrs)
55 self.tiers = mock.Mock()
56 attrs = {'get_tiers.return_value': [self.tier]}
57 self.tiers.configure_mock(**attrs)
59 self.run_tests_parser = run_tests.RunTestsParser()
61 self.config_file_yaml = {'general': {
63 'image_name': 'test_image_name'}},
65 'test_db_url': 'url1'}}
66 self.config_file_patch_yaml = {'fdio': {'general': {
69 'test_image_name_2'}}}}
70 self.config_file_aarcg64_patch_yaml = {'os': {'general': {
71 'openstack': {'image_name': 'test_image_name_3'}}}}
73 @mock.patch('functest.ci.run_tests.Runner.patch_file')
74 def test_update_config_file_default(self, mock_patch):
75 self.runner.update_config_file()
76 mock_patch.assert_called()
78 def test_patch_file_missing_file(self):
79 patch_file_path = "unexisting_file"
80 with self.assertRaises(IOError):
81 self.runner.patch_file(patch_file_path)
83 @mock.patch('functest.ci.run_tests.ft_utils.merge_dicts')
84 @mock.patch('functest.ci.run_tests.ft_utils.get_functest_yaml')
85 def test_patch_file_default(self, *mock_methods):
86 CONST.__setattr__('DEPLOY_SCENARIO', 'os-nosdn-nofeature-noha')
88 'six.moves.builtins.open', mock.mock_open()), mock.patch(
89 'functest.ci.run_tests.yaml.safe_load') as yaml1, mock.patch(
90 'functest.ci.run_tests.ft_utils.get_functest_yaml') as yaml2:
91 yaml1.return_value = self.config_file_patch_yaml
92 yaml2.return_value = self.config_file_yaml
93 self.runner.patch_file(yaml1)
94 mock_methods[1].assert_not_called()
95 mock_methods[0].assert_not_called()
97 @mock.patch('functest.ci.run_tests.ft_utils.merge_dicts')
98 @mock.patch('functest.ci.run_tests.os.remove')
99 def test_patch_file_match_scenario(self, *mock_methods):
100 CONST.__setattr__('DEPLOY_SCENARIO', 'os-nosdn-fdio-noha')
102 'six.moves.builtins.open', mock.mock_open()), mock.patch(
103 'functest.ci.run_tests.yaml.safe_load') as yaml1, mock.patch(
104 'functest.ci.run_tests.ft_utils.get_functest_yaml') as yaml2:
105 yaml1.return_value = self.config_file_patch_yaml
106 yaml2.return_value = self.config_file_yaml
107 self.runner.patch_file(yaml2)
108 mock_methods[1].assert_called()
109 mock_methods[0].assert_called()
111 @mock.patch('functest.ci.run_tests.logger.error')
112 def test_source_rc_file_missing_file(self, mock_logger_error):
113 with mock.patch('functest.ci.run_tests.os.path.isfile',
114 return_value=False), \
115 self.assertRaises(Exception):
116 self.runner.source_rc_file()
118 @mock.patch('functest.ci.run_tests.logger.debug')
119 @mock.patch('functest.ci.run_tests.os.path.isfile',
121 def test_source_rc_file_default(self, *args):
122 with mock.patch('functest.ci.run_tests.os_utils.source_credentials',
123 return_value=self.creds):
124 self.runner.source_rc_file()
126 def test_get_run_dict_if_defined_default(self):
127 mock_obj = mock.Mock()
128 with mock.patch('functest.ci.run_tests.'
129 'ft_utils.get_dict_by_test',
130 return_value={'run': mock_obj}):
131 self.assertEqual(self.runner.get_run_dict('test_name'),
134 @mock.patch('functest.ci.run_tests.logger.error')
135 def test_get_run_dict_if_defined_missing_config_option(self,
137 with mock.patch('functest.ci.run_tests.'
138 'ft_utils.get_dict_by_test',
140 testname = 'test_name'
141 self.assertEqual(self.runner.get_run_dict(testname),
143 mock_logger_error.assert_called_once_with("Cannot get {}'s config "
147 with mock.patch('functest.ci.run_tests.'
148 'ft_utils.get_dict_by_test',
150 testname = 'test_name'
151 self.assertEqual(self.runner.get_run_dict(testname),
154 @mock.patch('functest.ci.run_tests.logger.exception')
155 def test_get_run_dict_if_defined_exception(self,
157 with mock.patch('functest.ci.run_tests.'
158 'ft_utils.get_dict_by_test',
159 side_effect=Exception):
160 testname = 'test_name'
161 self.assertEqual(self.runner.get_run_dict(testname),
163 mock_logger_except.assert_called_once_with("Cannot get {}'s config"
167 def test_run_tests_import_test_class_exception(self):
168 mock_test = mock.Mock()
169 args = {'get_name.return_value': 'test_name',
170 'needs_clean.return_value': False}
171 mock_test.configure_mock(**args)
172 with mock.patch('functest.ci.run_tests.Runner.source_rc_file'), \
173 mock.patch('functest.ci.run_tests.Runner.get_run_dict',
174 return_value=None), \
175 self.assertRaises(Exception) as context:
176 self.runner(mock_test, 'tier_name')
177 msg = "Cannot import the class for the test case."
178 self.assertTrue(msg in context)
180 @mock.patch('functest.ci.run_tests.Runner.source_rc_file')
181 @mock.patch('importlib.import_module', name="module",
182 return_value=mock.Mock(test_class=mock.Mock(
183 side_effect=FakeModule)))
184 @mock.patch('functest.utils.functest_utils.get_dict_by_test')
185 def test_run_tests_default(self, *args):
186 mock_test = mock.Mock()
187 kwargs = {'get_name.return_value': 'test_name',
188 'needs_clean.return_value': True}
189 mock_test.configure_mock(**kwargs)
190 test_run_dict = {'module': 'test_module',
191 'class': 'test_class'}
192 with mock.patch('functest.ci.run_tests.Runner.get_run_dict',
193 return_value=test_run_dict):
194 self.runner.clean_flag = True
195 self.runner.run_test(mock_test)
196 self.assertEqual(self.runner.overall_result,
197 run_tests.Result.EX_OK)
199 @mock.patch('functest.ci.run_tests.Runner.run_test',
200 return_value=TestCase.EX_OK)
201 def test_run_tier_default(self, *mock_methods):
202 self.assertEqual(self.runner.run_tier(self.tier),
203 run_tests.Result.EX_OK)
204 mock_methods[0].assert_called_with(mock.ANY)
206 @mock.patch('functest.ci.run_tests.logger.info')
207 def test_run_tier_missing_test(self, mock_logger_info):
208 self.tier.get_tests.return_value = None
209 self.assertEqual(self.runner.run_tier(self.tier),
210 run_tests.Result.EX_ERROR)
211 self.assertTrue(mock_logger_info.called)
213 @mock.patch('functest.ci.run_tests.logger.info')
214 @mock.patch('functest.ci.run_tests.Runner.run_tier')
215 @mock.patch('functest.ci.run_tests.Runner.summary')
216 def test_run_all_default(self, *mock_methods):
217 CONST.__setattr__('CI_LOOP', 'test_ci_loop')
218 self.runner.run_all()
219 mock_methods[1].assert_not_called()
220 self.assertTrue(mock_methods[2].called)
222 @mock.patch('functest.ci.run_tests.logger.info')
223 @mock.patch('functest.ci.run_tests.Runner.summary')
224 def test_run_all_missing_tier(self, *mock_methods):
225 CONST.__setattr__('CI_LOOP', 'loop_re_not_available')
226 self.runner.run_all()
227 self.assertTrue(mock_methods[1].called)
229 @mock.patch('functest.ci.run_tests.Runner.source_rc_file',
230 side_effect=Exception)
231 @mock.patch('functest.ci.run_tests.Runner.summary')
232 def test_main_failed(self, *mock_methods):
233 kwargs = {'test': 'test_name', 'noclean': True, 'report': True}
234 args = {'get_tier.return_value': False,
235 'get_test.return_value': False}
236 self.runner._tiers = mock.Mock()
237 self.runner._tiers.configure_mock(**args)
238 self.assertEqual(self.runner.main(**kwargs),
239 run_tests.Result.EX_ERROR)
240 mock_methods[1].assert_called_once_with()
242 @mock.patch('functest.ci.run_tests.Runner.source_rc_file')
243 @mock.patch('functest.ci.run_tests.Runner.run_test',
244 return_value=TestCase.EX_OK)
245 @mock.patch('functest.ci.run_tests.Runner.summary')
246 def test_main_tier(self, *mock_methods):
247 mock_tier = mock.Mock()
248 test_mock = mock.Mock()
249 test_mock.get_name.return_value = 'test1'
250 args = {'get_name.return_value': 'tier_name',
251 'get_tests.return_value': [test_mock]}
252 mock_tier.configure_mock(**args)
253 kwargs = {'test': 'tier_name', 'noclean': True, 'report': True}
254 args = {'get_tier.return_value': mock_tier,
255 'get_test.return_value': None}
256 self.runner._tiers = mock.Mock()
257 self.runner._tiers.configure_mock(**args)
258 self.assertEqual(self.runner.main(**kwargs),
259 run_tests.Result.EX_OK)
260 mock_methods[1].assert_called()
262 @mock.patch('functest.ci.run_tests.Runner.source_rc_file')
263 @mock.patch('functest.ci.run_tests.Runner.run_test',
264 return_value=TestCase.EX_OK)
265 def test_main_test(self, *mock_methods):
266 kwargs = {'test': 'test_name', 'noclean': True, 'report': True}
267 args = {'get_tier.return_value': None,
268 'get_test.return_value': 'test_name'}
269 self.runner._tiers = mock.Mock()
270 self.runner._tiers.configure_mock(**args)
271 self.assertEqual(self.runner.main(**kwargs),
272 run_tests.Result.EX_OK)
273 mock_methods[0].assert_called_once_with('test_name')
275 @mock.patch('functest.ci.run_tests.Runner.source_rc_file')
276 @mock.patch('functest.ci.run_tests.Runner.run_all')
277 @mock.patch('functest.ci.run_tests.Runner.summary')
278 def test_main_all_tier(self, *mock_methods):
279 kwargs = {'test': 'all', 'noclean': True, 'report': True}
280 args = {'get_tier.return_value': None,
281 'get_test.return_value': None}
282 self.runner._tiers = mock.Mock()
283 self.runner._tiers.configure_mock(**args)
284 self.assertEqual(self.runner.main(**kwargs),
285 run_tests.Result.EX_OK)
286 mock_methods[1].assert_called_once_with()
288 @mock.patch('functest.ci.run_tests.Runner.source_rc_file')
289 @mock.patch('functest.ci.run_tests.Runner.summary')
290 def test_main_any_tier_test_ko(self, *mock_methods):
291 kwargs = {'test': 'any', 'noclean': True, 'report': True}
292 args = {'get_tier.return_value': None,
293 'get_test.return_value': None}
294 self.runner._tiers = mock.Mock()
295 self.runner._tiers.configure_mock(**args)
296 self.assertEqual(self.runner.main(**kwargs),
297 run_tests.Result.EX_ERROR)
300 if __name__ == "__main__":
301 logging.disable(logging.CRITICAL)
302 unittest.main(verbosity=2)