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