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
18 from functest.core import testcase
24 __author__ = "Cedric Ollivier <cedric.ollivier@orange.com>"
27 class TestCaseTesting(unittest.TestCase):
28 """The class testing TestCase."""
30 # pylint: disable=missing-docstring,too-many-public-methods
33 _project_name = "functest"
34 _published_result = "PASS"
35 _test_db_url = "http://testresults.opnfv.org/test/api/v1/results"
36 _headers = {'Content-Type': 'application/json'}
39 self.test = testcase.TestCase(case_name=self._case_name,
40 project_name=self._project_name)
41 self.test.start_time = 1
42 self.test.stop_time = 2
43 self.test.result = 100
44 self.test.details = {"Hello": "World"}
45 os.environ['TEST_DB_URL'] = TestCaseTesting._test_db_url
46 os.environ['INSTALLER_TYPE'] = "installer_type"
47 os.environ['DEPLOY_SCENARIO'] = "scenario"
48 os.environ['NODE_NAME'] = "node_name"
49 os.environ['BUILD_TAG'] = "foo-daily-master-bar"
51 def test_run_unimplemented(self):
52 self.assertEqual(self.test.run(),
53 testcase.TestCase.EX_RUN_ERROR)
55 def _test_pushdb_missing_attribute(self):
56 self.assertEqual(self.test.push_to_db(),
57 testcase.TestCase.EX_PUSH_TO_DB_ERROR)
59 def test_pushdb_no_project_name(self):
60 self.test.project_name = None
61 self._test_pushdb_missing_attribute()
63 def test_pushdb_no_case_name(self):
64 self.test.case_name = None
65 self._test_pushdb_missing_attribute()
67 def test_pushdb_no_start_time(self):
68 self.test.start_time = None
69 self._test_pushdb_missing_attribute()
71 def test_pushdb_no_stop_time(self):
72 self.test.stop_time = None
73 self._test_pushdb_missing_attribute()
75 def _test_pushdb_missing_env(self, var):
77 self.assertEqual(self.test.push_to_db(),
78 testcase.TestCase.EX_PUSH_TO_DB_ERROR)
80 def test_pushdb_no_db_url(self):
81 self._test_pushdb_missing_env('TEST_DB_URL')
83 def test_pushdb_no_installer_type(self):
84 self._test_pushdb_missing_env('INSTALLER_TYPE')
86 def test_pushdb_no_deploy_scenario(self):
87 self._test_pushdb_missing_env('DEPLOY_SCENARIO')
89 def test_pushdb_no_node_name(self):
90 self._test_pushdb_missing_env('NODE_NAME')
92 def test_pushdb_no_build_tag(self):
93 self._test_pushdb_missing_env('BUILD_TAG')
95 @mock.patch('requests.post')
96 def test_pushdb_bad_start_time(self, mock_function=None):
97 self.test.start_time = "1"
99 self.test.push_to_db(),
100 testcase.TestCase.EX_PUSH_TO_DB_ERROR)
101 mock_function.assert_not_called()
103 @mock.patch('requests.post')
104 def test_pushdb_bad_end_time(self, mock_function=None):
105 self.test.stop_time = "2"
107 self.test.push_to_db(),
108 testcase.TestCase.EX_PUSH_TO_DB_ERROR)
109 mock_function.assert_not_called()
113 "build_tag": os.environ['BUILD_TAG'],
114 "case_name": self._case_name,
115 "criteria": 'PASS' if self.test.is_successful(
116 ) == self.test.EX_OK else 'FAIL',
117 "details": self.test.details,
118 "installer": os.environ['INSTALLER_TYPE'],
119 "pod_name": os.environ['NODE_NAME'],
120 "project_name": self.test.project_name,
121 "scenario": os.environ['DEPLOY_SCENARIO'],
122 "start_date": datetime.fromtimestamp(
123 self.test.start_time).strftime('%Y-%m-%d %H:%M:%S'),
124 "stop_date": datetime.fromtimestamp(
125 self.test.stop_time).strftime('%Y-%m-%d %H:%M:%S'),
128 @mock.patch('requests.post')
129 def _test_pushdb_version(self, mock_function=None, **kwargs):
130 payload = self._get_data()
131 payload["version"] = kwargs.get("version", "unknown")
132 self.assertEqual(self.test.push_to_db(), testcase.TestCase.EX_OK)
133 mock_function.assert_called_once_with(
134 os.environ['TEST_DB_URL'],
135 data=json.dumps(payload, sort_keys=True),
136 headers=self._headers)
138 def test_pushdb_daily_job(self):
139 self._test_pushdb_version(version="master")
141 def test_pushdb_weekly_job(self):
142 os.environ['BUILD_TAG'] = 'foo-weekly-master-bar'
143 self._test_pushdb_version(version="master")
145 def test_pushdb_random_build_tag(self):
146 os.environ['BUILD_TAG'] = 'whatever'
147 self._test_pushdb_version(version="unknown")
149 @mock.patch('requests.post', return_value=mock.Mock(
150 raise_for_status=mock.Mock(
151 side_effect=requests.exceptions.HTTPError)))
152 def test_pushdb_http_errors(self, mock_function=None):
154 self.test.push_to_db(),
155 testcase.TestCase.EX_PUSH_TO_DB_ERROR)
156 mock_function.assert_called_once_with(
157 os.environ['TEST_DB_URL'],
158 data=json.dumps(self._get_data(), sort_keys=True),
159 headers=self._headers)
161 def test_check_criteria_missing(self):
162 self.test.criteria = None
163 self.assertEqual(self.test.is_successful(),
164 testcase.TestCase.EX_TESTCASE_FAILED)
166 def test_check_result_missing(self):
167 self.test.result = None
168 self.assertEqual(self.test.is_successful(),
169 testcase.TestCase.EX_TESTCASE_FAILED)
171 def test_check_result_failed(self):
172 # Backward compatibility
173 # It must be removed as soon as TestCase subclasses
174 # stop setting result = 'PASS' or 'FAIL'.
175 self.test.result = 'FAIL'
176 self.assertEqual(self.test.is_successful(),
177 testcase.TestCase.EX_TESTCASE_FAILED)
179 def test_check_result_pass(self):
180 # Backward compatibility
181 # It must be removed as soon as TestCase subclasses
182 # stop setting result = 'PASS' or 'FAIL'.
183 self.test.result = 'PASS'
184 self.assertEqual(self.test.is_successful(),
185 testcase.TestCase.EX_OK)
187 def test_check_result_lt(self):
188 self.test.result = 50
189 self.assertEqual(self.test.is_successful(),
190 testcase.TestCase.EX_TESTCASE_FAILED)
192 def test_check_result_eq(self):
193 self.test.result = 100
194 self.assertEqual(self.test.is_successful(),
195 testcase.TestCase.EX_OK)
197 def test_check_result_gt(self):
198 self.test.criteria = 50
199 self.test.result = 100
200 self.assertEqual(self.test.is_successful(),
201 testcase.TestCase.EX_OK)
203 def test_check_result_zero(self):
204 self.test.criteria = 0
206 self.assertEqual(self.test.is_successful(),
207 testcase.TestCase.EX_TESTCASE_FAILED)
209 def test_get_duration_start_ko(self):
210 self.test.start_time = None
211 self.assertEqual(self.test.get_duration(), "XX:XX")
212 self.test.start_time = 0
213 self.assertEqual(self.test.get_duration(), "XX:XX")
215 def test_get_duration_end_ko(self):
216 self.test.stop_time = None
217 self.assertEqual(self.test.get_duration(), "XX:XX")
218 self.test.stop_time = 0
219 self.assertEqual(self.test.get_duration(), "XX:XX")
221 def test_get_invalid_duration(self):
222 self.test.start_time = 2
223 self.test.stop_time = 1
224 self.assertEqual(self.test.get_duration(), "XX:XX")
226 def test_get_zero_duration(self):
227 self.test.start_time = 2
228 self.test.stop_time = 2
229 self.assertEqual(self.test.get_duration(), "00:00")
231 def test_get_duration(self):
232 self.test.start_time = 1
233 self.test.stop_time = 180
234 self.assertEqual(self.test.get_duration(), "02:59")
236 def test_str_project_name_ko(self):
237 self.test.project_name = None
238 self.assertIn("<functest.core.testcase.TestCase object at",
241 def test_str_case_name_ko(self):
242 self.test.case_name = None
243 self.assertIn("<functest.core.testcase.TestCase object at",
246 def test_str_pass(self):
248 with mock.patch.object(self.test, 'get_duration',
249 return_value=duration), \
250 mock.patch.object(self.test, 'is_successful',
251 return_value=testcase.TestCase.EX_OK):
252 message = str(self.test)
253 self.assertIn(self._project_name, message)
254 self.assertIn(self._case_name, message)
255 self.assertIn(duration, message)
256 self.assertIn('PASS', message)
258 def test_str_fail(self):
260 with mock.patch.object(self.test, 'get_duration',
261 return_value=duration), \
263 self.test, 'is_successful',
264 return_value=testcase.TestCase.EX_TESTCASE_FAILED):
265 message = str(self.test)
266 self.assertIn(self._project_name, message)
267 self.assertIn(self._case_name, message)
268 self.assertIn(duration, message)
269 self.assertIn('FAIL', message)
271 def test_clean(self):
272 self.assertEqual(self.test.clean(), None)
275 if __name__ == "__main__":
276 logging.disable(logging.CRITICAL)
277 unittest.main(verbosity=2)