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

Side by Side Diff: scripts/slave/recipe_modules/auto_bisect/test_api.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: Rebasing, addressing 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 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4 import math
5
6 from collections import defaultdict
7
8 from recipe_engine import recipe_test_api
9
10
11 class AutoBisectTestApi(recipe_test_api.RecipeTestApi):
12 def buildbot_job_status_mock(self, bb_data_list):
13 if bb_data_list:
14 return bb_data_list.pop()
15 return self.m.json.output_stream(
16 {'build': {
17 'result': 'SUCCESS',
18 'status': 'COMPLETED'}})
19
20 def compare_samples_data(self, data, rev_a, rev_b):
21 values_a = data[rev_a.commit_hash].get('parsed_values', [])[
22 :rev_a.test_run_count]
23 values_b = data[rev_b.commit_hash].get('parsed_values', [])[
24 :rev_b.test_run_count]
25 while len(values_a) < rev_a.test_run_count:
26 if values_a:
27 values_a.append(values_a[-1])
28 else:
29 values_a.append(0)
30
31 while len(values_b) < rev_b.test_run_count:
32 if values_b:
33 values_b.append(values_b[-1])
34 else:
35 values_b.append(0)
36
37 avg = lambda x: sum(x)/float((len(x) or 1))
38 mean_a = avg(values_a)
39 mean_b = avg(values_b)
40 var_a = map (lambda x: (x - mean_a) ** 2, values_a)
41 var_b = map (lambda x: (x - mean_b) ** 2, values_b)
42 std_dev_a = math.sqrt(avg(var_a))
43 std_dev_b = math.sqrt(avg(var_b))
44 result = 'needMoreData'
45 if len(values_a) >= 5 and len(values_b) >= 5:
46 if mean_a != mean_b:
47 result = True
48 # TODO(robertocn): Add a test that uses this clause.
49 if len(values_a) >= 18 and len(values_b) >= 18: # pragma: no cover
50 if mean_a == mean_b:
51 result = False
52 return self.m.json.output_stream(
53 {
54 'sample_a': {
55 'debug_values': values_a,
56 'mean': mean_a,
57 'std_dev': std_dev_a
58 },
59 'sample_b': {
60 'debug_values': values_b,
61 'mean': mean_b,
62 'std_dev': std_dev_b,
63 },
64 'result': result
65 })
66
67 @recipe_test_api.mod_test_data
68 def hash_cp_map(self, items):
69 result = {}
70 for item in items:
71 if 'hash' in item and 'commit_pos' in item:
72 result[item['commit_pos']] = self.m.json.output_stream(
73 {'git_sha': item['hash']})
74 return result
75
76 @recipe_test_api.mod_test_data
77 @staticmethod
78 def revision_data(items):
79 result = {}
80 for item in items:
81 if 'hash' in item:
82 result[item['hash']] = item
83 return result
84
85 @recipe_test_api.mod_test_data
86 def revision_list(self, items):
87 result = {}
88 for item in items:
89 if 'hash' in item:
90 depot = item.get('depot', 'chromium')
91 result.setdefault(depot, [])
92 result[depot].append([item['hash'], item.get('commit_pos')])
93 # Exclude the start of the revision range.
94 result['chromium'] = result['chromium'][1:]
95 for depot in result:
96 result[depot] = self.m.json.output_stream(result[depot])
97 return result
98
99 @recipe_test_api.mod_test_data
100 def deps_change(self, items):
101 # If the revision has the key DEPS_change, we mock the result of git show to
102 # appear as if DEPS was among the files changed by the CL.
103 result = {}
104 for item in items:
105 if 'hash' in item:
106 git_output = ''
107 if 'DEPS_change' in item:
108 git_output = 'DEPS'
109 result[item['hash']] = self.m.raw_io.stream_output(git_output)
110 return result
111
112 @recipe_test_api.mod_test_data
113 def diff_patch(self):
114 return self.m.raw_io.stream_output("""
115 diff --git a/DEPS b/DEPS
116 index 029be3b..2b3ea0a 100644
117 --- a/DEPS
118 +++ b/DEPS
119 @@ -13,7 +13,7 @@ deps = {
120 '@98fc59a5896f4ea990a4d527548204fed8f06c64',
121 'build/third_party/infra_libs':
122 'https://chromium.googlesource.com/infra/infra/packages/infra_libs.git'
123 - '@a13e6745a4edd01fee683e4157ea0195872e64eb',
124 + '@15ea0920b5f83d0aff4bd042e95bc388d069d51c',
125 'build/third_party/lighttpd':
126 'https://chromium.googlesource.com/chromium/deps/lighttpd.git'
127 '@9dfa55d15937a688a92cbf2b7a8621b0927d06eb',
128 """)
129
130 @recipe_test_api.mod_test_data
131 def deps(self, items):
132 result = {}
133 for item in items:
134 if 'hash' in item:
135 deps_content = ''
136 if 'DEPS' in item:
137 deps_content = item['DEPS']
138 result[item['hash']] = self.m.raw_io.stream_output(deps_content)
139 return result
140
141 @recipe_test_api.placeholder_step_data
142 @staticmethod
143 def exists_result(exists=True):
144 if exists:
145 return 'GS location exists', 0, ''
146 return 'GS location does not exist', 1, ''
147
148 @recipe_test_api.mod_test_data
149 def gsutil_exists(self, items):
150 result = {}
151 for item in items:
152 if 'hash' in item and 'gsutil_exists' in item:
153 result[item['hash']] = [self.exists_result(i)
154 for i in item['gsutil_exists']]
155 return result
156
157 @recipe_test_api.mod_test_data
158 def run_results(self, items):
159 def single_result(v):
160 return self.m.raw_io.stream_output(
161 data=v.get('stdout', 'text from actual benchmark, (ignored)'),
162 retcode=v.get('retcode', 0)) + self.m.raw_io.output(
163 data=v.get('stdout', 'text from actual benchmark, (ignored)'))
164
165 result = {'default': self.m.raw_io.stream_output('mock output', retcode=0)}
166 for item in items:
167 if 'hash' in item and 'test_results' in item:
168 result[item['hash']] = [single_result(v) for v in item['test_results']]
169 return result
170
171 @recipe_test_api.mod_test_data
172 def cl_info(self, items):
173 result = {}
174 for item in items:
175 if 'hash' in item:
176 if 'cl_info' in item:
177 info = item['cl_info']
178 else:
179 info = {}
180 result[item['hash']] = self.m.json.output_stream(info)
181 return result
182
183 @recipe_test_api.mod_test_data
184 def build_status(self, items):
185 result = {}
186 for item in items:
187 if 'hash' in item and 'build_status' in item:
188 result[item['hash']] = []
189 for entry in item['build_status']:
190 result[item['hash']].append(self.m.json.output_stream(entry))
191 return result
192
193 def __call__(self, config_items):
194 return (
195 self.revision_data(config_items)
196 + self.hash_cp_map(config_items)
197 + self.revision_list(config_items)
198 + self.run_results(config_items)
199 + self.deps_change(config_items)
200 + self.deps(config_items)
201 + self.cl_info (config_items)
202 + self.diff_patch()
203 + self.gsutil_exists(config_items)
204 + self.build_status(config_items)
205 )
206
207 # """Takes massive dictionary to populate test_data for all steps."""
208 # get commit hash
209 # get test results(gsutil) ?
210 # fetch deps
211 # generating patch
212 # reading culprit information
213 # expanding revision range
214 # hashing modified deps
215 # fetch builder state
216 # fetch build details
217 # (check image) gsutil
218 #
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698