Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1273)

Unified Diff: appengine/findit/handlers/test/triage_analysis_test.py

Issue 2029873002: [Findit] Cross-platform triage (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Naming, periods, and whitespace. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | appengine/findit/handlers/triage_analysis.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: appengine/findit/handlers/test/triage_analysis_test.py
diff --git a/appengine/findit/handlers/test/triage_analysis_test.py b/appengine/findit/handlers/test/triage_analysis_test.py
index 7bf6bdaffa72019d7bfe0bfe1baa384a9c72ef05..cfb0ccbe8633dbfac65d2a865101af940be57930 100644
--- a/appengine/findit/handlers/test/triage_analysis_test.py
+++ b/appengine/findit/handlers/test/triage_analysis_test.py
@@ -2,15 +2,18 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+from datetime import datetime
+from datetime import timedelta
+
from google.appengine.ext import ndb
import webapp2
from testing_utils import testing
from handlers import triage_analysis
-from model.wf_analysis import WfAnalysis
-from model import result_status
from model import analysis_status
+from model import result_status
+from model.wf_analysis import WfAnalysis
from waterfall import buildbot
@@ -33,6 +36,9 @@ class TriageAnalysisTest(testing.AppengineTestCase):
'url': 'https://codereview.chromium.org/123',
}]
+ self.build_start_time = (datetime.utcnow() - timedelta(2)).replace(
+ hour=12, minute=0, second=0, microsecond=0) # Two days ago, UTC Noon.
+
analysis = WfAnalysis.Create(
self.master_name, self.builder_name, self.build_number_incomplete)
analysis.status = analysis_status.RUNNING
@@ -42,6 +48,7 @@ class TriageAnalysisTest(testing.AppengineTestCase):
self.master_name, self.builder_name, self.build_number_found)
analysis.status = analysis_status.COMPLETED
analysis.suspected_cls = self.suspected_cls
+ analysis.build_start_time = self.build_start_time
analysis.put()
analysis = WfAnalysis.Create(
@@ -52,7 +59,7 @@ class TriageAnalysisTest(testing.AppengineTestCase):
self.mock_current_user(user_email='test@chromium.org', is_admin=True)
def testUpdateAnalysisResultStatusWhenAnalysisIsIncomplete(self):
- success = triage_analysis._UpdateAnalysisResultStatus(
+ success, _ = triage_analysis._UpdateAnalysisResultStatus(
self.master_name, self.builder_name, self.build_number_incomplete, True)
self.assertFalse(success)
analysis = WfAnalysis.Get(
@@ -130,3 +137,329 @@ class TriageAnalysisTest(testing.AppengineTestCase):
params={'url': build_url, 'correct': True, 'format': 'json'})
self.assertEquals(200, response.status_int)
self.assertEquals({'success': True}, response.json_body)
+
+ def testIncompleteTriage(self):
+ build_url = buildbot.CreateBuildUrl(
+ self.master_name, self.builder_name, self.build_number_incomplete)
+ response = self.test_app.get(
+ '/triage-analysis',
+ params={'url': build_url, 'correct': True, 'format': 'json'})
+ self.assertEquals(200, response.status_int)
+ self.assertEquals({'success': False}, response.json_body)
+
+ def testAnalysesMatch(self):
+ analysis_with_empty_failures = WfAnalysis.Create(
+ self.master_name, self.builder_name, 200)
+ analysis_with_empty_failures.result = {
+ 'failures': []
+ }
+ analysis_with_empty_failures.put()
+
+ analysis_with_no_suspected_cls = WfAnalysis.Create(
+ self.master_name, self.builder_name, 201)
+ analysis_with_no_suspected_cls.result = {
+ 'failures': [
+ {
+ 'suspected_cls': []
+ },
+ {
+ 'suspected_cls': []
+ },
+ ]
+ }
+ analysis_with_no_suspected_cls.put()
+
+ analysis_with_suspected_cls_1 = WfAnalysis.Create(
+ self.master_name, self.builder_name, 202)
+ analysis_with_suspected_cls_1.result = {
+ 'failures': [
+ {
+ 'step_name': 'step1',
+ 'suspected_cls': [
+ {
+ 'revision': 'rev1',
+ }
+ ],
+ }
+ ]
+ }
+ analysis_with_suspected_cls_1.put()
+
+ analysis_with_suspected_cls_2 = WfAnalysis.Create(
+ self.master_name, self.builder_name, 203)
+ analysis_with_suspected_cls_2.result = {
+ 'failures': [
+ {
+ 'suspected_cls': [],
+ 'step_name': 'step2'
+ },
+ {
+ 'suspected_cls': [
+ {
+ 'revision': 'rev2',
+ }
+ ],
+ 'step_name': 'step3'
+ }
+ ]
+ }
+ analysis_with_suspected_cls_2.put()
+
+ analysis_with_suspected_cls_3 = WfAnalysis.Create(
+ self.master_name, self.builder_name, 204)
+ analysis_with_suspected_cls_3.result = {
+ 'failures': [
+ {
+ 'suspected_cls': [],
+ 'step_name': 'step2',
+ },
+ {
+ 'suspected_cls': [
+ {
+ 'revision': 'rev2',
+ },
+ {
+ 'revision': 'rev3',
+ },
+ {
+ 'revision': 'rev4',
+ }
+ ],
+ 'step_name': 'step3',
+ }
+ ]
+ }
+ analysis_with_suspected_cls_3.result_status = result_status.FOUND_UNTRIAGED
+ analysis_with_suspected_cls_3.build_start_time = self.build_start_time
+ analysis_with_suspected_cls_3.put()
+
+ analysis_with_suspected_cls_4 = WfAnalysis.Create(
+ self.master_name, self.builder_name, 205)
+ analysis_with_suspected_cls_4.result = {
+ 'failures': [
+ {
+ 'suspected_cls': [],
+ 'step_name': 'step2',
+ },
+ {
+ 'suspected_cls': [
+ {
+ 'revision': 'rev2',
+ },
+ {
+ 'revision': 'rev3',
+ },
+ {
+ 'revision': 'rev4',
+ }
+ ],
+ 'step_name': 'step3',
+ }
+ ]
+ }
+ analysis_with_suspected_cls_4.result_status = result_status.FOUND_UNTRIAGED
+ analysis_with_suspected_cls_4.build_start_time = self.build_start_time
+ analysis_with_suspected_cls_4.put()
+
+ analysis_with_tests_1 = WfAnalysis.Create(
+ self.master_name, self.builder_name, 206)
+ analysis_with_tests_1.result = {
+ 'failures': [
+ {
+ 'tests': [
+ {
+ 'test_name': 'super_test_1',
+ 'suspected_cls': [
+ {
+ 'revision': 'abc'
+ }
+ ]
+ }, {
+ 'test_name': 'super_test_2',
+ 'suspected_cls': [
+ {
+ 'revision': 'def'
+ },
+ {
+ 'revision': 'ghi'
+ }
+ ]
+ }
+ ],
+ 'step_name': 'step1',
+ 'suspected_cls': [
+ {
+ 'revision': 'rev1',
+ }
+ ],
+ }
+ ]
+ }
+ analysis_with_tests_1.put()
+
+ analysis_with_tests_2 = WfAnalysis.Create(
+ self.master_name, self.builder_name, 207)
+ analysis_with_tests_2.result = {
+ 'failures': [
+ {
+ 'tests': [
+ {
+ 'test_name': 'super_test_3',
+ 'suspected_cls': [
+ {
+ 'revision': 'ab'
+ },
+ {
+ 'revision': 'cd'
+ },
+ {
+ 'revision': 'ef'
+ }
+ ]
+ }
+ ],
+ 'step_name': 'step1',
+ 'suspected_cls': [
+ {
+ 'revision': 'rev1',
+ }
+ ],
+ }
+ ]
+ }
+ analysis_with_tests_2.put()
+
+ # Empty failures list.
+ self.assertFalse(triage_analysis._DoAnalysesMatch(
+ analysis_with_empty_failures,
+ analysis_with_empty_failures))
+ # Zero culprit-tuples.
+ self.assertFalse(triage_analysis._DoAnalysesMatch(
+ analysis_with_no_suspected_cls,
+ analysis_with_no_suspected_cls))
+ # Zero culprit-tuples and some culprit-tuples.
+ self.assertFalse(triage_analysis._DoAnalysesMatch(
+ analysis_with_no_suspected_cls,
+ analysis_with_suspected_cls_1))
+ # Has step-level culprit-tuples, and should detect match.
+ self.assertTrue(triage_analysis._DoAnalysesMatch(
+ analysis_with_suspected_cls_2,
+ analysis_with_suspected_cls_2))
+ # Two different step-level culprit-tuples, and should fail to match.
+ self.assertFalse(triage_analysis._DoAnalysesMatch(
+ analysis_with_suspected_cls_2,
+ analysis_with_suspected_cls_3))
+ # Has test-level culprit-tuples, and should detect match.
+ self.assertTrue(triage_analysis._DoAnalysesMatch(
+ analysis_with_tests_1,
+ analysis_with_tests_1))
+ # Two different test-level culprit-tuples, and should fail to match.
+ self.assertFalse(triage_analysis._DoAnalysesMatch(
+ analysis_with_tests_1,
+ analysis_with_tests_2))
+
+ def _createAnalysis(self, build_number, build_start_time):
+ analysis = WfAnalysis.Create(
+ self.master_name, self.builder_name, build_number)
+ analysis.result = {
+ 'failures': [
+ {
+ 'suspected_cls': [
+ {
+ 'revision': 'abc',
+ }
+ ],
+ 'step_name': 'step_4',
+ }
+ ]
+ }
+ analysis.result_status = result_status.FOUND_UNTRIAGED
+ analysis.build_start_time = build_start_time
+ analysis.status = analysis_status.COMPLETED
+ analysis.put()
+ return analysis
+
+ def testGetDuplicateAnalysesTooEarly(self):
+ # Two days ago, UTC Noon.
+ original_time = (datetime.utcnow() - timedelta(days=2)).replace(
+ hour=12, minute=0, second=0, microsecond=0)
+ analysis_original = self._createAnalysis(300, original_time)
+
+ # An earlier time, outside bounds.
+ too_early_time = (original_time - timedelta(
+ hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START*2))
+ self._createAnalysis(301, too_early_time)
+
+ self.assertEquals(
+ len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 0)
+
+ def testGetDuplicateAnalysesEarlier(self):
+ # Two days ago, UTC Noon.
+ original_time = (datetime.utcnow() - timedelta(days=2)).replace(
+ hour=12, minute=0, second=0, microsecond=0)
+ analysis_original = self._createAnalysis(302, original_time)
+
+ # An earlier time, within bounds.
+ earlier_time = (original_time - timedelta(
+ hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START/2))
+ self._createAnalysis(303, earlier_time)
+
+ self.assertEquals(
+ len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 1)
+
+ def testGetDuplicateAnalysesLater(self):
+ # Two days ago, UTC Noon.
+ original_time = (datetime.utcnow() - timedelta(days=2)).replace(
+ hour=12, minute=0, second=0, microsecond=0)
+ analysis_original = self._createAnalysis(304, original_time)
+
+ # A later time, within bounds.
+ later_time = (original_time + timedelta(
+ hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START/2))
+ self._createAnalysis(305, later_time)
+
+ self.assertEquals(
+ len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 1)
+
+ def testGetDuplicateAnalysesTooLate(self):
+ # Two days ago, UTC Noon.
+ original_time = (datetime.utcnow() - timedelta(days=2)).replace(
+ hour=12, minute=0, second=0, microsecond=0)
+ analysis_original = self._createAnalysis(306, original_time)
+
+ # A later time, outside bounds.
+ too_late_time = (original_time + timedelta(
+ hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START*2))
+ self._createAnalysis(307, too_late_time)
+
+ self.assertEquals(
+ len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 0)
+
+ def testGetDuplicateAnalysesNotToday(self):
+ # Tomorrow, UTC Noon.
+ original_time = (datetime.utcnow() + timedelta(days=1)).replace(
+ hour=12, minute=0, second=0, microsecond=0)
+ analysis_original = self._createAnalysis(308, original_time)
+
+ # Create another analysis at the same time (also tomorrow).
+ self._createAnalysis(309, original_time)
+
+ self.assertEquals(
+ len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 0)
+
+ def testTriageDuplicateResults(self):
+ # Two days ago, UTC Noon.
+ original_time = (datetime.utcnow() - timedelta(days=2)).replace(
+ hour=12, minute=0, second=0, microsecond=0)
+ analysis_original = self._createAnalysis(310, original_time)
+
+ # Create another analysis at the same time (also two days ago).
+ self._createAnalysis(311, original_time)
+
+ triage_analysis._TriageDuplicateResults(analysis_original, True)
+
+ second_analysis = WfAnalysis.Get(self.master_name, self.builder_name, 311)
+
+ self.assertEquals(result_status.NOT_FOUND_CORRECT,
+ second_analysis.result_status)
+
« no previous file with comments | « no previous file | appengine/findit/handlers/triage_analysis.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698