| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 import os | 5 import os |
| 6 import re | 6 import re |
| 7 | 7 |
| 8 from google.appengine.ext import testbed | 8 from google.appengine.ext import testbed |
| 9 | 9 |
| 10 import webapp2 | 10 import webapp2 |
| 11 import webtest | 11 import webtest |
| 12 | 12 |
| 13 from handlers import build_failure | 13 from handlers import build_failure |
| 14 from handlers import handlers_util | 14 from handlers import handlers_util |
| 15 from handlers import result_status | 15 from handlers import result_status |
| 16 from model.wf_analysis import WfAnalysis | 16 from model.wf_analysis import WfAnalysis |
| 17 from model import wf_analysis_status | 17 from model import analysis_status |
| 18 from model.wf_analysis import WfAnalysis | 18 from model.wf_analysis import WfAnalysis |
| 19 from waterfall import buildbot | 19 from waterfall import buildbot |
| 20 from waterfall.test import wf_testcase | 20 from waterfall.test import wf_testcase |
| 21 | 21 |
| 22 # Root directory appengine/findit. | 22 # Root directory appengine/findit. |
| 23 ROOT_DIR = os.path.join(os.path.dirname(__file__), | 23 ROOT_DIR = os.path.join(os.path.dirname(__file__), |
| 24 os.path.pardir, os.path.pardir) | 24 os.path.pardir, os.path.pardir) |
| 25 | 25 |
| 26 SAMPLE_TRY_JOB_INFO = { | 26 SAMPLE_TRY_JOB_INFO = { |
| 27 'm/b/119': { | 27 'm/b/119': { |
| 28 'step1 on platform':{ | 28 'step1 on platform':{ |
| 29 'try_jobs': [ | 29 'try_jobs': [ |
| 30 { | 30 { |
| 31 'ref_name': 'step1', | 31 'ref_name': 'step1', |
| 32 'try_job_key': 'm/b/119', | 32 'try_job_key': 'm/b/119', |
| 33 'task_id': 'task1', | 33 'task_id': 'task1', |
| 34 'task_url': 'url/task1', | 34 'task_url': 'url/task1', |
| 35 'status': wf_analysis_status.ANALYZED, | 35 'status': analysis_status.COMPLETED, |
| 36 'try_job_url': ( | 36 'try_job_url': ( |
| 37 'http://build.chromium.org/p/tryserver.chromium.' | 37 'http://build.chromium.org/p/tryserver.chromium.' |
| 38 'linux/builders/linux_variable/builds/121'), | 38 'linux/builders/linux_variable/builds/121'), |
| 39 'try_job_build_number': 121, | 39 'try_job_build_number': 121, |
| 40 'tests': ['test3'], | 40 'tests': ['test3'], |
| 41 'culprit': {} | 41 'culprit': {} |
| 42 }, | 42 }, |
| 43 { | 43 { |
| 44 'ref_name': 'step1', | 44 'ref_name': 'step1', |
| 45 'try_job_key': 'm/b/119', | 45 'try_job_key': 'm/b/119', |
| 46 'task_id': 'task1', | 46 'task_id': 'task1', |
| 47 'task_url': 'url/task1', | 47 'task_url': 'url/task1', |
| 48 'status': wf_analysis_status.ANALYZED, | 48 'status': analysis_status.COMPLETED, |
| 49 'try_job_url': ( | 49 'try_job_url': ( |
| 50 'http://build.chromium.org/p/tryserver.chromium.' | 50 'http://build.chromium.org/p/tryserver.chromium.' |
| 51 'linux/builders/linux_variable/builds/121'), | 51 'linux/builders/linux_variable/builds/121'), |
| 52 'try_job_build_number': 121, | 52 'try_job_build_number': 121, |
| 53 'culprit': { | 53 'culprit': { |
| 54 'revision': 'rev2', | 54 'revision': 'rev2', |
| 55 'commit_position': '2', | 55 'commit_position': '2', |
| 56 'review_url': 'url_2' | 56 'review_url': 'url_2' |
| 57 }, | 57 }, |
| 58 'tests': ['test2'] | 58 'tests': ['test2'] |
| 59 }, | 59 }, |
| 60 { | 60 { |
| 61 'ref_name': 'step1', | 61 'ref_name': 'step1', |
| 62 'try_job_key': 'm/b/119', | 62 'try_job_key': 'm/b/119', |
| 63 'status': result_status.FLAKY, | 63 'status': result_status.FLAKY, |
| 64 'task_id': 'task1', | 64 'task_id': 'task1', |
| 65 'task_url': 'url/task1', | 65 'task_url': 'url/task1', |
| 66 'tests': ['test4'] | 66 'tests': ['test4'] |
| 67 }, | 67 }, |
| 68 { | 68 { |
| 69 'ref_name': 'step1', | 69 'ref_name': 'step1', |
| 70 'try_job_key': 'm/b/120', | 70 'try_job_key': 'm/b/120', |
| 71 'status': result_status.NO_TRY_JOB_REASON_MAP[ | 71 'status': result_status.NO_TRY_JOB_REASON_MAP[ |
| 72 wf_analysis_status.PENDING], | 72 analysis_status.PENDING], |
| 73 'task_id': 'task2', | 73 'task_id': 'task2', |
| 74 'task_url': 'url/task2', | 74 'task_url': 'url/task2', |
| 75 'tests': ['test1'] | 75 'tests': ['test1'] |
| 76 } | 76 } |
| 77 ] | 77 ] |
| 78 } | 78 } |
| 79 }, | 79 }, |
| 80 'm/b/120': { | 80 'm/b/120': { |
| 81 'compile': { | 81 'compile': { |
| 82 'try_jobs': [ | 82 'try_jobs': [ |
| 83 { | 83 { |
| 84 'try_job_key': 'm/b/120', | 84 'try_job_key': 'm/b/120', |
| 85 'status': wf_analysis_status.ANALYZED, | 85 'status': analysis_status.COMPLETED, |
| 86 'try_job_build_number': 120, | 86 'try_job_build_number': 120, |
| 87 'try_job_url': ( | 87 'try_job_url': ( |
| 88 'http://build.chromium.org/p/tryserver.chromium.' | 88 'http://build.chromium.org/p/tryserver.chromium.' |
| 89 'linux/builders/linux_variable/builds/120'), | 89 'linux/builders/linux_variable/builds/120'), |
| 90 'culprit': { | 90 'culprit': { |
| 91 'revision': 'rev2', | 91 'revision': 'rev2', |
| 92 'commit_position': '2', | 92 'commit_position': '2', |
| 93 'review_url': 'url_2' | 93 'review_url': 'url_2' |
| 94 } | 94 } |
| 95 } | 95 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 113 for queue in self.taskqueue_stub.GetQueues(): | 113 for queue in self.taskqueue_stub.GetQueues(): |
| 114 self.taskqueue_stub.FlushQueue(queue['name']) | 114 self.taskqueue_stub.FlushQueue(queue['name']) |
| 115 | 115 |
| 116 def MockedGetAllTryJobResults(master_name, builder_name, build_number): | 116 def MockedGetAllTryJobResults(master_name, builder_name, build_number): |
| 117 build_key = '%s/%s/%d' % (master_name, builder_name, build_number) | 117 build_key = '%s/%s/%d' % (master_name, builder_name, build_number) |
| 118 return SAMPLE_TRY_JOB_INFO.get(build_key, None) | 118 return SAMPLE_TRY_JOB_INFO.get(build_key, None) |
| 119 self.mock(handlers_util, 'GetAllTryJobResults', MockedGetAllTryJobResults) | 119 self.mock(handlers_util, 'GetAllTryJobResults', MockedGetAllTryJobResults) |
| 120 | 120 |
| 121 def testGetTriageHistoryWhenUserIsNotAdmin(self): | 121 def testGetTriageHistoryWhenUserIsNotAdmin(self): |
| 122 analysis = WfAnalysis.Create('m', 'b', 1) | 122 analysis = WfAnalysis.Create('m', 'b', 1) |
| 123 analysis.status = wf_analysis_status.ANALYZED | 123 analysis.status = analysis_status.COMPLETED |
| 124 analysis.triage_history = [ | 124 analysis.triage_history = [ |
| 125 { | 125 { |
| 126 'triage_timestamp': 1438380761, | 126 'triage_timestamp': 1438380761, |
| 127 'user_name': 'test', | 127 'user_name': 'test', |
| 128 'result_status': 'dummy status', | 128 'result_status': 'dummy status', |
| 129 'version': 'dummy version', | 129 'version': 'dummy version', |
| 130 } | 130 } |
| 131 ] | 131 ] |
| 132 self.assertIsNone(build_failure._GetTriageHistory(analysis)) | 132 self.assertIsNone(build_failure._GetTriageHistory(analysis)) |
| 133 | 133 |
| 134 def testGetTriageHistoryWhenUserIsAdmin(self): | 134 def testGetTriageHistoryWhenUserIsAdmin(self): |
| 135 analysis = WfAnalysis.Create('m', 'b', 1) | 135 analysis = WfAnalysis.Create('m', 'b', 1) |
| 136 analysis.status = wf_analysis_status.ANALYZED | 136 analysis.status = analysis_status.COMPLETED |
| 137 analysis.triage_history = [ | 137 analysis.triage_history = [ |
| 138 { | 138 { |
| 139 'triage_timestamp': 1438380761, | 139 'triage_timestamp': 1438380761, |
| 140 'user_name': 'test', | 140 'user_name': 'test', |
| 141 'result_status': 'dummy status', | 141 'result_status': 'dummy status', |
| 142 'version': 'dummy version', | 142 'version': 'dummy version', |
| 143 } | 143 } |
| 144 ] | 144 ] |
| 145 self.mock_current_user(user_email='test@chromium.org', is_admin=True) | 145 self.mock_current_user(user_email='test@chromium.org', is_admin=True) |
| 146 self.assertEqual(1, len(build_failure._GetTriageHistory(analysis))) | 146 self.assertEqual(1, len(build_failure._GetTriageHistory(analysis))) |
| 147 | 147 |
| 148 def testInvalidBuildUrl(self): | 148 def testInvalidBuildUrl(self): |
| 149 build_url = 'abc' | 149 build_url = 'abc' |
| 150 self.assertRaisesRegexp( | 150 self.assertRaisesRegexp( |
| 151 webtest.app.AppError, | 151 webtest.app.AppError, |
| 152 re.compile('.*501 Not Implemented.*Url "%s" ' | 152 re.compile('.*501 Not Implemented.*Url "%s" ' |
| 153 'is not pointing to a build.*' % build_url, | 153 'is not pointing to a build.*' % build_url, |
| 154 re.MULTILINE | re.DOTALL), | 154 re.MULTILINE | re.DOTALL), |
| 155 self.test_app.get, '/build-failure', params={'url': build_url}) | 155 self.test_app.get, '/build-failure', params={'url': build_url}) |
| 156 | 156 |
| 157 def testNonAdminCanViewAnalysisOfFailureOnUnsupportedMaster(self): | 157 def testNonAdminCanViewAnalysisOfFailureOnUnsupportedMaster(self): |
| 158 master_name = 'm2' | 158 master_name = 'm2' |
| 159 builder_name = 'b 1' | 159 builder_name = 'b 1' |
| 160 build_number = 123 | 160 build_number = 123 |
| 161 build_url = buildbot.CreateBuildUrl( | 161 build_url = buildbot.CreateBuildUrl( |
| 162 master_name, builder_name, build_number) | 162 master_name, builder_name, build_number) |
| 163 | 163 |
| 164 analysis = WfAnalysis.Create(master_name, builder_name, build_number) | 164 analysis = WfAnalysis.Create(master_name, builder_name, build_number) |
| 165 analysis.status = wf_analysis_status.ANALYZED | 165 analysis.status = analysis_status.COMPLETED |
| 166 analysis.put() | 166 analysis.put() |
| 167 | 167 |
| 168 response = self.test_app.get('/build-failure', | 168 response = self.test_app.get('/build-failure', |
| 169 params={'url': build_url}) | 169 params={'url': build_url}) |
| 170 self.assertEquals(200, response.status_int) | 170 self.assertEquals(200, response.status_int) |
| 171 self.assertEqual(0, len(self.taskqueue_stub.get_filtered_tasks())) | 171 self.assertEqual(0, len(self.taskqueue_stub.get_filtered_tasks())) |
| 172 | 172 |
| 173 def testNonAdminCannotRequestAnalysisOfFailureOnUnsupportedMaster(self): | 173 def testNonAdminCannotRequestAnalysisOfFailureOnUnsupportedMaster(self): |
| 174 master_name = 'm2' | 174 master_name = 'm2' |
| 175 builder_name = 'b 1' | 175 builder_name = 'b 1' |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 expected_result = { | 417 expected_result = { |
| 418 'step1 on platform':{ | 418 'step1 on platform':{ |
| 419 'results': { | 419 'results': { |
| 420 'reliable_failures': [ | 420 'reliable_failures': [ |
| 421 { | 421 { |
| 422 'try_job':{ | 422 'try_job':{ |
| 423 'ref_name': 'step1', | 423 'ref_name': 'step1', |
| 424 'try_job_key': 'm/b/119', | 424 'try_job_key': 'm/b/119', |
| 425 'task_id': 'task1', | 425 'task_id': 'task1', |
| 426 'task_url': 'url/task1', | 426 'task_url': 'url/task1', |
| 427 'status': wf_analysis_status.ANALYZED, | 427 'status': analysis_status.COMPLETED, |
| 428 'try_job_url': ( | 428 'try_job_url': ( |
| 429 'http://build.chromium.org/p/tryserver.chromium' | 429 'http://build.chromium.org/p/tryserver.chromium' |
| 430 '.linux/builders/linux_variable/builds/121'), | 430 '.linux/builders/linux_variable/builds/121'), |
| 431 'try_job_build_number': 121, | 431 'try_job_build_number': 121, |
| 432 'tests': ['test3'], | 432 'tests': ['test3'], |
| 433 'culprit': {} | 433 'culprit': {} |
| 434 }, | 434 }, |
| 435 'heuristic_analysis': { | 435 'heuristic_analysis': { |
| 436 'suspected_cls': [ | 436 'suspected_cls': [ |
| 437 { | 437 { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 452 'first_failure': 119, | 452 'first_failure': 119, |
| 453 'last_pass': 118, | 453 'last_pass': 118, |
| 454 'supported': True | 454 'supported': True |
| 455 }, | 455 }, |
| 456 { | 456 { |
| 457 'try_job':{ | 457 'try_job':{ |
| 458 'ref_name': 'step1', | 458 'ref_name': 'step1', |
| 459 'try_job_key': 'm/b/119', | 459 'try_job_key': 'm/b/119', |
| 460 'task_id': 'task1', | 460 'task_id': 'task1', |
| 461 'task_url': 'url/task1', | 461 'task_url': 'url/task1', |
| 462 'status': wf_analysis_status.ANALYZED, | 462 'status': analysis_status.COMPLETED, |
| 463 'try_job_url': ( | 463 'try_job_url': ( |
| 464 'http://build.chromium.org/p/tryserver.chromium' | 464 'http://build.chromium.org/p/tryserver.chromium' |
| 465 '.linux/builders/linux_variable/builds/121'), | 465 '.linux/builders/linux_variable/builds/121'), |
| 466 'try_job_build_number': 121, | 466 'try_job_build_number': 121, |
| 467 'culprit': { | 467 'culprit': { |
| 468 'revision': 'rev2', | 468 'revision': 'rev2', |
| 469 'commit_position': '2', | 469 'commit_position': '2', |
| 470 'review_url': 'url_2' | 470 'review_url': 'url_2' |
| 471 }, | 471 }, |
| 472 'tests': ['test2'] | 472 'tests': ['test2'] |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 'last_pass': 118, | 511 'last_pass': 118, |
| 512 'supported': True | 512 'supported': True |
| 513 } | 513 } |
| 514 ], | 514 ], |
| 515 'unclassified_failures': [ | 515 'unclassified_failures': [ |
| 516 { | 516 { |
| 517 'try_job':{ | 517 'try_job':{ |
| 518 'ref_name': 'step1', | 518 'ref_name': 'step1', |
| 519 'try_job_key': 'm/b/120', | 519 'try_job_key': 'm/b/120', |
| 520 'status': result_status.NO_TRY_JOB_REASON_MAP[ | 520 'status': result_status.NO_TRY_JOB_REASON_MAP[ |
| 521 wf_analysis_status.PENDING], | 521 analysis_status.PENDING], |
| 522 'task_id': 'task2', | 522 'task_id': 'task2', |
| 523 'task_url': 'url/task2', | 523 'task_url': 'url/task2', |
| 524 'tests': ['test1'] | 524 'tests': ['test1'] |
| 525 }, | 525 }, |
| 526 'heuristic_analysis': { | 526 'heuristic_analysis': { |
| 527 'suspected_cls': [] | 527 'suspected_cls': [] |
| 528 }, | 528 }, |
| 529 'tests': ['test1'], | 529 'tests': ['test1'], |
| 530 'first_failure': 120, | 530 'first_failure': 120, |
| 531 'last_pass': 119, | 531 'last_pass': 119, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 result = build_failure._GetAnalysisResultWithTryJobInfo( | 573 result = build_failure._GetAnalysisResultWithTryJobInfo( |
| 574 organized_results, 'm', 'b', 120) | 574 organized_results, 'm', 'b', 120) |
| 575 | 575 |
| 576 expected_result = { | 576 expected_result = { |
| 577 'compile':{ | 577 'compile':{ |
| 578 'results': { | 578 'results': { |
| 579 'reliable_failures': [ | 579 'reliable_failures': [ |
| 580 { | 580 { |
| 581 'try_job': { | 581 'try_job': { |
| 582 'try_job_key': 'm/b/120', | 582 'try_job_key': 'm/b/120', |
| 583 'status': wf_analysis_status.ANALYZED, | 583 'status': analysis_status.COMPLETED, |
| 584 'try_job_build_number': 120, | 584 'try_job_build_number': 120, |
| 585 'try_job_url': ( | 585 'try_job_url': ( |
| 586 'http://build.chromium.org/p/tryserver.chromium' | 586 'http://build.chromium.org/p/tryserver.chromium' |
| 587 '.linux/builders/linux_variable/builds/120'), | 587 '.linux/builders/linux_variable/builds/120'), |
| 588 'culprit': { | 588 'culprit': { |
| 589 'revision': 'rev2', | 589 'revision': 'rev2', |
| 590 'commit_position': '2', | 590 'commit_position': '2', |
| 591 'review_url': 'url_2' | 591 'review_url': 'url_2' |
| 592 } | 592 } |
| 593 }, | 593 }, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 609 'tests': [], | 609 'tests': [], |
| 610 'first_failure': 120, | 610 'first_failure': 120, |
| 611 'last_pass': 119, | 611 'last_pass': 119, |
| 612 'supported': True | 612 'supported': True |
| 613 } | 613 } |
| 614 ] | 614 ] |
| 615 } | 615 } |
| 616 } | 616 } |
| 617 } | 617 } |
| 618 self.assertEqual(expected_result, result) | 618 self.assertEqual(expected_result, result) |
| OLD | NEW |