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

Side by Side Diff: scripts/slave/recipe_modules/auto_bisect/bisector_test.py

Issue 2247373002: Refactor stages 1, 2 and test_api overhaul. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/build.git@master
Patch Set: Addressing all early feedback. Created 4 years, 3 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
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 import copy
7 import os
8 import sys
9 import unittest
10
11 root_dir = os.path.abspath(os.path.join(
12 os.path.dirname(__file__), os.path.pardir,
13 os.path.pardir, os.path.pardir, os.path.pardir))
14 sys.path.insert(0, os.path.join(root_dir, 'third_party', 'mock-1.0.1'))
15 sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.path.pardir))
16
17 import mock
18
19 import auto_bisect.bisector
20 import auto_bisect.depot_config
21
22
23 class MockRevisionClass(object): # pragma: no cover
24
25 def __init__(
26 self, bisector, commit_hash,
27 depot_name='chromium', base_revision=None):
28 self.bisector = bisector
29 self.commit_hash = commit_hash
30 self.depot_name = depot_name
31 self.base_revision = base_revision
32 self.previous_revision = None
33 self.next_revision = None
34 self.values = []
35 self.overall_return_code = None
36 self.deps = {}
37 self.status = ''
38
39 def read_deps(self, tester_name):
40 pass
41
42 def retest(self):
43 self.bisector.last_tested_revision = self
44 self.values.append(3)
45
46
47 @mock.patch.object(auto_bisect.bisector.Bisector, 'ensure_sync_master_branch',
48 mock.MagicMock())
49 class BisectorTest(unittest.TestCase): # pragma: no cover
50
51 def setUp(self):
52 self.bisect_config = {
53 'test_type': 'perf',
54 'command': ('tools/perf/run_benchmark -v '
55 '--browser=release page_cycler.intl_ar_fa_he'),
56 'good_revision': 'abcd5678abcd5678abcd5678abcd5678abcd5678',
57 'bad_revision': 'def05678def05678def05678def05678def05678',
58 'metric': 'warm_times/page_load_time',
59 'repeat_count': '2',
60 'max_time_minutes': '5',
61 'bug_id': '425582',
62 'gs_bucket': 'chrome-perf',
63 'builder_host': 'master4.golo.chromium.org',
64 'builder_port': '8341',
65 'dummy_builds': True,
66 }
67 self.dummy_api = mock.MagicMock()
68 self.dummy_api.internal_bisect = False
69
70 def test_improvement_direction_default(self):
71 # By default, no improvement direction should be set
72 bisector = auto_bisect.bisector.Bisector(self.dummy_api, self.bisect_config,
73 MockRevisionClass)
74 self.assertIsNone(bisector.improvement_direction)
75
76 def test_improvement_direction_greater_is_better_fail(self):
77 # Improvement up, bad > good: should fail
78 self.bisect_config['improvement_direction'] = 1
79 bisector = auto_bisect.bisector.Bisector(self.dummy_api, self.bisect_config,
80 MockRevisionClass)
81 bisector.good_rev.mean_value = 10
82 bisector.bad_rev.mean_value = 100
83 self.assertFalse(bisector.check_improvement_direction())
84 self.assertIn('direction of improvement', ''.join(bisector.warnings))
85
86 def test_improvement_direction_greater_is_better_pass(self):
87 # Improvement up, bad < good: should not fail
88 self.bisect_config['improvement_direction'] = 1
89 bisector = auto_bisect.bisector.Bisector(self.dummy_api, self.bisect_config,
90 MockRevisionClass)
91 bisector.good_rev.mean_value = 100
92 bisector.bad_rev.mean_value = 10
93 self.assertTrue(bisector.check_improvement_direction())
94 self.assertNotIn('direction of improvement', ''.join(bisector.warnings))
95
96 def test_improvement_direction_lower_is_better_fail(self):
97 # Improvement down, bad < good: should fail
98 self.bisect_config['improvement_direction'] = -1
99 bisector = auto_bisect.bisector.Bisector(self.dummy_api, self.bisect_config,
100 MockRevisionClass)
101 bisector.good_rev.mean_value = 100
102 bisector.bad_rev.mean_value = 10
103 self.assertFalse(bisector.check_improvement_direction())
104 self.assertIn('direction of improvement', ''.join(bisector.warnings))
105
106 def test_improvement_direction_lower_is_better_pass(self):
107 # Improvement down, bad > good: should not fail
108 self.bisect_config['improvement_direction'] = -1
109 bisector = auto_bisect.bisector.Bisector(self.dummy_api, self.bisect_config,
110 MockRevisionClass)
111 bisector.good_rev.mean_value = 10
112 bisector.bad_rev.mean_value = 100
113 self.assertTrue(bisector.check_improvement_direction())
114 self.assertNotIn('direction of improvement', ''.join(bisector.warnings))
115
116 def test_improvement_direction_return_code(self):
117 # The improvement direction check doesn't apply for return code bisects.
118 bisect_config = copy.deepcopy(self.bisect_config)
119 bisect_config['test_type'] = 'return_code'
120 bisector = auto_bisect.bisector.Bisector(self.dummy_api, bisect_config,
121 MockRevisionClass)
122 bisector.good_rev.mean_value = 1
123 bisector.bad_rev.mean_value = 0
124 self.assertTrue(bisector.is_return_code_mode())
125 self.assertTrue(bisector.check_improvement_direction())
126
127 @mock.patch.object(auto_bisect.bisector.Bisector, 'significantly_different',
128 mock.MagicMock(return_value=True))
129 def test_check_initial_confidence_pass(self):
130 # patch bisector.significantly_different with true
131 # assert both revisions have > 5 samples
132 bisector = auto_bisect.bisector.Bisector(self.dummy_api, self.bisect_config,
133 MockRevisionClass)
134 bisector.good_rev.values = [3, 3, 3, 3, 3, 3]
135 bisector.bad_rev.values = [3, 3, 3, 3]
136 self.assertTrue(bisector.check_initial_confidence())
137 self.assertTrue(len(bisector.bad_rev.values) >= 5)
138
139 @mock.patch.object(auto_bisect.bisector.Bisector, 'significantly_different',
140 mock.MagicMock(return_value=False))
141 def test_check_initial_confidence_non_diverging(self):
142 bisector = auto_bisect.bisector.Bisector(self.dummy_api, self.bisect_config,
143 MockRevisionClass)
144 bisector.good_rev.values = [3, 3, 3, 3, 3, 3]
145 bisector.bad_rev.values = [3, 3, 3, 3]
146 self.assertFalse(bisector.check_initial_confidence())
147 self.assertTrue(len(bisector.bad_rev.values) >=
148 auto_bisect.bisector.MAX_REQUIRED_SAMPLES or
149 len(bisector.good_rev.values) >=
150 auto_bisect.bisector.MAX_REQUIRED_SAMPLES)
151
152 def test_check_initial_confidence_return_code_pass(self):
153 return_code_config = self.bisect_config
154 return_code_config['test_type'] = 'return_code'
155 bisector = auto_bisect.bisector.Bisector(self.dummy_api, return_code_config,
156 MockRevisionClass)
157 bisector.good_rev.overall_return_code = 0
158 bisector.bad_rev.overall_return_code = 1
159 self.assertTrue(bisector.check_initial_confidence())
160
161 def test_check_initial_confidence_return_code_fail(self):
162 return_code_config = self.bisect_config
163 return_code_config['test_type'] = 'return_code'
164 bisector = auto_bisect.bisector.Bisector(self.dummy_api, return_code_config,
165 MockRevisionClass)
166 bisector.good_rev.overall_return_code = 0
167 bisector.bad_rev.overall_return_code = 0
168 self.assertFalse(bisector.check_initial_confidence())
169
170 bisector.good_rev.overall_return_code = 1
171 bisector.bad_rev.overall_return_code = 1
172 self.assertFalse(bisector.check_initial_confidence())
173
174 def test_commit_log_from_gitiles(self):
175 self.dummy_api.internal_bisect = True
176 commits = [
177 {'commit': 'def05678def05678def05678def05678def05678'}, # bad revision
178 {'commit': 'bbbbb'},
179 {'commit': 'ccccc'},
180 ]
181 self.dummy_api.m.gitiles.log = mock.MagicMock(return_value=(commits, None))
182 auto_bisect.depot_config.DEPOT_DEPS_NAME['android-chrome'] = {
183 'src' : 'src/internal',
184 'recurse' : True,
185 'depends' : None,
186 'from' : [],
187 'deps_file': '.DEPS.git',
188 'url': 'https://dummy-internal-url'
189 }
190 bisector = auto_bisect.bisector.Bisector(
191 self.dummy_api, self.bisect_config, MockRevisionClass)
192 for r in bisector.revisions:
193 self.assertIn(r.commit_hash,
194 [bisector.good_rev.commit_hash,
195 'bbbbb',
196 'ccccc',
197 bisector.bad_rev.commit_hash])
198
199 if __name__ == '__main__':
200 unittest.main() # pragma: no cover
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698