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

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: Some refactoring 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
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..acc0a0fc8ade8d85ba82ad7ed1caef4795ae0072 100644
--- a/appengine/findit/handlers/test/triage_analysis_test.py
+++ b/appengine/findit/handlers/test/triage_analysis_test.py
@@ -2,6 +2,9 @@
# 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
@@ -33,6 +36,9 @@ class TriageAnalysisTest(testing.AppengineTestCase):
'url': 'https://codereview.chromium.org/123',
}]
+ self.build_start_time = (datetime.utcnow() - timedelta(1)).replace(
+ hour=12, minute=0, second=0, microsecond=0) # Yesterday, 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': 'interactive_ui_tests',
+ 'suspected_cls': [
+ {
+ 'revision': '3cf9343f4602d4ec11717cb6ff56a793c1d5f84b',
lijeffrey 2016/06/24 01:30:06 nit: for consistency with the rest of the changes
josiahk 2016/06/24 18:12:38 Done.
+ }
+ ],
+ }
+ ]
+ }
+ 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': 'browser_tests'
+ },
+ {
+ 'suspected_cls': [
+ {
+ 'revision': '0e8dc209f5e4a6140e43551de0e036324c68a383',
+ }
+ ],
+ 'step_name': 'content_browsertests'
+ }
+ ]
+ }
+ 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': 'browser_tests',
+ },
+ {
+ 'suspected_cls': [
+ {
+ 'revision': '0e8dc209f5e4a6140e43551de0e036324c68a383',
+ },
+ {
+ 'revision': '292b41bbd603ae2f11d239f457a8a5f04387fa85',
+ },
+ {
+ 'revision': 'f6c9ef029e28a6bef28e727cd70751d782963e21',
+ }
+ ],
+ 'step_name': 'content_browsertests',
+ }
+ ]
+ }
+ 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': 'browser_tests',
+ },
+ {
+ 'suspected_cls': [
+ {
+ 'revision': '0e8dc209f5e4a6140e43551de0e036324c68a383',
+ },
+ {
+ 'revision': '292b41bbd603ae2f11d239f457a8a5f04387fa85',
+ },
+ {
+ 'revision': 'f6c9ef029e28a6bef28e727cd70751d782963e21',
+ }
+ ],
+ 'step_name': 'content_browsertests',
+ }
+ ]
+ }
+ 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': 'interactive_ui_tests',
lijeffrey 2016/06/24 01:30:06 nit: use general test names, i.e. 'step_name': 'st
josiahk 2016/06/24 18:12:38 Done.
+ 'suspected_cls': [
+ {
+ 'revision': '3cf9343f4602d4ec11717cb6ff56a793c1d5f84b',
+ }
+ ],
+ }
+ ]
+ }
+ 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': 'interactive_ui_tests',
+ 'suspected_cls': [
+ {
+ 'revision': '3cf9343f4602d4ec11717cb6ff56a793c1d5f84b',
+ }
+ ],
+ }
+ ]
+ }
+ 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': 'turing_test',
+ }
+ ]
+ }
+ 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):
+ # Yesterday, UTC Noon.
+ original_time = (datetime.utcnow() - timedelta(days=1)).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):
+ # Yesterday, UTC Noon.
+ original_time = (datetime.utcnow() - timedelta(days=1)).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):
+ # Yesterday, UTC Noon.
+ original_time = (datetime.utcnow() - timedelta(days=1)).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):
+ # Yesterday, UTC Noon.
+ original_time = (datetime.utcnow() - timedelta(days=1)).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):
+ # Today, UTC Noon.
+ original_time = datetime.utcnow().replace(
+ hour=12, minute=0, second=0, microsecond=0)
+ analysis_original = self.createAnalysis(308, original_time)
+
+ # Create another analysis at the same time (also today).
+ self.createAnalysis(309, original_time)
+
+ self.assertEquals(
+ len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 0)
+
+ def testTriageDuplicateResults(self):
+ # Yesterday, UTC Noon.
+ original_time = (datetime.utcnow() - timedelta(days=1)).replace(
+ hour=12, minute=0, second=0, microsecond=0)
+ analysis_original = self.createAnalysis(310, original_time)
+
+ # Create another analysis at the same time (also yesterday).
+ 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') | appengine/findit/handlers/triage_analysis.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698