Chromium Code Reviews| 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 from waterfall.try_job_type import TryJobType | |
| 12 | 13 |
| 13 | 14 |
| 14 class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 15 class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): |
| 15 | 16 |
| 16 def _MockGetChangeLog(self, revision): | 17 def _MockGetChangeLog(self, revision): |
| 17 class MockedChangeLog(object): | 18 class MockedChangeLog(object): |
| 18 | 19 |
| 19 def __init__(self, commit_position, code_review_url): | 20 def __init__(self, commit_position, code_review_url): |
| 20 self.commit_position = commit_position | 21 self.commit_position = commit_position |
| 21 self.code_review_url = code_review_url | 22 self.code_review_url = code_review_url |
| 22 | 23 |
| 23 mock_change_logs = {} | 24 mock_change_logs = {} |
| 25 mock_change_logs['rev1'] = MockedChangeLog('1', 'url_1') | |
| 24 mock_change_logs['rev2'] = MockedChangeLog('2', 'url_2') | 26 mock_change_logs['rev2'] = MockedChangeLog('2', 'url_2') |
| 25 return mock_change_logs.get(revision) | 27 return mock_change_logs.get(revision) |
| 26 | 28 |
| 27 def testGetFailedRevisionFromResultsDict(self): | 29 def testGetFailedRevisionFromResultsDict(self): |
| 28 self.assertIsNone( | 30 self.assertIsNone( |
| 29 IdentifyTryJobCulpritPipeline._GetFailedRevisionFromResultsDict({})) | 31 IdentifyTryJobCulpritPipeline._GetFailedRevisionFromResultsDict({})) |
| 30 self.assertEqual( | 32 self.assertEqual( |
| 31 None, | 33 None, |
| 32 IdentifyTryJobCulpritPipeline._GetFailedRevisionFromResultsDict( | 34 IdentifyTryJobCulpritPipeline._GetFailedRevisionFromResultsDict( |
| 33 {'rev1': 'passed'})) | 35 {'rev1': 'passed'})) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 self.assertEqual( | 72 self.assertEqual( |
| 71 'rev2', | 73 'rev2', |
| 72 IdentifyTryJobCulpritPipeline._GetFailedRevisionFromCompileResult( | 74 IdentifyTryJobCulpritPipeline._GetFailedRevisionFromCompileResult( |
| 73 { | 75 { |
| 74 'report': [ | 76 'report': [ |
| 75 ['rev1', 'passed'], | 77 ['rev1', 'passed'], |
| 76 ['rev2', 'failed'] | 78 ['rev2', 'failed'] |
| 77 ] | 79 ] |
| 78 })) | 80 })) |
| 79 | 81 |
| 80 def testGetCulpritFromFailedRevision(self): | |
| 81 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) | |
| 82 self.assertIsNone( | |
| 83 IdentifyTryJobCulpritPipeline._GetCulpritFromFailedRevision(None)) | |
| 84 self.assertIsNone( | |
| 85 IdentifyTryJobCulpritPipeline._GetCulpritFromFailedRevision( | |
| 86 'revision_with_no_change_log')) | |
| 87 self.assertEqual( | |
| 88 { | |
| 89 'revision': 'rev2', | |
| 90 'commit_position': '2', | |
| 91 'review_url': 'url_2' | |
| 92 }, | |
| 93 IdentifyTryJobCulpritPipeline._GetCulpritFromFailedRevision('rev2')) | |
| 94 | |
| 95 def testIdentifyCulpritForCompileTryJobNoCulprit(self): | 82 def testIdentifyCulpritForCompileTryJobNoCulprit(self): |
| 96 master_name = 'm' | 83 master_name = 'm' |
| 97 builder_name = 'b' | 84 builder_name = 'b' |
| 98 build_number = 1 | 85 build_number = 1 |
| 99 try_job_id = '1' | |
| 100 | 86 |
| 101 try_job = WfTryJob.Create(master_name, builder_name, build_number) | 87 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 102 try_job.put() | 88 try_job.put() |
| 103 | 89 |
| 104 pipeline = IdentifyTryJobCulpritPipeline() | 90 pipeline = IdentifyTryJobCulpritPipeline() |
| 105 culprit = pipeline.run( | 91 culprit = pipeline.run( |
| 106 master_name, builder_name, build_number, try_job_id, None) | 92 master_name, builder_name, build_number, ['rev1'], |
| 93 TryJobType.COMPILE, '1', None) | |
| 94 try_job = WfTryJob.Get(master_name, builder_name, build_number) | |
| 107 | 95 |
| 108 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | 96 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) |
| 109 self.assertEqual([], try_job.compile_results) | 97 self.assertEqual([], try_job.compile_results) |
| 110 self.assertIsNone(culprit) | 98 self.assertIsNone(culprit) |
| 111 | 99 |
| 112 def testIdentifyCulpritForCompileTryJobSuccess(self): | 100 def testIdentifyCulpritForCompileTryJobSuccess(self): |
| 113 master_name = 'm' | 101 master_name = 'm' |
| 114 builder_name = 'b' | 102 builder_name = 'b' |
| 115 build_number = 1 | 103 build_number = 1 |
| 116 try_job_id = '1' | |
| 117 compile_result = { | 104 compile_result = { |
| 118 'report': { | 105 'report': { |
| 119 'result': { | 106 'result': { |
| 120 'rev1': 'passed', | 107 'rev1': 'passed', |
| 121 'rev2': 'failed' | 108 'rev2': 'failed' |
| 122 } | 109 } |
| 123 }, | 110 }, |
| 124 } | 111 } |
| 125 | 112 |
| 126 try_job = WfTryJob.Create(master_name, builder_name, build_number) | 113 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 127 try_job.status = wf_analysis_status.ANALYZING | 114 try_job.status = wf_analysis_status.ANALYZING |
| 128 try_job.compile_results = [{ | 115 try_job.compile_results = [{ |
| 129 'report': { | 116 'report': { |
| 130 'result': { | 117 'result': { |
| 131 'rev1': 'passed', | 118 'rev1': 'passed', |
| 132 'rev2': 'failed' | 119 'rev2': 'failed' |
| 133 }, | 120 }, |
| 134 }, | 121 }, |
| 135 'try_job_id': '1', | 122 'try_job_id': '1', |
| 136 }] | 123 }] |
| 137 try_job.put() | 124 try_job.put() |
| 138 | 125 |
| 139 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) | 126 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) |
| 140 | 127 |
| 141 pipeline = IdentifyTryJobCulpritPipeline() | 128 pipeline = IdentifyTryJobCulpritPipeline() |
| 142 culprit = pipeline.run( | 129 culprit = pipeline.run( |
| 143 master_name, builder_name, build_number, try_job_id, compile_result) | 130 master_name, builder_name, build_number, ['rev1'], |
| 144 | 131 TryJobType.COMPILE, '1', compile_result) |
| 145 expected_compile_result = { | 132 expected_compile_result = { |
| 146 'report': { | 133 'report': { |
| 147 'result': { | 134 'result': { |
| 148 'rev1': 'passed', | 135 'rev1': 'passed', |
| 149 'rev2': 'failed' | 136 'rev2': 'failed' |
| 150 } | 137 } |
| 151 }, | 138 }, |
| 152 'try_job_id': '1', | 139 'try_job_id': '1', |
| 153 'culprit': { | 140 'culprit': { |
| 154 'revision': 'rev2', | 141 'revision': 'rev2', |
| 155 'commit_position': '2', | 142 'commit_position': '2', |
| 156 'review_url': 'url_2' | 143 'review_url': 'url_2' |
| 157 } | 144 } |
| 158 } | 145 } |
| 159 | 146 |
| 160 self.assertEqual(expected_compile_result['culprit'], culprit) | 147 self.assertEqual(expected_compile_result['culprit'], culprit) |
| 161 | 148 |
| 162 try_job = WfTryJob.Get(master_name, builder_name, build_number) | 149 try_job = WfTryJob.Get(master_name, builder_name, build_number) |
| 150 | |
| 163 self.assertEqual(expected_compile_result, try_job.compile_results[-1]) | 151 self.assertEqual(expected_compile_result, try_job.compile_results[-1]) |
| 164 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | 152 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) |
| 165 | 153 |
| 154 def testIdentifyCulpritForCompileReturnNoneIfAllPassed(self): | |
| 155 master_name = 'm' | |
| 156 builder_name = 'b' | |
| 157 build_number = 1 | |
| 158 compile_result = { | |
|
lijeffrey
2016/02/02 00:24:31
Since the compile recipe has now changed, the form
chanli
2016/02/02 01:53:02
Done.
| |
| 159 'report': [ | |
| 160 ['rev1', 'passed'], | |
| 161 ['rev2', 'passed'] | |
| 162 ], | |
| 163 'url': 'url', | |
| 164 'try_job_id': '1', | |
| 165 } | |
| 166 WfTryJob.Create(master_name, builder_name, build_number).put() | |
| 167 | |
| 168 pipeline = IdentifyTryJobCulpritPipeline() | |
| 169 culprit = pipeline.run( | |
| 170 master_name, builder_name, build_number, ['rev1'], | |
| 171 TryJobType.COMPILE, '1', compile_result) | |
| 172 try_job = WfTryJob.Get(master_name, builder_name, build_number) | |
| 173 | |
| 174 self.assertIsNone(culprit) | |
| 175 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | |
| 176 | |
| 166 # TODO(lijeffrey): Deprecate all tests with compile_results whose 'result' | 177 # TODO(lijeffrey): Deprecate all tests with compile_results whose 'result' |
| 167 # key is a list once it is returned as a dict from the recipe. | 178 # key is a list once it is returned as a dict from the recipe. |
| 168 def testIdentifyCulpritForCompileListTryJobSuccess(self): | 179 def testIdentifyCulpritForCompileListTryJobSuccess(self): |
| 169 master_name = 'm' | 180 master_name = 'm' |
| 170 builder_name = 'b' | 181 builder_name = 'b' |
| 171 build_number = 1 | 182 build_number = 1 |
| 172 try_job_id = '1' | |
| 173 compile_result = { | 183 compile_result = { |
| 174 'report': [ | 184 'report': [ |
| 175 ['rev1', 'passed'], | 185 ['rev1', 'passed'], |
| 176 ['rev2', 'failed'] | 186 ['rev2', 'failed'] |
| 177 ], | 187 ], |
| 178 'url': 'url', | 188 'url': 'url', |
| 179 'try_job_id': '1', | 189 'try_job_id': '1', |
| 180 } | 190 } |
| 181 | 191 |
| 182 try_job = WfTryJob.Create(master_name, builder_name, build_number) | 192 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 183 try_job.status = wf_analysis_status.ANALYZING | 193 try_job.status = wf_analysis_status.ANALYZING |
| 184 try_job.compile_results = [{ | 194 try_job.compile_results = [compile_result] |
| 185 'report': [ | |
| 186 ['rev1', 'passed'], | |
| 187 ['rev2', 'failed'] | |
| 188 ], | |
| 189 'url': 'url', | |
| 190 'try_job_id': '1', | |
| 191 }] | |
| 192 try_job.put() | 195 try_job.put() |
| 193 | 196 |
| 194 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) | 197 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) |
| 195 | 198 |
| 196 pipeline = IdentifyTryJobCulpritPipeline() | 199 pipeline = IdentifyTryJobCulpritPipeline() |
| 197 culprit = pipeline.run( | 200 culprit = pipeline.run( |
| 198 master_name, builder_name, build_number, try_job_id, compile_result) | 201 master_name, builder_name, build_number, ['rev1'], |
| 202 TryJobType.COMPILE, '1', compile_result) | |
| 199 | 203 |
| 200 expected_compile_result = { | 204 expected_compile_result = { |
| 201 'report': [ | 205 'report': [ |
| 202 ['rev1', 'passed'], | 206 ['rev1', 'passed'], |
| 203 ['rev2', 'failed'] | 207 ['rev2', 'failed'] |
| 204 ], | 208 ], |
| 205 'url': 'url', | 209 'url': 'url', |
| 206 'try_job_id': '1', | 210 'try_job_id': '1', |
| 207 'culprit': { | 211 'culprit': { |
| 208 'revision': 'rev2', | 212 'revision': 'rev2', |
| 209 'commit_position': '2', | 213 'commit_position': '2', |
| 210 'review_url': 'url_2' | 214 'review_url': 'url_2' |
| 211 } | 215 } |
| 212 } | 216 } |
| 213 | 217 |
| 214 self.assertEqual(expected_compile_result['culprit'], culprit) | 218 self.assertEqual(expected_compile_result['culprit'], culprit) |
| 215 | 219 |
| 216 try_job = WfTryJob.Get(master_name, builder_name, build_number) | 220 try_job = WfTryJob.Get(master_name, builder_name, build_number) |
| 217 self.assertEqual(expected_compile_result, try_job.compile_results[-1]) | 221 self.assertEqual(expected_compile_result, try_job.compile_results[-1]) |
| 218 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | 222 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) |
| 223 | |
| 224 def testIdentifyCulpritForTestTryJobReturnNoneIfNoTryJobResult(self): | |
| 225 master_name = 'm' | |
| 226 builder_name = 'b' | |
| 227 build_number = 1 | |
| 228 | |
| 229 try_job = WfTryJob.Create(master_name, builder_name, build_number) | |
| 230 try_job.status = wf_analysis_status.ANALYZING | |
| 231 try_job.put() | |
| 232 | |
| 233 pipeline = IdentifyTryJobCulpritPipeline() | |
| 234 culprit = pipeline.run( | |
| 235 master_name, builder_name, build_number, ['rev1', 'rev2'], | |
| 236 TryJobType.TEST, '1', None) | |
| 237 | |
| 238 self.assertIsNone(culprit) | |
| 239 | |
| 240 def testIdentifyCulpritForTestTryJobReturnNoneIfNoRevisionToCheck(self): | |
| 241 master_name = 'm' | |
| 242 builder_name = 'b' | |
| 243 build_number = 1 | |
| 244 test_result = { | |
| 245 'report': { | |
| 246 'rev1': { | |
| 247 'a_test': { | |
| 248 'status': 'failed', | |
| 249 'valid': True, | |
| 250 'failures': ['a_test1'] | |
| 251 } | |
| 252 } | |
| 253 }, | |
| 254 'url': 'url', | |
| 255 'try_job_id': '1' | |
| 256 } | |
| 257 | |
| 258 try_job = WfTryJob.Create(master_name, builder_name, build_number) | |
| 259 try_job.status = wf_analysis_status.ANALYZING | |
| 260 try_job.put() | |
| 261 | |
| 262 pipeline = IdentifyTryJobCulpritPipeline() | |
| 263 culprit = pipeline.run( | |
| 264 master_name, builder_name, build_number, [], TryJobType.TEST, '1', | |
| 265 test_result) | |
| 266 | |
| 267 self.assertIsNone(culprit) | |
| 268 | |
| 269 def testIdentifyCulpritForTestTryJobReturnNoneIfNoCulpritInfo(self): | |
| 270 master_name = 'm' | |
| 271 builder_name = 'b' | |
| 272 build_number = 1 | |
| 273 test_result = { | |
| 274 'report': { | |
| 275 'rev3': { | |
| 276 'a_test': { | |
| 277 'status': 'failed', | |
| 278 'valid': True, | |
| 279 'failures': ['a_test1'] | |
| 280 } | |
| 281 } | |
| 282 }, | |
| 283 'url': 'url', | |
| 284 'try_job_id': '1' | |
| 285 } | |
| 286 | |
| 287 try_job = WfTryJob.Create(master_name, builder_name, build_number) | |
| 288 try_job.status = wf_analysis_status.ANALYZING | |
| 289 try_job.put() | |
| 290 | |
| 291 pipeline = IdentifyTryJobCulpritPipeline() | |
| 292 culprit = pipeline.run( | |
| 293 master_name, builder_name, build_number, ['rev3'], TryJobType.TEST, | |
| 294 '1', test_result) | |
| 295 | |
| 296 expected_culprit = { | |
| 297 'a_test': { | |
| 298 'tests':{ | |
| 299 'a_test1': { | |
| 300 'revision': 'rev3' | |
| 301 } | |
| 302 } | |
| 303 } | |
| 304 } | |
| 305 self.assertEqual(expected_culprit, culprit) | |
| 306 | |
| 307 def testIdentifyCulpritForTestTryJobSuccess(self): | |
| 308 master_name = 'm' | |
| 309 builder_name = 'b' | |
| 310 build_number = 1 | |
| 311 test_result = { | |
| 312 'report': { | |
| 313 'rev1': { | |
| 314 'a_test': { | |
| 315 'status': 'failed', | |
| 316 'valid': True, | |
| 317 'failures': ['a_test1'] | |
| 318 }, | |
| 319 'b_test': { | |
| 320 'status': 'failed', | |
| 321 'valid': True, | |
| 322 'failures': ['b_test1'] | |
| 323 }, | |
| 324 'c_test': { | |
| 325 'status': 'passed', | |
| 326 'valid': True | |
| 327 } | |
| 328 }, | |
| 329 'rev2': { | |
| 330 'a_test': { | |
| 331 'status': 'failed', | |
| 332 'valid': True, | |
| 333 'failures': ['a_test1', 'a_test2'] | |
| 334 }, | |
| 335 'b_test': { | |
| 336 'status': 'passed', | |
| 337 'valid': True | |
| 338 }, | |
| 339 'c_test': { | |
| 340 'status': 'failed', | |
| 341 'valid': True, | |
| 342 'failures': [] | |
| 343 } | |
| 344 } | |
| 345 }, | |
| 346 'url': 'url', | |
| 347 'try_job_id': '1' | |
| 348 } | |
| 349 | |
| 350 try_job = WfTryJob.Create(master_name, builder_name, build_number) | |
| 351 try_job.status = wf_analysis_status.ANALYZING | |
| 352 try_job.test_results = [test_result] | |
| 353 try_job.put() | |
| 354 | |
| 355 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) | |
| 356 | |
| 357 pipeline = IdentifyTryJobCulpritPipeline() | |
| 358 culprit = pipeline.run( | |
| 359 master_name, builder_name, build_number, ['rev1', 'rev2'], | |
| 360 TryJobType.TEST, '1', test_result) | |
| 361 | |
| 362 expected_test_result = { | |
| 363 'report': { | |
| 364 'rev1': { | |
| 365 'a_test': { | |
| 366 'status': 'failed', | |
| 367 'valid': True, | |
| 368 'failures': ['a_test1'] | |
| 369 }, | |
| 370 'b_test': { | |
| 371 'status': 'failed', | |
| 372 'valid': True, | |
| 373 'failures': ['b_test1'] | |
| 374 }, | |
| 375 'c_test': { | |
| 376 'status': 'passed', | |
| 377 'valid': True | |
| 378 } | |
| 379 }, | |
| 380 'rev2': { | |
| 381 'a_test': { | |
| 382 'status': 'failed', | |
| 383 'valid': True, | |
| 384 'failures': ['a_test1', 'a_test2'] | |
| 385 }, | |
| 386 'b_test': { | |
| 387 'status': 'passed', | |
| 388 'valid': True | |
| 389 }, | |
| 390 'c_test': { | |
| 391 'status': 'failed', | |
| 392 'valid': True, | |
| 393 'failures': [] | |
| 394 } | |
| 395 } | |
| 396 }, | |
| 397 'url': 'url', | |
| 398 'try_job_id': '1', | |
| 399 'culprit': { | |
| 400 'a_test': { | |
| 401 'tests': { | |
| 402 'a_test1': { | |
| 403 'revision': 'rev1', | |
| 404 'commit_position': '1', | |
| 405 'review_url': 'url_1' | |
| 406 }, | |
| 407 'a_test2': { | |
| 408 'revision': 'rev2', | |
| 409 'commit_position': '2', | |
| 410 'review_url': 'url_2' | |
| 411 } | |
| 412 } | |
| 413 }, | |
| 414 'b_test': { | |
| 415 'tests': { | |
| 416 'b_test1': { | |
| 417 'revision': 'rev1', | |
| 418 'commit_position': '1', | |
| 419 'review_url': 'url_1' | |
| 420 } | |
| 421 } | |
| 422 }, | |
| 423 'c_test': { | |
| 424 'revision': 'rev2', | |
| 425 'commit_position': '2', | |
| 426 'review_url': 'url_2', | |
| 427 'tests': {} | |
| 428 } | |
| 429 } | |
| 430 } | |
| 431 | |
| 432 self.assertEqual(expected_test_result['culprit'], culprit) | |
| 433 | |
| 434 try_job = WfTryJob.Get(master_name, builder_name, build_number) | |
| 435 self.assertEqual(expected_test_result, try_job.test_results[-1]) | |
| 436 self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | |
| OLD | NEW |