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

Side by Side Diff: appengine/findit/test/findit_api_test.py

Issue 2425853005: [Findit] Modify Findit API to return more information to Sheriff-O-Matic. (Closed)
Patch Set: rebase Created 4 years, 1 month 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
« no previous file with comments | « appengine/findit/model/wf_suspected_cl.py ('k') | appengine/findit/waterfall/build_util.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 import json 5 import json
6 import mock 6 import mock
7 import pickle 7 import pickle
8 import re 8 import re
9 9
10 import endpoints
11 from google.appengine.api import taskqueue 10 from google.appengine.api import taskqueue
12 import webtest 11 import webtest
13 12
14 from testing_utils import testing 13 from testing_utils import testing
15 14
16 from common.waterfall import failure_type 15 from common.waterfall import failure_type
17 import findit_api 16 import findit_api
17 from model import analysis_approach_type
18 from model import analysis_status 18 from model import analysis_status
19 from model.flake.flake_analysis_request import FlakeAnalysisRequest
20 from model.wf_analysis import WfAnalysis 19 from model.wf_analysis import WfAnalysis
20 from model.wf_suspected_cl import WfSuspectedCL
21 from model.wf_swarming_task import WfSwarmingTask 21 from model.wf_swarming_task import WfSwarmingTask
22 from model.wf_try_job import WfTryJob 22 from model.wf_try_job import WfTryJob
23 from waterfall import build_util
24 from waterfall import suspected_cl_util
23 from waterfall import waterfall_config 25 from waterfall import waterfall_config
24 26
25 27
26 class FinditApiTest(testing.EndpointsTestCase): 28 class FinditApiTest(testing.EndpointsTestCase):
27 api_service_cls = findit_api.FindItApi 29 api_service_cls = findit_api.FindItApi
28 30
29 def setUp(self): 31 def setUp(self):
30 super(FinditApiTest, self).setUp() 32 super(FinditApiTest, self).setUp()
31 self.taskqueue_requests = [] 33 self.taskqueue_requests = []
32 def Mocked_taskqueue_add(**kwargs): 34 def Mocked_taskqueue_add(**kwargs):
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 'builder_name': builder_name, 215 'builder_name': builder_name,
214 'build_number': build_number, 216 'build_number': build_number,
215 'step_name': 'a', 217 'step_name': 'a',
216 'is_sub_test': False, 218 'is_sub_test': False,
217 'first_known_failed_build_number': 23, 219 'first_known_failed_build_number': 23,
218 'suspected_cls': [ 220 'suspected_cls': [
219 { 221 {
220 'repo_name': 'chromium', 222 'repo_name': 'chromium',
221 'revision': 'git_hash', 223 'revision': 'git_hash',
222 'commit_position': 123, 224 'commit_position': 123,
225 'analysis_approach': 'HEURISTIC'
223 } 226 }
224 ], 227 ],
225 'analysis_approach': 'HEURISTIC', 228 'analysis_approach': 'HEURISTIC',
229 'try_job_status': 'FINISHED',
230 'is_flaky_test': False
226 }, 231 },
227 ] 232 ]
228 233
229 analysis = WfAnalysis.Create(master_name, builder_name, build_number) 234 analysis = WfAnalysis.Create(master_name, builder_name, build_number)
230 analysis.status = analysis_status.RUNNING 235 analysis.status = analysis_status.RUNNING
231 analysis.result = analysis_result 236 analysis.result = analysis_result
232 analysis.put() 237 analysis.put()
233 238
234 response = self.call_api('AnalyzeBuildFailures', body=builds) 239 response = self.call_api('AnalyzeBuildFailures', body=builds)
235 self.assertEqual(200, response.status_int) 240 self.assertEqual(200, response.status_int)
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 'builder_name': builder_name, 337 'builder_name': builder_name,
333 'build_number': build_number, 338 'build_number': build_number,
334 'step_name': 'test', 339 'step_name': 'test',
335 'is_sub_test': False, 340 'is_sub_test': False,
336 'first_known_failed_build_number': 3, 341 'first_known_failed_build_number': 3,
337 'suspected_cls': [ 342 'suspected_cls': [
338 { 343 {
339 'repo_name': 'chromium', 344 'repo_name': 'chromium',
340 'revision': 'git_hash1', 345 'revision': 'git_hash1',
341 'commit_position': 234, 346 'commit_position': 234,
347 'analysis_approach': 'HEURISTIC'
342 }, 348 },
343 { 349 {
344 'repo_name': 'chromium', 350 'repo_name': 'chromium',
345 'revision': 'git_hash2', 351 'revision': 'git_hash2',
346 'commit_position': 288, 352 'commit_position': 288,
353 'analysis_approach': 'HEURISTIC'
347 } 354 }
348 ], 355 ],
349 'analysis_approach': 'HEURISTIC', 356 'analysis_approach': 'HEURISTIC',
357 'is_flaky_test': False,
358 'try_job_status': 'FINISHED'
350 } 359 }
351 ] 360 ]
352 361
353 self._MockMasterIsSupported(supported=True) 362 self._MockMasterIsSupported(supported=True)
354 363
355 response = self.call_api('AnalyzeBuildFailures', body=builds) 364 response = self.call_api('AnalyzeBuildFailures', body=builds)
356 self.assertEqual(200, response.status_int) 365 self.assertEqual(200, response.status_int)
357 self.assertEqual(expected_results, response.json_body.get('results')) 366 self.assertEqual(expected_results, response.json_body.get('results'))
358 367
359 def testTryJobResultReturnedForCompileFailure(self): 368 def testTryJobResultReturnedForCompileFailure(self):
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 'builder_name': builder_name, 432 'builder_name': builder_name,
424 'build_number': build_number, 433 'build_number': build_number,
425 'step_name': 'compile', 434 'step_name': 'compile',
426 'is_sub_test': False, 435 'is_sub_test': False,
427 'first_known_failed_build_number': 3, 436 'first_known_failed_build_number': 3,
428 'suspected_cls': [ 437 'suspected_cls': [
429 { 438 {
430 'repo_name': 'chromium', 439 'repo_name': 'chromium',
431 'revision': 'r3', 440 'revision': 'r3',
432 'commit_position': 3, 441 'commit_position': 3,
442 'analysis_approach': 'TRY_JOB'
433 }, 443 },
434 ], 444 ],
435 'analysis_approach': 'TRY_JOB', 445 'analysis_approach': 'TRY_JOB',
446 'is_flaky_test': False,
447 'try_job_status': 'FINISHED'
436 } 448 }
437 ] 449 ]
438 450
439 self._MockMasterIsSupported(supported=True) 451 self._MockMasterIsSupported(supported=True)
440 452
441 response = self.call_api('AnalyzeBuildFailures', body=builds) 453 response = self.call_api('AnalyzeBuildFailures', body=builds)
442 self.assertEqual(200, response.status_int) 454 self.assertEqual(200, response.status_int)
443 self.assertEqual(expected_results, response.json_body.get('results')) 455 self.assertEqual(expected_results, response.json_body.get('results'))
444 456
445 def testTestLevelResultIsReturned(self): 457 def testTryJobIsRunning(self):
446 master_name = 'm' 458 master_name = 'm'
447 builder_name = 'b' 459 builder_name = 'b'
448 build_number = 5 460 build_number = 5
461
462 master_url = 'https://build.chromium.org/p/%s' % master_name
463 builds = {
464 'builds': [
465 {
466 'master_url': master_url,
467 'builder_name': builder_name,
468 'build_number': build_number
469 }
470 ]
471 }
472
473 try_job = WfTryJob.Create(master_name, builder_name, 3)
474 try_job.status = analysis_status.RUNNING
475 try_job.put()
476
477 analysis = WfAnalysis.Create(master_name, builder_name, build_number)
478 analysis.status = analysis_status.COMPLETED
479 analysis.build_failure_type = failure_type.COMPILE
480 analysis.failure_result_map = {
481 'compile': '/'.join([master_name, builder_name, '3']),
482 }
483 analysis.result = {
484 'failures': [
485 {
486 'step_name': 'compile',
487 'first_failure': 3,
488 'last_pass': 1,
489 'suspected_cls': [
490 {
491 'build_number': 3,
492 'repo_name': 'chromium',
493 'revision': 'git_hash2',
494 'commit_position': 288,
495 'score': 1,
496 'hints': {
497 'modify d/e/f.cc': 1,
498 }
499 }
500 ]
501 }
502 ]
503 }
504 analysis.put()
505
506 expected_results = [
507 {
508 'master_url': master_url,
509 'builder_name': builder_name,
510 'build_number': build_number,
511 'step_name': 'compile',
512 'is_sub_test': False,
513 'first_known_failed_build_number': 3,
514 'suspected_cls': [
515 {
516 'repo_name': 'chromium',
517 'revision': 'git_hash2',
518 'commit_position': 288,
519 'analysis_approach': 'HEURISTIC'
520 },
521 ],
522 'analysis_approach': 'HEURISTIC',
523 'is_flaky_test': False,
524 'try_job_status': 'RUNNING'
525 }
526 ]
527
528 self._MockMasterIsSupported(supported=True)
529
530 response = self.call_api('AnalyzeBuildFailures', body=builds)
531 self.assertEqual(200, response.status_int)
532 self.assertEqual(expected_results, response.json_body.get('results'))
533
534 def testTestIsFlaky(self):
535 master_name = 'm'
536 builder_name = 'b'
537 build_number = 5
538
539 master_url = 'https://build.chromium.org/p/%s' % master_name
540 builds = {
541 'builds': [
542 {
543 'master_url': master_url,
544 'builder_name': builder_name,
545 'build_number': build_number
546 }
547 ]
548 }
549
550 task = WfSwarmingTask.Create(master_name, builder_name, 3, 'b on platform')
551 task.tests_statuses = {
552 'Unittest3.Subtest1': {
553 'total_run': 4,
554 'SUCCESS': 2,
555 'FAILURE': 2
556 }
557 }
558 task.put()
559
560 analysis = WfAnalysis.Create(master_name, builder_name, build_number)
561 analysis.status = analysis_status.COMPLETED
562 analysis.failure_result_map = {
563 'b on platform': {
564 'Unittest3.Subtest1': '/'.join([master_name, builder_name, '3']),
565 },
566 }
567 analysis.result = {
568 'failures': [
569 {
570 'step_name': 'b on platform',
571 'first_failure': 3,
572 'last_pass': 2,
573 'suspected_cls': [],
574 'tests': [
575 {
576 'test_name': 'Unittest3.Subtest1',
577 'first_failure': 3,
578 'last_pass': 2,
579 'suspected_cls': []
580 }
581 ]
582 }
583 ]
584 }
585 analysis.put()
586
587 expected_results = [
588 {
589 'master_url': master_url,
590 'builder_name': builder_name,
591 'build_number': build_number,
592 'step_name': 'b on platform',
593 'is_sub_test': True,
594 'test_name': 'Unittest3.Subtest1',
595 'first_known_failed_build_number': 3,
596 'analysis_approach': 'HEURISTIC',
597 'is_flaky_test': True,
598 'try_job_status': 'FINISHED'
599 }
600 ]
601
602 self._MockMasterIsSupported(supported=True)
603
604 response = self.call_api('AnalyzeBuildFailures', body=builds)
605 self.assertEqual(200, response.status_int)
606 self.assertEqual(expected_results, response.json_body.get('results'))
607
608 @mock.patch.object(suspected_cl_util, 'GetSuspectedCLConfidenceScore')
609 def testTestLevelResultIsReturned(self, mock_fn):
610 master_name = 'm'
611 builder_name = 'b'
612 build_number = 5
449 613
450 master_url = 'https://build.chromium.org/p/%s' % master_name 614 master_url = 'https://build.chromium.org/p/%s' % master_name
451 builds = { 615 builds = {
452 'builds': [ 616 'builds': [
453 { 617 {
454 'master_url': master_url, 618 'master_url': master_url,
455 'builder_name': builder_name, 619 'builder_name': builder_name,
456 'build_number': build_number 620 'build_number': build_number
457 } 621 }
458 ] 622 ]
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 'first_failure': 4, 751 'first_failure': 4,
588 'last_pass': 2, 752 'last_pass': 2,
589 'suspected_cls': [] 753 'suspected_cls': []
590 } 754 }
591 ] 755 ]
592 } 756 }
593 ] 757 ]
594 } 758 }
595 analysis.put() 759 analysis.put()
596 760
761 suspected_cl_42 = WfSuspectedCL.Create('chromium', 'r4_2', 42)
762 suspected_cl_42.builds = {
763 build_util.CreateBuildId(master_name, builder_name, 4): {
764 'approaches': [analysis_approach_type.TRY_JOB]
765 }
766 }
767 suspected_cl_42.put()
768
769 suspected_cl_21 = WfSuspectedCL.Create('chromium', 'r2_1', None)
770 suspected_cl_21.builds = {
771 build_util.CreateBuildId(master_name, builder_name, build_number): {
772 'approaches': [analysis_approach_type.HEURISTIC],
773 'top_score': 5
774 }
775 }
776 suspected_cl_21.put()
777
778 def confidence_side_effect(_, build_info):
779 if build_info.get('top_score'):
780 return 90
781 return 98
782
783 mock_fn.side_effect = confidence_side_effect
784
597 expected_results = [ 785 expected_results = [
598 { 786 {
599 'master_url': master_url, 787 'master_url': master_url,
600 'builder_name': builder_name, 788 'builder_name': builder_name,
601 'build_number': build_number, 789 'build_number': build_number,
602 'step_name': 'a', 790 'step_name': 'a',
603 'is_sub_test': False, 791 'is_sub_test': False,
604 'first_known_failed_build_number': 4, 792 'first_known_failed_build_number': 4,
605 'suspected_cls': [ 793 'suspected_cls': [
606 { 794 {
607 'repo_name': 'chromium', 795 'repo_name': 'chromium',
608 'revision': 'r4_2', 796 'revision': 'r4_2',
609 'commit_position': 42, 797 'commit_position': 42,
798 'confidence': 98,
799 'analysis_approach': 'TRY_JOB'
610 } 800 }
611 ], 801 ],
612 'analysis_approach': 'TRY_JOB', 802 'analysis_approach': 'TRY_JOB',
803 'is_flaky_test': False,
804 'try_job_status': 'FINISHED'
613 }, 805 },
614 { 806 {
615 'master_url': master_url, 807 'master_url': master_url,
616 'builder_name': builder_name, 808 'builder_name': builder_name,
617 'build_number': build_number, 809 'build_number': build_number,
618 'step_name': 'b on platform', 810 'step_name': 'b on platform',
619 'is_sub_test': True, 811 'is_sub_test': True,
620 'test_name': 'Unittest1.Subtest1', 812 'test_name': 'Unittest1.Subtest1',
621 'first_known_failed_build_number': 3, 813 'first_known_failed_build_number': 3,
622 'suspected_cls': [ 814 'suspected_cls': [
623 { 815 {
624 'repo_name': 'chromium', 816 'repo_name': 'chromium',
625 'revision': 'r2_1', 817 'revision': 'r2_1',
818 'confidence': 90,
819 'analysis_approach': 'HEURISTIC'
626 } 820 }
627 ], 821 ],
628 'analysis_approach': 'HEURISTIC', 822 'analysis_approach': 'HEURISTIC',
823 'is_flaky_test': False,
824 'try_job_status': 'FINISHED'
629 }, 825 },
630 { 826 {
631 'master_url': master_url, 827 'master_url': master_url,
632 'builder_name': builder_name, 828 'builder_name': builder_name,
633 'build_number': build_number, 829 'build_number': build_number,
634 'step_name': 'b on platform', 830 'step_name': 'b on platform',
635 'is_sub_test': True, 831 'is_sub_test': True,
636 'test_name': 'Unittest2.Subtest1', 832 'test_name': 'Unittest2.Subtest1',
637 'first_known_failed_build_number': 4, 833 'first_known_failed_build_number': 4,
638 'suspected_cls': [ 834 'suspected_cls': [
639 { 835 {
640 'repo_name': 'chromium', 836 'repo_name': 'chromium',
641 'revision': 'r2_1', 837 'revision': 'r2_1',
838 'confidence': 90,
839 'analysis_approach': 'HEURISTIC'
642 } 840 }
643 ], 841 ],
644 'analysis_approach': 'HEURISTIC', 842 'analysis_approach': 'HEURISTIC',
843 'is_flaky_test': False,
844 'try_job_status': 'FINISHED'
645 }, 845 },
646 { 846 {
647 'master_url': master_url, 847 'master_url': master_url,
648 'builder_name': builder_name, 848 'builder_name': builder_name,
649 'build_number': build_number, 849 'build_number': build_number,
650 'step_name': 'b on platform', 850 'step_name': 'b on platform',
651 'is_sub_test': True, 851 'is_sub_test': True,
652 'test_name': 'Unittest3.Subtest1', 852 'test_name': 'Unittest3.Subtest1',
653 'first_known_failed_build_number': 4, 853 'first_known_failed_build_number': 4,
654 'suspected_cls': [ 854 'suspected_cls': [
655 { 855 {
656 'repo_name': 'chromium', 856 'repo_name': 'chromium',
657 'revision': 'r4_10', 857 'revision': 'r4_10',
658 'commit_position': 410, 858 'commit_position': 410,
859 'analysis_approach': 'TRY_JOB'
659 } 860 }
660 ], 861 ],
661 'analysis_approach': 'TRY_JOB', 862 'analysis_approach': 'TRY_JOB',
863 'is_flaky_test': False,
864 'try_job_status': 'FINISHED'
662 } 865 }
663 ] 866 ]
664 867
665 self._MockMasterIsSupported(supported=True) 868 self._MockMasterIsSupported(supported=True)
666 869
667 response = self.call_api('AnalyzeBuildFailures', body=builds) 870 response = self.call_api('AnalyzeBuildFailures', body=builds)
668 self.assertEqual(200, response.status_int) 871 self.assertEqual(200, response.status_int)
669 self.assertEqual(expected_results, response.json_body.get('results')) 872 self.assertEqual(expected_results, response.json_body.get('results'))
670 873
671 def testAnalysisRequestQueuedAsExpected(self): 874 def testAnalysisRequestQueuedAsExpected(self):
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 self.assertFalse(request.is_step) 987 self.assertFalse(request.is_step)
785 self.assertEqual(123, request.bug_id) 988 self.assertEqual(123, request.bug_id)
786 self.assertEqual(1, len(request.build_steps)) 989 self.assertEqual(1, len(request.build_steps))
787 self.assertEqual('m', request.build_steps[0].master_name) 990 self.assertEqual('m', request.build_steps[0].master_name)
788 self.assertEqual('b', request.build_steps[0].builder_name) 991 self.assertEqual('b', request.build_steps[0].builder_name)
789 self.assertEqual(456, request.build_steps[0].build_number) 992 self.assertEqual(456, request.build_steps[0].build_number)
790 self.assertEqual('name (with patch) on Windows-7-SP1', 993 self.assertEqual('name (with patch) on Windows-7-SP1',
791 request.build_steps[0].step_name) 994 request.build_steps[0].step_name)
792 self.assertEqual('test@chromium.org', user_email) 995 self.assertEqual('test@chromium.org', user_email)
793 self.assertTrue(is_admin) 996 self.assertTrue(is_admin)
OLDNEW
« no previous file with comments | « appengine/findit/model/wf_suspected_cl.py ('k') | appengine/findit/waterfall/build_util.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698