| 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 import analysis_approach_type |
| 16 from model.base_build_model import BaseBuildModel | 17 from model.base_build_model import BaseBuildModel |
| 17 from model.wf_analysis import WfAnalysis | 18 from model.wf_analysis import WfAnalysis |
| 18 from model.wf_try_job import WfTryJob | 19 from model.wf_try_job import WfTryJob |
| 19 from model import analysis_status | 20 from model import analysis_status |
| 21 from model import suspected_cl_status |
| 22 from model.base_build_model import BaseBuildModel |
| 20 from model.wf_analysis import WfAnalysis | 23 from model.wf_analysis import WfAnalysis |
| 24 from model.wf_suspected_cl import WfSuspectedCL |
| 25 from model.wf_try_job import WfTryJob |
| 21 from waterfall import buildbot | 26 from waterfall import buildbot |
| 22 from waterfall.test import wf_testcase | 27 from waterfall.test import wf_testcase |
| 23 | 28 |
| 24 # Root directory appengine/findit. | 29 # Root directory appengine/findit. |
| 25 ROOT_DIR = os.path.join(os.path.dirname(__file__), | 30 ROOT_DIR = os.path.join(os.path.dirname(__file__), |
| 26 os.path.pardir, os.path.pardir) | 31 os.path.pardir, os.path.pardir) |
| 27 | 32 |
| 28 SAMPLE_TRY_JOB_INFO = { | 33 SAMPLE_TRY_JOB_INFO = { |
| 29 'm/b/119': { | 34 'm/b/119': { |
| 30 'step1 on platform': { | 35 'step1 on platform': { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 analysis.triage_history = [ | 139 analysis.triage_history = [ |
| 135 { | 140 { |
| 136 'triage_timestamp': 1438380761, | 141 'triage_timestamp': 1438380761, |
| 137 'user_name': 'test', | 142 'user_name': 'test', |
| 138 'result_status': 'dummy status', | 143 'result_status': 'dummy status', |
| 139 'version': 'dummy version', | 144 'version': 'dummy version', |
| 140 } | 145 } |
| 141 ] | 146 ] |
| 142 self.assertIsNone(build_failure._GetTriageHistory(analysis)) | 147 self.assertIsNone(build_failure._GetTriageHistory(analysis)) |
| 143 | 148 |
| 149 def testGetCLDict(self): |
| 150 analysis = WfAnalysis.Create('m', 'b', 1) |
| 151 analysis.suspected_cls = [ |
| 152 { |
| 153 'repo_name': 'chromium', |
| 154 'revision': 'rev2', |
| 155 'url': 'url', |
| 156 'commit_position': 123 |
| 157 } |
| 158 ] |
| 159 analysis.put() |
| 160 cl_info = 'chromium/rev1' |
| 161 self.assertEqual({}, build_failure._GetCLDict(analysis, cl_info)) |
| 162 |
| 163 def testGetCLDictNone(self): |
| 164 self.assertEqual({}, build_failure._GetCLDict(None, None)) |
| 165 |
| 144 def testGetTriageHistoryWhenUserIsAdmin(self): | 166 def testGetTriageHistoryWhenUserIsAdmin(self): |
| 145 analysis = WfAnalysis.Create('m', 'b', 1) | 167 analysis = WfAnalysis.Create('m', 'b', 1) |
| 146 analysis.status = analysis_status.COMPLETED | 168 analysis.status = analysis_status.COMPLETED |
| 169 analysis.suspected_cls = [ |
| 170 { |
| 171 'repo_name': 'chromium', |
| 172 'revision': 'rev1', |
| 173 'url': 'url', |
| 174 'commit_position': 123 |
| 175 } |
| 176 ] |
| 147 analysis.triage_history = [ | 177 analysis.triage_history = [ |
| 148 { | 178 { |
| 149 'triage_timestamp': 1438380761, | 179 'triage_timestamp': 1438380761, |
| 150 'user_name': 'test', | 180 'user_name': 'test', |
| 151 'result_status': 'dummy status', | 181 'result_status': 'dummy status', |
| 152 'version': 'dummy version', | 182 'version': 'dummy version', |
| 183 'triaged_cl': 'chromium/rev1' |
| 153 } | 184 } |
| 154 ] | 185 ] |
| 155 self.mock_current_user(user_email='test@chromium.org', is_admin=True) | 186 self.mock_current_user(user_email='test@chromium.org', is_admin=True) |
| 156 self.assertEqual(1, len(build_failure._GetTriageHistory(analysis))) | 187 self.assertEqual(1, len(build_failure._GetTriageHistory(analysis))) |
| 157 | 188 |
| 158 def testInvalidBuildUrl(self): | 189 def testInvalidBuildUrl(self): |
| 159 build_url = 'abc' | 190 build_url = 'abc' |
| 160 self.assertRaisesRegexp( | 191 self.assertRaisesRegexp( |
| 161 webtest.app.AppError, | 192 webtest.app.AppError, |
| 162 re.compile('.*501 Not Implemented.*Url "%s" ' | 193 re.compile('.*501 Not Implemented.*Url "%s" ' |
| 163 'is not pointing to a build.*' % build_url, | 194 'is not pointing to a build.*' % build_url, |
| 164 re.MULTILINE | re.DOTALL), | 195 re.MULTILINE | re.DOTALL), |
| 165 self.test_app.get, '/build-failure', params={'url': build_url}) | 196 self.test_app.get, '/build-failure', params={'url': build_url}) |
| 166 | 197 |
| 167 def testNonAdminCanViewAnalysisOfFailureOnUnsupportedMaster(self): | 198 def testNonAdminCanViewAnalysisOfFailureOnUnsupportedMaster(self): |
| 168 master_name = 'm2' | 199 master_name = 'm2' |
| 169 builder_name = 'b 1' | 200 builder_name = 'b 1' |
| 170 build_number = 123 | 201 build_number = 123 |
| 171 build_url = buildbot.CreateBuildUrl( | 202 build_url = buildbot.CreateBuildUrl( |
| 172 master_name, builder_name, build_number) | 203 master_name, builder_name, build_number) |
| 173 | 204 |
| 174 analysis = WfAnalysis.Create(master_name, builder_name, build_number) | 205 analysis = WfAnalysis.Create(master_name, builder_name, build_number) |
| 175 analysis.status = analysis_status.COMPLETED | 206 analysis.status = analysis_status.COMPLETED |
| 207 analysis.suspected_cls = [ |
| 208 { |
| 209 'repo_name': 'chromium', |
| 210 'revision': 'r99_2', |
| 211 'commit_position': None, |
| 212 'url': None, |
| 213 } |
| 214 ] |
| 176 analysis.put() | 215 analysis.put() |
| 177 | 216 |
| 178 response = self.test_app.get('/build-failure', | 217 response = self.test_app.get('/build-failure', |
| 179 params={'url': build_url}) | 218 params={'url': build_url}) |
| 180 self.assertEquals(200, response.status_int) | 219 self.assertEquals(200, response.status_int) |
| 181 self.assertEqual(0, len(self.taskqueue_stub.get_filtered_tasks())) | 220 self.assertEqual(0, len(self.taskqueue_stub.get_filtered_tasks())) |
| 182 | 221 |
| 183 def testNonAdminCannotRequestAnalysisOfFailureOnUnsupportedMaster(self): | 222 def testNonAdminCannotRequestAnalysisOfFailureOnUnsupportedMaster(self): |
| 184 master_name = 'm2' | 223 master_name = 'm2' |
| 185 builder_name = 'b 1' | 224 builder_name = 'b 1' |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 }, | 771 }, |
| 733 { | 772 { |
| 734 'step_name': 'steps', | 773 'step_name': 'steps', |
| 735 }, | 774 }, |
| 736 ] | 775 ] |
| 737 } | 776 } |
| 738 analysis.failure_result_map = { | 777 analysis.failure_result_map = { |
| 739 'compile': 'm/b/122', | 778 'compile': 'm/b/122', |
| 740 } | 779 } |
| 741 analysis.status = analysis_status.COMPLETED | 780 analysis.status = analysis_status.COMPLETED |
| 781 analysis.suspected_cls = [ |
| 782 { |
| 783 'repo_name': 'chromium', |
| 784 'revision': 'rev', |
| 785 'commit_position': 122, |
| 786 'url': None |
| 787 } |
| 788 ] |
| 742 analysis.put() | 789 analysis.put() |
| 743 | 790 |
| 744 try_job = WfTryJob.Create('m', 'b', 122) | 791 try_job = WfTryJob.Create('m', 'b', 122) |
| 745 try_job.status = analysis_status.COMPLETED | 792 try_job.status = analysis_status.COMPLETED |
| 746 try_job.compile_results = [ | 793 try_job.compile_results = [ |
| 747 { | 794 { |
| 748 'url': 'build/url', | 795 'url': 'build/url', |
| 749 'culprit': { | 796 'culprit': { |
| 750 'compile': { | 797 'compile': { |
| 751 'revision': 'rev', | 798 'revision': 'rev', |
| 752 } | 799 } |
| 753 } | 800 } |
| 754 } | 801 } |
| 755 ] | 802 ] |
| 756 try_job.put() | 803 try_job.put() |
| 757 | 804 |
| 805 suspected_cl = WfSuspectedCL.Create('chromium', 'rev', 122) |
| 806 suspected_cl.builds = { |
| 807 'm/b/123': { |
| 808 'failure_type': 'compile', |
| 809 'failures': None, |
| 810 'status': suspected_cl_status.CORRECT, |
| 811 'approach': analysis_approach_type.HEURISTIC, |
| 812 'top_score': 5, |
| 813 'Confidence': 97.9 |
| 814 } |
| 815 } |
| 816 suspected_cl.put() |
| 817 |
| 758 expected_try_job_result = { | 818 expected_try_job_result = { |
| 759 'status': 'completed', | 819 'status': 'completed', |
| 760 'url': 'build/url', | 820 'url': 'build/url', |
| 761 'completed': True, | 821 'completed': True, |
| 762 'culprit': { | 822 'culprit': { |
| 763 'revision': 'rev', | 823 'revision': 'rev', |
| 764 }, | 824 }, |
| 765 'failed': False, | 825 'failed': False, |
| 766 } | 826 } |
| 767 | 827 |
| 828 expected_suspected_cls = [ |
| 829 { |
| 830 'repo_name': 'chromium', |
| 831 'revision': 'rev', |
| 832 'commit_position': 122, |
| 833 'url': None, |
| 834 'status': suspected_cl_status.CORRECT |
| 835 } |
| 836 ] |
| 837 |
| 768 build_url = buildbot.CreateBuildUrl('m', 'b', 123) | 838 build_url = buildbot.CreateBuildUrl('m', 'b', 123) |
| 769 response = self.test_app.get('/build-failure', | 839 response = self.test_app.get('/build-failure', |
| 770 params={'url': build_url, 'format': 'json'}) | 840 params={'url': build_url, 'format': 'json'}) |
| 771 | 841 |
| 772 self.assertEquals(200, response.status_int) | 842 self.assertEquals(200, response.status_int) |
| 773 self.assertEqual(expected_try_job_result, response.json_body['try_job']) | 843 self.assertEqual(expected_try_job_result, response.json_body['try_job']) |
| 844 self.assertEqual( |
| 845 expected_suspected_cls, response.json_body['suspected_cls']) |
| 846 |
| 847 def testGetAllSuspectedCLsAndCheckStatus(self): |
| 848 master_name = 'm' |
| 849 builder_name = 'b' |
| 850 build_number = 123 |
| 851 analysis = WfAnalysis.Create(master_name, builder_name, build_number) |
| 852 analysis.suspected_cls = [ |
| 853 { |
| 854 'repo_name': 'chromium', |
| 855 'revision': 'rev', |
| 856 'commit_position': 122, |
| 857 'url': None |
| 858 } |
| 859 ] |
| 860 analysis.put() |
| 861 suspected_cl = WfSuspectedCL.Create('chromium', 'rev', 122) |
| 862 suspected_cl.builds = { |
| 863 'm/b/122': { |
| 864 'failure_type': 'compile', |
| 865 'failures': None, |
| 866 'status': suspected_cl_status.CORRECT, |
| 867 'approach': analysis_approach_type.HEURISTIC, |
| 868 'top_score': 5, |
| 869 'Confidence': 97.9 |
| 870 } |
| 871 } |
| 872 suspected_cl.put() |
| 873 |
| 874 expected_suspected_cls = [ |
| 875 { |
| 876 'repo_name': 'chromium', |
| 877 'revision': 'rev', |
| 878 'commit_position': 122, |
| 879 'url': None, |
| 880 'status': None |
| 881 } |
| 882 ] |
| 883 |
| 884 suspected_cls = build_failure._GetAllSuspectedCLsAndCheckStatus( |
| 885 master_name, builder_name, build_number, analysis) |
| 886 self.assertEqual( |
| 887 expected_suspected_cls, suspected_cls) |
| 888 |
| OLD | NEW |