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

Side by Side Diff: appengine/findit/handlers/test/triage_analysis_test.py

Issue 2086113004: [Findit] Show build analysis references in UI for Findit Cross-platform auto-triage (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@build-matching
Patch Set: Rebased on tip of tree Created 4 years, 5 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 unified diff | Download patch
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 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 from datetime import datetime 5 from datetime import datetime
6 from datetime import timedelta 6 from datetime import timedelta
7 7
8 from google.appengine.ext import ndb 8 from testing_utils import testing
9 import webapp2 9 import webapp2
10 10
11 from testing_utils import testing
12
13 from handlers import triage_analysis 11 from handlers import triage_analysis
14 from model import analysis_status 12 from model import analysis_status
15 from model import result_status 13 from model import result_status
16 from model.wf_analysis import WfAnalysis 14 from model.wf_analysis import WfAnalysis
17 from waterfall import buildbot 15 from waterfall import buildbot
18 16
19 17
20 class TriageAnalysisTest(testing.AppengineTestCase): 18 class TriageAnalysisTest(testing.AppengineTestCase):
21 app_module = webapp2.WSGIApplication([ 19 app_module = webapp2.WSGIApplication([
22 ('/triage-analysis', triage_analysis.TriageAnalysis), 20 ('/triage-analysis', triage_analysis.TriageAnalysis),
23 ], debug=True) 21 ], debug=True)
24 22
25 def setUp(self): 23 def setUp(self):
26 super(TriageAnalysisTest, self).setUp() 24 super(TriageAnalysisTest, self).setUp()
27 self.master_name = 'm' 25 self.master_name = 'm'
28 self.builder_name = 'b' 26 self.builder_name = 'b'
29 self.build_number_incomplete = 120 # Analysis is not completed yet. 27 self.build_number_incomplete = 120 # Analysis is not completed yet.
30 self.build_number_found = 122 # Suspected CLs are found for this build. 28 self.build_number_found = 122 # Suspected CLs are found for this build.
31 self.build_number_not_found = 123 # No suspected CLs found. 29 self.build_number_not_found = 123 # No suspected CLs found.
32 self.suspected_cls = [{ 30 self.suspected_cls = [{
33 'repo_name': 'chromium', 31 'repo_name': 'chromium',
34 'revision': 'r1', 32 'revision': 'r1',
35 'commit_position': 123, 33 'commit_position': 123,
36 'url': 'https://codereview.chromium.org/123', 34 'url': 'https://codereview.chromium.org/123',
37 }] 35 }]
38 36
39 self.build_start_time = (datetime.utcnow() - timedelta(2)).replace( 37 self.build_start_time = (datetime.utcnow() - timedelta(3)).replace(
40 hour=12, minute=0, second=0, microsecond=0) # Two days ago, UTC Noon. 38 hour=12, minute=0, second=0, microsecond=0) # Three days ago, UTC Noon.
41 39
42 analysis = WfAnalysis.Create( 40 analysis = WfAnalysis.Create(
43 self.master_name, self.builder_name, self.build_number_incomplete) 41 self.master_name, self.builder_name, self.build_number_incomplete)
44 analysis.status = analysis_status.RUNNING 42 analysis.status = analysis_status.RUNNING
45 analysis.put() 43 analysis.put()
46 44
47 analysis = WfAnalysis.Create( 45 analysis = WfAnalysis.Create(
48 self.master_name, self.builder_name, self.build_number_found) 46 self.master_name, self.builder_name, self.build_number_found)
49 analysis.status = analysis_status.COMPLETED 47 analysis.status = analysis_status.COMPLETED
50 analysis.suspected_cls = self.suspected_cls 48 analysis.suspected_cls = self.suspected_cls
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 self.assertEquals(2, len(analysis.triage_history)) 116 self.assertEquals(2, len(analysis.triage_history))
119 self.assertEquals(result_status.FOUND_CORRECT, 117 self.assertEquals(result_status.FOUND_CORRECT,
120 analysis.triage_history[0]['result_status']) 118 analysis.triage_history[0]['result_status'])
121 self.assertEquals(result_status.FOUND_INCORRECT, 119 self.assertEquals(result_status.FOUND_INCORRECT,
122 analysis.triage_history[1]['result_status']) 120 analysis.triage_history[1]['result_status'])
123 121
124 def testInvalidBuildUrl(self): 122 def testInvalidBuildUrl(self):
125 build_url = 'http://invalid/build/url' 123 build_url = 'http://invalid/build/url'
126 response = self.test_app.get( 124 response = self.test_app.get(
127 '/triage-analysis', 125 '/triage-analysis',
128 params={'url': build_url, 'correct': True, 'format': 'json'}) 126 params={
127 'url': build_url,
128 'correct': True,
129 'format': 'json'
130 })
129 self.assertEquals(200, response.status_int) 131 self.assertEquals(200, response.status_int)
130 self.assertEquals({'success': False}, response.json_body) 132 self.assertEquals({'success': False}, response.json_body)
131 133
132 def testSuccessfulTriage(self): 134 def testSuccessfulTriage(self):
133 build_url = buildbot.CreateBuildUrl( 135 build_url = buildbot.CreateBuildUrl(
134 self.master_name, self.builder_name, self.build_number_found) 136 self.master_name, self.builder_name, self.build_number_found)
135 response = self.test_app.get( 137 response = self.test_app.get(
136 '/triage-analysis', 138 '/triage-analysis',
137 params={'url': build_url, 'correct': True, 'format': 'json'}) 139 params={
140 'url': build_url,
141 'correct': True,
142 'format': 'json'
143 })
138 self.assertEquals(200, response.status_int) 144 self.assertEquals(200, response.status_int)
139 self.assertEquals({'success': True}, response.json_body) 145 self.assertEquals(
146 {
147 'success': True,
148 'num_duplicate_analyses': 0
149 },
150 response.json_body)
140 151
141 def testIncompleteTriage(self): 152 def testIncompleteTriage(self):
142 build_url = buildbot.CreateBuildUrl( 153 build_url = buildbot.CreateBuildUrl(
143 self.master_name, self.builder_name, self.build_number_incomplete) 154 self.master_name, self.builder_name, self.build_number_incomplete)
144 response = self.test_app.get( 155 response = self.test_app.get(
145 '/triage-analysis', 156 '/triage-analysis',
146 params={'url': build_url, 'correct': True, 'format': 'json'}) 157 params={
158 'url': build_url,
159 'correct': True,
160 'format': 'json'
161 })
147 self.assertEquals(200, response.status_int) 162 self.assertEquals(200, response.status_int)
148 self.assertEquals({'success': False}, response.json_body) 163 self.assertEquals(
164 {
165 'success': False,
166 'num_duplicate_analyses': 0
167 },
168 response.json_body)
149 169
150 def testAnalysesMatch(self): 170 def testAnalysesMatch(self):
151 analysis_with_empty_failures = WfAnalysis.Create( 171 analysis_with_empty_failures = WfAnalysis.Create(
152 self.master_name, self.builder_name, 200) 172 self.master_name, self.builder_name, 200)
153 analysis_with_empty_failures.result = { 173 analysis_with_empty_failures.result = {
154 'failures': [] 174 'failures': []
155 } 175 }
156 analysis_with_empty_failures.put() 176 analysis_with_empty_failures.put()
157 177
158 analysis_with_no_suspected_cls = WfAnalysis.Create( 178 analysis_with_no_suspected_cls = WfAnalysis.Create(
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 self.assertFalse(triage_analysis._DoAnalysesMatch( 377 self.assertFalse(triage_analysis._DoAnalysesMatch(
358 analysis_with_tests_1, 378 analysis_with_tests_1,
359 analysis_with_tests_2)) 379 analysis_with_tests_2))
360 380
361 def _createAnalysis(self, build_number, build_start_time): 381 def _createAnalysis(self, build_number, build_start_time):
362 analysis = WfAnalysis.Create( 382 analysis = WfAnalysis.Create(
363 self.master_name, self.builder_name, build_number) 383 self.master_name, self.builder_name, build_number)
364 analysis.result = { 384 analysis.result = {
365 'failures': [ 385 'failures': [
366 { 386 {
367 'suspected_cls': [ 387 'suspected_cls': self.suspected_cls,
368 {
369 'revision': 'abc',
370 }
371 ],
372 'step_name': 'step_4', 388 'step_name': 'step_4',
373 } 389 }
374 ] 390 ]
375 } 391 }
376 analysis.result_status = result_status.FOUND_UNTRIAGED 392 analysis.result_status = result_status.FOUND_UNTRIAGED
377 analysis.build_start_time = build_start_time 393 analysis.build_start_time = build_start_time
378 analysis.status = analysis_status.COMPLETED 394 analysis.status = analysis_status.COMPLETED
395 analysis.suspected_cls = self.suspected_cls
379 analysis.put() 396 analysis.put()
380 return analysis 397 return analysis
381 398
382 def testGetDuplicateAnalysesTooEarly(self): 399 def testGetDuplicateAnalysesTooEarly(self):
383 # Two days ago, UTC Noon. 400 # Three days ago, UTC Noon.
384 original_time = (datetime.utcnow() - timedelta(days=2)).replace( 401 original_time = (datetime.utcnow() - timedelta(days=3)).replace(
385 hour=12, minute=0, second=0, microsecond=0) 402 hour=12, minute=0, second=0, microsecond=0)
386 analysis_original = self._createAnalysis(300, original_time) 403 analysis_original = self._createAnalysis(300, original_time)
387 404
388 # An earlier time, outside bounds. 405 # An earlier time, outside bounds.
389 too_early_time = (original_time - timedelta( 406 too_early_time = (original_time - timedelta(
390 hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START*2)) 407 hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START*2))
391 self._createAnalysis(301, too_early_time) 408 self._createAnalysis(301, too_early_time)
392 409
393 self.assertEquals( 410 self.assertEquals(
394 len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 0) 411 len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 0)
395 412
396 def testGetDuplicateAnalysesEarlier(self): 413 def testGetDuplicateAnalysesEarlier(self):
397 # Two days ago, UTC Noon. 414 # Three days ago, UTC Noon.
398 original_time = (datetime.utcnow() - timedelta(days=2)).replace( 415 original_time = (datetime.utcnow() - timedelta(days=3)).replace(
399 hour=12, minute=0, second=0, microsecond=0) 416 hour=12, minute=0, second=0, microsecond=0)
400 analysis_original = self._createAnalysis(302, original_time) 417 analysis_original = self._createAnalysis(302, original_time)
401 418
402 # An earlier time, within bounds. 419 # An earlier time, within bounds.
403 earlier_time = (original_time - timedelta( 420 earlier_time = (original_time - timedelta(
404 hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START/2)) 421 hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START/2))
405 self._createAnalysis(303, earlier_time) 422 self._createAnalysis(303, earlier_time)
406 423
407 self.assertEquals( 424 self.assertEquals(
408 len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 1) 425 len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 1)
409 426
410 def testGetDuplicateAnalysesLater(self): 427 def testGetDuplicateAnalysesLater(self):
411 # Two days ago, UTC Noon. 428 # Three days ago, UTC Noon.
412 original_time = (datetime.utcnow() - timedelta(days=2)).replace( 429 original_time = (datetime.utcnow() - timedelta(days=3)).replace(
413 hour=12, minute=0, second=0, microsecond=0) 430 hour=12, minute=0, second=0, microsecond=0)
414 analysis_original = self._createAnalysis(304, original_time) 431 analysis_original = self._createAnalysis(304, original_time)
415 432
416 # A later time, within bounds. 433 # A later time, within bounds.
417 later_time = (original_time + timedelta( 434 later_time = (original_time + timedelta(
418 hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START/2)) 435 hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START/2))
419 self._createAnalysis(305, later_time) 436 self._createAnalysis(305, later_time)
420 437
421 self.assertEquals( 438 self.assertEquals(
422 len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 1) 439 len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 1)
423 440
424 def testGetDuplicateAnalysesTooLate(self): 441 def testGetDuplicateAnalysesTooLate(self):
425 # Two days ago, UTC Noon. 442 # Three days ago, UTC Noon.
426 original_time = (datetime.utcnow() - timedelta(days=2)).replace( 443 original_time = (datetime.utcnow() - timedelta(days=3)).replace(
427 hour=12, minute=0, second=0, microsecond=0) 444 hour=12, minute=0, second=0, microsecond=0)
428 analysis_original = self._createAnalysis(306, original_time) 445 analysis_original = self._createAnalysis(306, original_time)
429 446
430 # A later time, outside bounds. 447 # A later time, outside bounds.
431 too_late_time = (original_time + timedelta( 448 too_late_time = (original_time + timedelta(
432 hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START*2)) 449 hours=triage_analysis.MATCHING_ANALYSIS_HOURS_AGO_START*2))
433 self._createAnalysis(307, too_late_time) 450 self._createAnalysis(307, too_late_time)
434 451
435 self.assertEquals( 452 self.assertEquals(
436 len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 0) 453 len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 0)
437 454
438 def testGetDuplicateAnalysesNotToday(self): 455 def testGetDuplicateAnalysesPastEndBoundTime(self):
439 # Tomorrow, UTC Noon. 456 # Tomorrow, UTC Noon.
440 original_time = (datetime.utcnow() + timedelta(days=1)).replace( 457 original_time = (datetime.utcnow() + timedelta(days=1)).replace(
441 hour=12, minute=0, second=0, microsecond=0) 458 hour=12, minute=0, second=0, microsecond=0)
442 analysis_original = self._createAnalysis(308, original_time) 459 analysis_original = self._createAnalysis(308, original_time)
443 460
444 # Create another analysis at the same time (also tomorrow). 461 # Create another analysis at the same time (also tomorrow).
445 self._createAnalysis(309, original_time) 462 self._createAnalysis(309, original_time)
446 463
447 self.assertEquals( 464 self.assertEquals(
448 len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 0) 465 len(triage_analysis._GetDuplicateAnalyses(analysis_original)), 0)
449 466
450 def testTriageDuplicateResults(self): 467 def testTriageDuplicateResultsFoundCorrectDuplicate(self):
451 # Two days ago, UTC Noon. 468 # Three days ago, UTC Noon.
452 original_time = (datetime.utcnow() - timedelta(days=2)).replace( 469 original_time = (datetime.utcnow() - timedelta(days=3)).replace(
453 hour=12, minute=0, second=0, microsecond=0) 470 hour=12, minute=0, second=0, microsecond=0)
454 analysis_original = self._createAnalysis(310, original_time) 471 analysis_original = self._createAnalysis(310, original_time)
455 472
456 # Create another analysis at the same time (also two days ago). 473 # Create another analysis a bit later (also three days ago).
457 self._createAnalysis(311, original_time) 474 self._createAnalysis(311, original_time + timedelta(minutes=1))
458 475
459 triage_analysis._TriageDuplicateResults(analysis_original, True) 476 triage_analysis._TriageAndCountDuplicateResults(analysis_original,
477 is_correct=True)
460 478
461 second_analysis = WfAnalysis.Get(self.master_name, self.builder_name, 311) 479 second_analysis = WfAnalysis.Get(self.master_name, self.builder_name, 311)
462 480
463 self.assertEquals(result_status.NOT_FOUND_CORRECT, 481 self.assertEquals(result_status.FOUND_CORRECT_DUPLICATE,
464 second_analysis.result_status) 482 second_analysis.result_status)
465 483
484 def testTriageDuplicateResultsFoundIncorrectDuplicate(self):
485 # Three days ago, UTC Noon.
486 original_time = (datetime.utcnow() - timedelta(days=3)).replace(
487 hour=12, minute=0, second=0, microsecond=0)
488 analysis_original = self._createAnalysis(312, original_time)
489
490 # Create another analysis a bit later (also three days ago).
491 self._createAnalysis(313, original_time + timedelta(minutes=1))
492
493 triage_analysis._TriageAndCountDuplicateResults(analysis_original,
494 is_correct=False)
495
496 second_analysis = WfAnalysis.Get(self.master_name, self.builder_name, 313)
497
498 self.assertEquals(result_status.FOUND_INCORRECT_DUPLICATE,
499 second_analysis.result_status)
OLDNEW
« no previous file with comments | « appengine/findit/handlers/build_failure.py ('k') | appengine/findit/handlers/triage_analysis.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698