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

Side by Side Diff: appengine/chromium_try_flakes/handlers/test/flake_issues_test.py

Issue 1873243002: Only report Patch failure on infra error and refactor code (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « appengine/chromium_try_flakes/handlers/flake_issues.py ('k') | no next file » | 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 datetime 5 import datetime
6 import json 6 import json
7 import mock 7 import mock
8 import urllib2 8 import urllib2
9 9
10 from google.appengine.datastore import datastore_stub_util 10 from google.appengine.datastore import datastore_stub_util
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 73
74 # Ignore steps that are duplicating error in another step. 74 # Ignore steps that are duplicating error in another step.
75 {'results': [2], 'name': 'steps', 'text': ['bar10']}, 75 {'results': [2], 'name': 'steps', 'text': ['bar10']},
76 {'results': [2], 'name': '[swarming] foo7', 'text': ['bar11']}, 76 {'results': [2], 'name': '[swarming] foo7', 'text': ['bar11']},
77 {'results': [2], 'name': 'presubmit', 'text': ['bar12']}, 77 {'results': [2], 'name': 'presubmit', 'text': ['bar12']},
78 {'results': [2], 'name': 'recipe failure reason', 'text': ['bar12a']}, 78 {'results': [2], 'name': 'recipe failure reason', 'text': ['bar12a']},
79 {'results': [2], 'name': 'test results', 'text': ['bar12b']}, 79 {'results': [2], 'name': 'test results', 'text': ['bar12b']},
80 {'results': [2], 'name': 'Uncaught Exception', 'text': ['bar12c']}, 80 {'results': [2], 'name': 'Uncaught Exception', 'text': ['bar12c']},
81 {'results': [2], 'name': 'bot_update', 'text': ['bot_update PATCH FAILED']}, 81 {'results': [2], 'name': 'bot_update', 'text': ['bot_update PATCH FAILED']},
82 82
83 # Detect infra-failure for 'Patch failure', but igore normal error.
84 {'results': [4], 'name': 'Patch failure', 'text': ['Patch failure']},
85 {'results': [2], 'name': 'Patch failure', 'text': ['Patch failure']},
86
83 # Only count first step (with patch) and ignore summary step. 87 # Only count first step (with patch) and ignore summary step.
84 {'results': [2], 'name': 'foo8 xx (with patch)', 'text': ['bar13']}, 88 {'results': [2], 'name': 'foo8 xx (with patch)', 'text': ['bar13']},
85 {'results': [0], 'name': 'foo8 xx (without patch)', 'text': ['bar14']}, 89 {'results': [0], 'name': 'foo8 xx (without patch)', 'text': ['bar14']},
86 {'results': [2], 'name': 'foo8 xx (retry summary)', 'text': ['bar15']}, 90 {'results': [2], 'name': 'foo8 xx (retry summary)', 'text': ['bar15']},
87 ] 91 ]
88 }) 92 })
89 93
90 94
91 class MockComment(object): 95 class MockComment(object):
92 def __init__(self, created, author, comment=None): 96 def __init__(self, created, author, comment=None):
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 676
673 def test_get_flaky_run_reason(self): 677 def test_get_flaky_run_reason(self):
674 now = datetime.datetime.utcnow() 678 now = datetime.datetime.utcnow()
675 br_f, br_s = self._create_build_runs(now - datetime.timedelta(hours=1), now) 679 br_f, br_s = self._create_build_runs(now - datetime.timedelta(hours=1), now)
676 680
677 urlfetch_mock = mock.Mock(side_effect = [ 681 urlfetch_mock = mock.Mock(side_effect = [
678 # JSON results for the build. 682 # JSON results for the build.
679 mock.Mock(status_code=200, content=TEST_BUILDBOT_JSON_REPLY), 683 mock.Mock(status_code=200, content=TEST_BUILDBOT_JSON_REPLY),
680 # JSON results for step "foo1". 684 # JSON results for step "foo1".
681 mock.Mock(status_code=200, content=TEST_TEST_RESULTS_REPLY), 685 mock.Mock(status_code=200, content=TEST_TEST_RESULTS_REPLY),
686 # JSON results for step "Patch failure".
687 mock.Mock(status_code=404),
682 # For step "foo8 xx (with patch)", something failed while parsing JSON, 688 # For step "foo8 xx (with patch)", something failed while parsing JSON,
683 # step text ("bar13") should be reported as flake. 689 # step text ("bar13") should be reported as flake.
684 Exception(), 690 Exception(),
685 ]) 691 ])
686 692
687 # We also create one Flake to test that it is correctly updated. Other Flake 693 # We also create one Flake to test that it is correctly updated. Other Flake
688 # entities will be created automatically. 694 # entities will be created automatically.
689 Flake(id='foo2', name='foo2', occurrences=[], 695 Flake(id='foo2', name='foo2', occurrences=[],
690 last_time_seen=datetime.datetime.min).put() 696 last_time_seen=datetime.datetime.min).put()
691 697
(...skipping 16 matching lines...) Expand all
708 mock.call( 714 mock.call(
709 'http://build.chromium.org/p/test.master/json/builders/test-builder/' 715 'http://build.chromium.org/p/test.master/json/builders/test-builder/'
710 'builds/100'), 716 'builds/100'),
711 # Verify that we've used correct URLs to retrieve test-results GTest JSON. 717 # Verify that we've used correct URLs to retrieve test-results GTest JSON.
712 mock.call( 718 mock.call(
713 'http://test-results.appspot.com/testfile?builder=test-builder&' 719 'http://test-results.appspot.com/testfile?builder=test-builder&'
714 'name=full_results.json&master=test.master&testtype=foo1&' 720 'name=full_results.json&master=test.master&testtype=foo1&'
715 'buildnumber=100'), 721 'buildnumber=100'),
716 mock.call( 722 mock.call(
717 'http://test-results.appspot.com/testfile?builder=test-builder&' 723 'http://test-results.appspot.com/testfile?builder=test-builder&'
724 'name=full_results.json&master=test.master&testtype=Patch&'
725 'buildnumber=100'),
726 mock.call(
727 'http://test-results.appspot.com/testfile?builder=test-builder&'
718 'name=full_results.json&master=test.master&' 728 'name=full_results.json&master=test.master&'
719 'testtype=foo8%20%28with%20patch%29&buildnumber=100')]) 729 'testtype=foo8%20%28with%20patch%29&buildnumber=100')])
720 730
721 # Expected flakes to be found: list of (step_name, test_name). 731 # Expected flakes to be found: list of (step_name, test_name).
722 expected_flakes = [ 732 # We compare sets below, because order of entities returned by datastore
733 # doesn't have to be same as steps above.
734 expected_flakes = set([
723 ('foo1', 'test2.a'), 735 ('foo1', 'test2.a'),
724 ('foo1', 'test2.d'), 736 ('foo1', 'test2.d'),
725 ('foo2', 'foo2'), 737 ('foo2', 'foo2'),
726 ('foo8 xx (with patch)', 'foo8 (with patch)'), 738 ('foo8 xx (with patch)', 'foo8 (with patch)'),
727 ] 739 ('Patch failure', 'Patch'),
740 ])
728 741
729 flake_occurrences = flaky_run.flakes 742 flake_occurrences = flaky_run.flakes
730 self.assertEqual(len(flake_occurrences), len(expected_flakes)) 743 self.assertEqual(len(flake_occurrences), len(expected_flakes))
731 actual_flake_occurrences = [ 744 actual_flake_occurrences = set([
732 (fo.name, fo.failure) for fo in flake_occurrences] 745 (fo.name, fo.failure) for fo in flake_occurrences])
733 self.assertEqual(expected_flakes, actual_flake_occurrences) 746 self.assertEqual(expected_flakes, actual_flake_occurrences)
734 747
735 # We compare sets below, because order of flakes returned by datastore
736 # doesn't have to be same as steps above.
737 flakes = Flake.query().fetch() 748 flakes = Flake.query().fetch()
738 self.assertEqual(len(flakes), len(expected_flakes)) 749 self.assertEqual(len(flakes), len(expected_flakes))
739 expected_flake_names = set([ef[1] for ef in expected_flakes]) 750 expected_flake_names = set([ef[1] for ef in expected_flakes])
740 actual_flake_names = set([f.name for f in flakes]) 751 actual_flake_names = set([f.name for f in flakes])
741 self.assertEqual(expected_flake_names, actual_flake_names) 752 self.assertEqual(expected_flake_names, actual_flake_names)
742 753
743 for flake in flakes: 754 for flake in flakes:
744 self.assertEqual(flake.occurrences, [flaky_run.key]) 755 self.assertEqual(flake.occurrences, [flaky_run.key])
745 756
746 def test_flattens_tests_correctly(self): 757 def test_flattens_tests_correctly(self):
747 passed, failed, skipped = CreateFlakyRun._flatten_tests( 758 passed, failed, skipped = CreateFlakyRun._flatten_tests(
748 json.loads(TEST_TEST_RESULTS_REPLY)['tests'], '/') 759 json.loads(TEST_TEST_RESULTS_REPLY)['tests'], '/')
749 self.assertEqual(set(passed), set(['test1'])) 760 self.assertEqual(set(passed), set(['test1']))
750 self.assertEqual(set(failed), set(['test2/a', 'test2/d'])) 761 self.assertEqual(set(failed), set(['test2/a', 'test2/d']))
751 self.assertEqual(set(skipped), set(['test2/b'])) 762 self.assertEqual(set(skipped), set(['test2/b']))
OLDNEW
« no previous file with comments | « appengine/chromium_try_flakes/handlers/flake_issues.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698