3 # Copyright (c) 2016 Orange and others.
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
10 """Define the class required to fully cover testcase."""
12 from datetime import datetime
21 from xtesting.core import testcase
23 __author__ = "Cedric Ollivier <cedric.ollivier@orange.com>"
26 class TestCaseTesting(unittest.TestCase):
27 """The class testing TestCase."""
29 # pylint: disable=missing-docstring,too-many-public-methods
32 _project_name = "xtesting"
33 _published_result = "PASS"
34 _test_db_url = "http://testresults.opnfv.org/test/api/v1/results"
35 _headers = {'Content-Type': 'application/json'}
38 self.test = testcase.TestCase(case_name=self._case_name,
39 project_name=self._project_name)
40 self.test.start_time = 1
41 self.test.stop_time = 2
42 self.test.result = 100
43 self.test.details = {"Hello": "World"}
44 os.environ['TEST_DB_URL'] = TestCaseTesting._test_db_url
45 os.environ['INSTALLER_TYPE'] = "installer_type"
46 os.environ['DEPLOY_SCENARIO'] = "scenario"
47 os.environ['NODE_NAME'] = "node_name"
48 os.environ['BUILD_TAG'] = "foo-daily-master-bar"
50 def test_run_unimplemented(self):
51 self.assertEqual(self.test.run(),
52 testcase.TestCase.EX_RUN_ERROR)
54 def _test_pushdb_missing_attribute(self):
55 self.assertEqual(self.test.push_to_db(),
56 testcase.TestCase.EX_PUSH_TO_DB_ERROR)
58 def test_pushdb_no_project_name(self):
59 self.test.project_name = None
60 self._test_pushdb_missing_attribute()
62 def test_pushdb_no_case_name(self):
63 self.test.case_name = None
64 self._test_pushdb_missing_attribute()
66 def test_pushdb_no_start_time(self):
67 self.test.start_time = None
68 self._test_pushdb_missing_attribute()
70 def test_pushdb_no_stop_time(self):
71 self.test.stop_time = None
72 self._test_pushdb_missing_attribute()
74 def _test_pushdb_missing_env(self, var):
76 self.assertEqual(self.test.push_to_db(),
77 testcase.TestCase.EX_PUSH_TO_DB_ERROR)
79 def test_pushdb_no_db_url(self):
80 self._test_pushdb_missing_env('TEST_DB_URL')
82 def test_pushdb_no_installer_type(self):
83 self._test_pushdb_missing_env('INSTALLER_TYPE')
85 def test_pushdb_no_deploy_scenario(self):
86 self._test_pushdb_missing_env('DEPLOY_SCENARIO')
88 def test_pushdb_no_node_name(self):
89 self._test_pushdb_missing_env('NODE_NAME')
91 def test_pushdb_no_build_tag(self):
92 self._test_pushdb_missing_env('BUILD_TAG')
94 @mock.patch('requests.post')
95 def test_pushdb_bad_start_time(self, mock_function=None):
96 self.test.start_time = "1"
98 self.test.push_to_db(),
99 testcase.TestCase.EX_PUSH_TO_DB_ERROR)
100 mock_function.assert_not_called()
102 @mock.patch('requests.post')
103 def test_pushdb_bad_end_time(self, mock_function=None):
104 self.test.stop_time = "2"
106 self.test.push_to_db(),
107 testcase.TestCase.EX_PUSH_TO_DB_ERROR)
108 mock_function.assert_not_called()
110 @mock.patch('requests.post')
111 def test_pushdb_skipped_test(self, mock_function=None):
112 self.test.is_skipped = True
114 self.test.push_to_db(),
115 testcase.TestCase.EX_PUSH_TO_DB_ERROR)
116 mock_function.assert_not_called()
120 "build_tag": os.environ['BUILD_TAG'],
121 "case_name": self._case_name,
122 "criteria": 'PASS' if self.test.is_successful(
123 ) == self.test.EX_OK else 'FAIL',
124 "details": self.test.details,
125 "installer": os.environ['INSTALLER_TYPE'],
126 "pod_name": os.environ['NODE_NAME'],
127 "project_name": self.test.project_name,
128 "scenario": os.environ['DEPLOY_SCENARIO'],
129 "start_date": datetime.fromtimestamp(
130 self.test.start_time).strftime('%Y-%m-%d %H:%M:%S'),
131 "stop_date": datetime.fromtimestamp(
132 self.test.stop_time).strftime('%Y-%m-%d %H:%M:%S'),
135 @mock.patch('requests.post')
136 def _test_pushdb_version(self, mock_function=None, **kwargs):
137 payload = self._get_data()
138 payload["version"] = kwargs.get("version", "unknown")
139 self.assertEqual(self.test.push_to_db(), testcase.TestCase.EX_OK)
140 mock_function.assert_called_once_with(
141 os.environ['TEST_DB_URL'],
142 data=json.dumps(payload, sort_keys=True),
143 headers=self._headers)
145 def test_pushdb_daily_job(self):
146 self._test_pushdb_version(version="master")
148 def test_pushdb_weekly_job(self):
149 os.environ['BUILD_TAG'] = 'foo-weekly-master-bar'
150 self._test_pushdb_version(version="master")
152 def test_pushdb_random_build_tag(self):
153 os.environ['BUILD_TAG'] = 'whatever'
154 self._test_pushdb_version(version="unknown")
156 @mock.patch('requests.post', return_value=mock.Mock(
157 raise_for_status=mock.Mock(
158 side_effect=requests.exceptions.HTTPError)))
159 def test_pushdb_http_errors(self, mock_function=None):
161 self.test.push_to_db(),
162 testcase.TestCase.EX_PUSH_TO_DB_ERROR)
163 mock_function.assert_called_once_with(
164 os.environ['TEST_DB_URL'],
165 data=json.dumps(self._get_data(), sort_keys=True),
166 headers=self._headers)
168 def test_check_requirements(self):
169 self.test.check_requirements()
170 self.assertEqual(self.test.is_skipped, False)
172 def test_check_criteria_missing(self):
173 self.test.criteria = None
174 self.assertEqual(self.test.is_successful(),
175 testcase.TestCase.EX_TESTCASE_FAILED)
177 def test_check_result_missing(self):
178 self.test.result = None
179 self.assertEqual(self.test.is_successful(),
180 testcase.TestCase.EX_TESTCASE_FAILED)
182 def test_check_result_failed(self):
183 # Backward compatibility
184 # It must be removed as soon as TestCase subclasses
185 # stop setting result = 'PASS' or 'FAIL'.
186 self.test.result = 'FAIL'
187 self.assertEqual(self.test.is_successful(),
188 testcase.TestCase.EX_TESTCASE_FAILED)
190 def test_check_result_pass(self):
191 # Backward compatibility
192 # It must be removed as soon as TestCase subclasses
193 # stop setting result = 'PASS' or 'FAIL'.
194 self.test.result = 'PASS'
195 self.assertEqual(self.test.is_successful(),
196 testcase.TestCase.EX_OK)
198 def test_check_result_skip(self):
199 self.test.is_skipped = True
200 self.assertEqual(self.test.is_successful(),
201 testcase.TestCase.EX_TESTCASE_SKIPPED)
203 def test_check_result_lt(self):
204 self.test.result = 50
205 self.assertEqual(self.test.is_successful(),
206 testcase.TestCase.EX_TESTCASE_FAILED)
208 def test_check_result_eq(self):
209 self.test.result = 100
210 self.assertEqual(self.test.is_successful(),
211 testcase.TestCase.EX_OK)
213 def test_check_result_gt(self):
214 self.test.criteria = 50
215 self.test.result = 100
216 self.assertEqual(self.test.is_successful(),
217 testcase.TestCase.EX_OK)
219 def test_check_result_zero(self):
220 self.test.criteria = 0
222 self.assertEqual(self.test.is_successful(),
223 testcase.TestCase.EX_TESTCASE_FAILED)
225 def test_get_duration_start_ko(self):
226 self.test.start_time = None
227 self.assertEqual(self.test.get_duration(), "XX:XX")
228 self.test.start_time = 0
229 self.assertEqual(self.test.get_duration(), "XX:XX")
231 def test_get_duration_end_ko(self):
232 self.test.stop_time = None
233 self.assertEqual(self.test.get_duration(), "XX:XX")
234 self.test.stop_time = 0
235 self.assertEqual(self.test.get_duration(), "XX:XX")
237 def test_get_invalid_duration(self):
238 self.test.start_time = 2
239 self.test.stop_time = 1
240 self.assertEqual(self.test.get_duration(), "XX:XX")
242 def test_get_zero_duration(self):
243 self.test.start_time = 2
244 self.test.stop_time = 2
245 self.assertEqual(self.test.get_duration(), "00:00")
247 def test_get_duration(self):
248 self.test.start_time = 1
249 self.test.stop_time = 180
250 self.assertEqual(self.test.get_duration(), "02:59")
252 def test_get_duration_skipped_test(self):
253 self.test.is_skipped = True
254 self.assertEqual(self.test.get_duration(), "00:00")
256 def test_str_project_name_ko(self):
257 self.test.project_name = None
258 self.assertIn("<xtesting.core.testcase.TestCase object at",
261 def test_str_case_name_ko(self):
262 self.test.case_name = None
263 self.assertIn("<xtesting.core.testcase.TestCase object at",
266 def test_str_pass(self):
268 with mock.patch.object(self.test, 'get_duration',
269 return_value=duration), \
270 mock.patch.object(self.test, 'is_successful',
271 return_value=testcase.TestCase.EX_OK):
272 message = str(self.test)
273 self.assertIn(self._project_name, message)
274 self.assertIn(self._case_name, message)
275 self.assertIn(duration, message)
276 self.assertIn('PASS', message)
278 def test_str_fail(self):
280 with mock.patch.object(self.test, 'get_duration',
281 return_value=duration), \
283 self.test, 'is_successful',
284 return_value=testcase.TestCase.EX_TESTCASE_FAILED):
285 message = str(self.test)
286 self.assertIn(self._project_name, message)
287 self.assertIn(self._case_name, message)
288 self.assertIn(duration, message)
289 self.assertIn('FAIL', message)
291 def test_str_skip(self):
292 self.test.is_skipped = True
293 message = str(self.test)
294 self.assertIn(self._project_name, message)
295 self.assertIn(self._case_name, message)
296 self.assertIn("00:00", message)
297 self.assertIn('SKIP', message)
299 def test_clean(self):
300 self.assertEqual(self.test.clean(), None)
303 if __name__ == "__main__":
304 logging.disable(logging.CRITICAL)
305 unittest.main(verbosity=2)