| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 from testing_utils import testing | 5 from testing_utils import testing |
| 6 | 6 |
| 7 from common.git_repository import GitRepository | 7 from common.git_repository import GitRepository |
| 8 from model import wf_analysis_status | 8 from model import wf_analysis_status |
| 9 from model.wf_try_job import WfTryJob | 9 from model.wf_try_job import WfTryJob |
| 10 from waterfall.identify_try_job_culprit_pipeline import( | 10 from waterfall.identify_try_job_culprit_pipeline import( |
| 11 IdentifyTryJobCulpritPipeline) | 11 IdentifyTryJobCulpritPipeline) |
| 12 | 12 |
| 13 | 13 |
| 14 class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 14 class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): |
| 15 | 15 |
| 16 def _MockGetChangeLog(self, revision): | 16 def _MockGetChangeLog(self, revision): |
| 17 class MockedChangeLog(object): | 17 class MockedChangeLog(object): |
| 18 | 18 |
| 19 def __init__(self, commit_position, code_review_url): | 19 def __init__(self, commit_position, code_review_url): |
| 20 self.commit_position = commit_position | 20 self.commit_position = commit_position |
| 21 self.code_review_url = code_review_url | 21 self.code_review_url = code_review_url |
| 22 | 22 |
| 23 mock_change_logs = {} | 23 mock_change_logs = {} |
| 24 mock_change_logs['rev1'] = MockedChangeLog('1', 'url_1') |
| 24 mock_change_logs['rev2'] = MockedChangeLog('2', 'url_2') | 25 mock_change_logs['rev2'] = MockedChangeLog('2', 'url_2') |
| 25 return mock_change_logs.get(revision) | 26 return mock_change_logs.get(revision) |
| 26 | 27 |
| 27 def testIdentifyCulpritForCompileReturnNoneIfNoCompileResult(self): | 28 def testIdentifyCulpritForCompileReturnNoneIfNoCompileResult(self): |
| 28 master_name = 'm' | 29 master_name = 'm' |
| 29 builder_name = 'b' | 30 builder_name = 'b' |
| 30 build_number = 1 | 31 build_number = 1 |
| 31 try_job_id = '1' | |
| 32 compile_result = None | |
| 33 | 32 |
| 34 WfTryJob.Create(master_name, builder_name, build_number).put() | 33 WfTryJob.Create(master_name, builder_name, build_number).put() |
| 35 pipeline = IdentifyTryJobCulpritPipeline() | 34 pipeline = IdentifyTryJobCulpritPipeline() |
| 36 culprit = pipeline.run( | 35 culprit = pipeline.run( |
| 37 master_name, builder_name, build_number, try_job_id, compile_result) | 36 master_name, builder_name, build_number, ['rev1'], 'compile', '1', None) |
| 38 try_job = WfTryJob.Get(master_name, builder_name, build_number) | 37 try_job = WfTryJob.Get(master_name, builder_name, build_number) |
| 39 | 38 |
| 40 self.assertIsNone(culprit) | 39 self.assertIsNone(culprit) |
| 41 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | 40 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) |
| 42 | 41 |
| 43 def testIdentifyCulpritForCompileReturnNoneIfNoTryJobResultForCompile(self): | 42 def testIdentifyCulpritForCompileReturnNoneIfNoTryJobResultForCompile(self): |
| 44 master_name = 'm' | 43 master_name = 'm' |
| 45 builder_name = 'b' | 44 builder_name = 'b' |
| 46 build_number = 1 | 45 build_number = 1 |
| 47 try_job_id = '1' | |
| 48 compile_result = { | 46 compile_result = { |
| 49 'result': [], | 47 'result': [], |
| 50 'url': 'url', | 48 'url': 'url', |
| 51 'try_job_id': '1', | 49 'try_job_id': '1', |
| 52 } | 50 } |
| 53 WfTryJob.Create(master_name, builder_name, build_number).put() | 51 WfTryJob.Create(master_name, builder_name, build_number).put() |
| 54 | 52 |
| 55 pipeline = IdentifyTryJobCulpritPipeline() | 53 pipeline = IdentifyTryJobCulpritPipeline() |
| 56 culprit = pipeline.run( | 54 culprit = pipeline.run( |
| 57 master_name, builder_name, build_number, try_job_id, compile_result) | 55 master_name, builder_name, build_number, ['rev1'], 'compile', '1', |
| 56 compile_result) |
| 58 try_job = WfTryJob.Get(master_name, builder_name, build_number) | 57 try_job = WfTryJob.Get(master_name, builder_name, build_number) |
| 59 | 58 |
| 60 self.assertIsNone(culprit) | 59 self.assertIsNone(culprit) |
| 61 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | 60 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) |
| 62 | 61 |
| 63 def testIdentifyCulpritForCompileReturnNoneIfAllPassed(self): | 62 def testIdentifyCulpritForCompileReturnNoneIfAllPassed(self): |
| 64 master_name = 'm' | 63 master_name = 'm' |
| 65 builder_name = 'b' | 64 builder_name = 'b' |
| 66 build_number = 1 | 65 build_number = 1 |
| 67 try_job_id = '1' | |
| 68 compile_result = { | 66 compile_result = { |
| 69 'result': [ | 67 'result': [ |
| 70 ['rev1', 'passed'], | 68 ['rev1', 'passed'], |
| 71 ['rev2', 'passed'] | 69 ['rev2', 'passed'] |
| 72 ], | 70 ], |
| 73 'url': 'url', | 71 'url': 'url', |
| 74 'try_job_id': '1', | 72 'try_job_id': '1', |
| 75 } | 73 } |
| 76 WfTryJob.Create(master_name, builder_name, build_number).put() | 74 WfTryJob.Create(master_name, builder_name, build_number).put() |
| 77 | 75 |
| 78 pipeline = IdentifyTryJobCulpritPipeline() | 76 pipeline = IdentifyTryJobCulpritPipeline() |
| 79 culprit = pipeline.run( | 77 culprit = pipeline.run( |
| 80 master_name, builder_name, build_number, try_job_id, compile_result) | 78 master_name, builder_name, build_number, ['rev1'], 'compile', '1', |
| 79 compile_result) |
| 81 try_job = WfTryJob.Get(master_name, builder_name, build_number) | 80 try_job = WfTryJob.Get(master_name, builder_name, build_number) |
| 82 | 81 |
| 83 self.assertIsNone(culprit) | 82 self.assertIsNone(culprit) |
| 84 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | 83 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) |
| 85 | 84 |
| 86 def testIdentifyCulpritForCompileReturnNoneIfNoChangeLog(self): | 85 def testIdentifyCulpritForCompileReturnNoneIfNoChangeLog(self): |
| 87 master_name = 'm' | 86 master_name = 'm' |
| 88 builder_name = 'b' | 87 builder_name = 'b' |
| 89 build_number = 1 | 88 build_number = 1 |
| 90 try_job_id = '1' | |
| 91 compile_result = { | 89 compile_result = { |
| 92 'result': [ | 90 'result': [ |
| 93 ['rev1', 'failed'] | 91 ['rev0', 'failed'] |
| 94 ], | 92 ], |
| 95 'url': 'url', | 93 'url': 'url', |
| 96 'try_job_id': '1', | 94 'try_job_id': '1', |
| 97 } | 95 } |
| 98 | 96 |
| 99 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) | 97 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) |
| 100 WfTryJob.Create(master_name, builder_name, build_number).put() | 98 WfTryJob.Create(master_name, builder_name, build_number).put() |
| 101 | 99 |
| 102 pipeline = IdentifyTryJobCulpritPipeline() | 100 pipeline = IdentifyTryJobCulpritPipeline() |
| 103 culprit = pipeline.run( | 101 culprit = pipeline.run( |
| 104 master_name, builder_name, build_number, try_job_id, compile_result) | 102 master_name, builder_name, build_number, ['rev1'], 'compile', '1', |
| 103 compile_result) |
| 105 try_job = WfTryJob.Get(master_name, builder_name, build_number) | 104 try_job = WfTryJob.Get(master_name, builder_name, build_number) |
| 106 | 105 |
| 107 self.assertIsNone(culprit) | 106 self.assertIsNone(culprit) |
| 108 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | 107 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) |
| 109 | 108 |
| 110 def testIdentifyCulpritForCompileTryJobSuccess(self): | 109 def testIdentifyCulpritForCompileTryJobSuccess(self): |
| 111 master_name = 'm' | 110 master_name = 'm' |
| 112 builder_name = 'b' | 111 builder_name = 'b' |
| 113 build_number = 1 | 112 build_number = 1 |
| 114 try_job_id = '1' | |
| 115 compile_result = { | 113 compile_result = { |
| 116 'result': [ | 114 'result': [ |
| 117 ['rev1', 'passed'], | 115 ['rev1', 'passed'], |
| 118 ['rev2', 'failed'] | 116 ['rev2', 'failed'] |
| 119 ], | 117 ], |
| 120 'url': 'url', | 118 'url': 'url', |
| 121 'try_job_id': '1', | 119 'try_job_id': '1', |
| 122 } | 120 } |
| 123 | 121 |
| 124 try_job = WfTryJob.Create(master_name, builder_name, build_number) | 122 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 125 try_job.status = wf_analysis_status.ANALYZING | 123 try_job.status = wf_analysis_status.ANALYZING |
| 126 try_job.compile_results = [{ | 124 try_job.compile_results = [compile_result] |
| 127 'result': [ | |
| 128 ['rev1', 'passed'], | |
| 129 ['rev2', 'failed'] | |
| 130 ], | |
| 131 'url': 'url', | |
| 132 'try_job_id': '1', | |
| 133 }] | |
| 134 try_job.put() | 125 try_job.put() |
| 135 | 126 |
| 136 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) | 127 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) |
| 137 | 128 |
| 138 pipeline = IdentifyTryJobCulpritPipeline() | 129 pipeline = IdentifyTryJobCulpritPipeline() |
| 139 culprit = pipeline.run( | 130 culprit = pipeline.run( |
| 140 master_name, builder_name, build_number, try_job_id, compile_result) | 131 master_name, builder_name, build_number, ['rev1'], 'compile', '1', |
| 132 compile_result) |
| 141 | 133 |
| 142 expected_compile_result = { | 134 expected_compile_result = { |
| 143 'result': [ | 135 'result': [ |
| 144 ['rev1', 'passed'], | 136 ['rev1', 'passed'], |
| 145 ['rev2', 'failed'] | 137 ['rev2', 'failed'] |
| 146 ], | 138 ], |
| 147 'url': 'url', | 139 'url': 'url', |
| 148 'try_job_id': '1', | 140 'try_job_id': '1', |
| 149 'culprit': { | 141 'culprit': { |
| 150 'revision': 'rev2', | 142 'revision': 'rev2', |
| 151 'commit_position': '2', | 143 'commit_position': '2', |
| 152 'review_url': 'url_2' | 144 'review_url': 'url_2' |
| 153 } | 145 } |
| 154 } | 146 } |
| 155 | 147 |
| 156 self.assertEqual(expected_compile_result['culprit'], culprit) | 148 self.assertEqual(expected_compile_result['culprit'], culprit) |
| 157 | 149 |
| 158 try_job = WfTryJob.Get(master_name, builder_name, build_number) | 150 try_job = WfTryJob.Get(master_name, builder_name, build_number) |
| 159 self.assertEqual(expected_compile_result, try_job.compile_results[-1]) | 151 self.assertEqual(expected_compile_result, try_job.compile_results[-1]) |
| 160 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | 152 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) |
| 153 |
| 154 def testIdentifyCulpritForTestTryJobReturnNoneIfNoTryJobResult(self): |
| 155 master_name = 'm' |
| 156 builder_name = 'b' |
| 157 build_number = 1 |
| 158 |
| 159 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 160 try_job.status = wf_analysis_status.ANALYZING |
| 161 try_job.put() |
| 162 |
| 163 pipeline = IdentifyTryJobCulpritPipeline() |
| 164 culprit = pipeline.run( |
| 165 master_name, builder_name, build_number, ['rev1', 'rev2'], 'test', '1', |
| 166 None) |
| 167 |
| 168 self.assertIsNone(culprit) |
| 169 |
| 170 def testIdentifyCulpritForTestTryJobReturnNoneIfNoRevisionToCheck(self): |
| 171 master_name = 'm' |
| 172 builder_name = 'b' |
| 173 build_number = 1 |
| 174 test_result = { |
| 175 'result': { |
| 176 'rev1': { |
| 177 'a_test': { |
| 178 'status': 'failed', |
| 179 'valid': True, |
| 180 'failures': ['a_test1'] |
| 181 } |
| 182 } |
| 183 }, |
| 184 'url': 'url', |
| 185 'try_job_id': '1' |
| 186 } |
| 187 |
| 188 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 189 try_job.status = wf_analysis_status.ANALYZING |
| 190 try_job.put() |
| 191 |
| 192 pipeline = IdentifyTryJobCulpritPipeline() |
| 193 culprit = pipeline.run( |
| 194 master_name, builder_name, build_number, [], 'test', '1', |
| 195 test_result) |
| 196 |
| 197 self.assertIsNone(culprit) |
| 198 |
| 199 def testIdentifyCulpritForTestTryJobReturnNoneIfNoCulpritInfo(self): |
| 200 master_name = 'm' |
| 201 builder_name = 'b' |
| 202 build_number = 1 |
| 203 test_result = { |
| 204 'result': { |
| 205 'rev3': { |
| 206 'a_test': { |
| 207 'status': 'failed', |
| 208 'valid': True, |
| 209 'failures': ['a_test1'] |
| 210 } |
| 211 } |
| 212 }, |
| 213 'url': 'url', |
| 214 'try_job_id': '1' |
| 215 } |
| 216 |
| 217 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 218 try_job.status = wf_analysis_status.ANALYZING |
| 219 try_job.put() |
| 220 |
| 221 pipeline = IdentifyTryJobCulpritPipeline() |
| 222 culprit = pipeline.run( |
| 223 master_name, builder_name, build_number, ['rev3'], 'test', '1', |
| 224 test_result) |
| 225 |
| 226 self.assertIsNone(culprit) |
| 227 |
| 228 def testIdentifyCulpritForTestTryJobSuccess(self): |
| 229 master_name = 'm' |
| 230 builder_name = 'b' |
| 231 build_number = 1 |
| 232 test_result = { |
| 233 'result': { |
| 234 'rev1': { |
| 235 'a_test': { |
| 236 'status': 'failed', |
| 237 'valid': True, |
| 238 'failures': ['a_test1'] |
| 239 }, |
| 240 'b_test': { |
| 241 'status': 'failed', |
| 242 'valid': True, |
| 243 'failures': ['b_test1'] |
| 244 }, |
| 245 'c_test': { |
| 246 'status': 'passed', |
| 247 'valid': True |
| 248 } |
| 249 }, |
| 250 'rev2': { |
| 251 'a_test': { |
| 252 'status': 'failed', |
| 253 'valid': True, |
| 254 'failures': ['a_test1', 'a_test2'] |
| 255 }, |
| 256 'b_test': { |
| 257 'status': 'passed', |
| 258 'valid': True |
| 259 }, |
| 260 'c_test': { |
| 261 'status': 'failed', |
| 262 'valid': True, |
| 263 'failures': [] |
| 264 } |
| 265 } |
| 266 }, |
| 267 'url': 'url', |
| 268 'try_job_id': '1' |
| 269 } |
| 270 |
| 271 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 272 try_job.status = wf_analysis_status.ANALYZING |
| 273 try_job.test_results = [test_result] |
| 274 try_job.put() |
| 275 |
| 276 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) |
| 277 |
| 278 pipeline = IdentifyTryJobCulpritPipeline() |
| 279 culprit = pipeline.run( |
| 280 master_name, builder_name, build_number, ['rev1', 'rev2'], 'test', '1', |
| 281 test_result) |
| 282 |
| 283 expected_test_result = { |
| 284 'result': { |
| 285 'rev1': { |
| 286 'a_test': { |
| 287 'status': 'failed', |
| 288 'valid': True, |
| 289 'failures': ['a_test1'] |
| 290 }, |
| 291 'b_test': { |
| 292 'status': 'failed', |
| 293 'valid': True, |
| 294 'failures': ['b_test1'] |
| 295 }, |
| 296 'c_test': { |
| 297 'status': 'passed', |
| 298 'valid': True |
| 299 } |
| 300 }, |
| 301 'rev2': { |
| 302 'a_test': { |
| 303 'status': 'failed', |
| 304 'valid': True, |
| 305 'failures': ['a_test1', 'a_test2'] |
| 306 }, |
| 307 'b_test': { |
| 308 'status': 'passed', |
| 309 'valid': True |
| 310 }, |
| 311 'c_test': { |
| 312 'status': 'failed', |
| 313 'valid': True, |
| 314 'failures': [] |
| 315 } |
| 316 } |
| 317 }, |
| 318 'url': 'url', |
| 319 'try_job_id': '1', |
| 320 'culprit': { |
| 321 'a_test': { |
| 322 'suspected_cls': { |
| 323 'rev1': { |
| 324 'revision': 'rev1', |
| 325 'commit_position': '1', |
| 326 'review_url': 'url_1' |
| 327 }, |
| 328 'rev2': { |
| 329 'revision': 'rev2', |
| 330 'commit_position': '2', |
| 331 'review_url': 'url_2' |
| 332 } |
| 333 }, |
| 334 'tests': { |
| 335 'a_test1': { |
| 336 'revision': 'rev1', |
| 337 'commit_position': '1', |
| 338 'review_url': 'url_1' |
| 339 }, |
| 340 'a_test2': { |
| 341 'revision': 'rev2', |
| 342 'commit_position': '2', |
| 343 'review_url': 'url_2' |
| 344 } |
| 345 } |
| 346 }, |
| 347 'b_test': { |
| 348 'suspected_cls': { |
| 349 'rev1': { |
| 350 'revision': 'rev1', |
| 351 'commit_position': '1', |
| 352 'review_url': 'url_1' |
| 353 } |
| 354 }, |
| 355 'tests': { |
| 356 'b_test1': { |
| 357 'revision': 'rev1', |
| 358 'commit_position': '1', |
| 359 'review_url': 'url_1' |
| 360 } |
| 361 } |
| 362 }, |
| 363 'c_test': { |
| 364 'suspected_cls': { |
| 365 'rev2': { |
| 366 'revision': 'rev2', |
| 367 'commit_position': '2', |
| 368 'review_url': 'url_2', |
| 369 } |
| 370 }, |
| 371 'tests': {} |
| 372 } |
| 373 } |
| 374 } |
| 375 |
| 376 self.assertEqual(expected_test_result['culprit'], culprit) |
| 377 |
| 378 try_job = WfTryJob.Get(master_name, builder_name, build_number) |
| 379 self.assertEqual(expected_test_result, try_job.test_results[-1]) |
| 380 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) |
| OLD | NEW |