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: appengine/findit/waterfall/buildbot.py

Issue 1149743002: [Findit] Use step level analysis to exclude flaky test failures. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Use cStringIO to pull the reliable test failures. Created 5 years, 7 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 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 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 contextlib
5 from datetime import datetime 6 from datetime import datetime
7 import gzip
6 import json 8 import json
7 import re 9 import re
8 import urllib 10 import urllib
9 11
12 import cloudstorage as gcs
13
10 from waterfall.build_info import BuildInfo 14 from waterfall.build_info import BuildInfo
11 15
12 _MASTER_URL_PATTERN = re.compile(r'^https?://build\.chromium\.org/p/([^/]+)' 16 _MASTER_URL_PATTERN = re.compile(r'^https?://build\.chromium\.org/p/([^/]+)'
13 '(/.*)?$') 17 '(/.*)?$')
14 18
15 _BUILD_URL_PATTERN = re.compile(r'^https?://build\.chromium\.org/p/([^/]+)/' 19 _BUILD_URL_PATTERN = re.compile(r'^https?://build\.chromium\.org/p/([^/]+)/'
16 'builders/([^/]+)/builds/([\d]+)(/.*)?$') 20 'builders/([^/]+)/builds/([\d]+)(/.*)?$')
17 21
18 _STEP_URL_PATTERN = re.compile(r'^https?://build\.chromium\.org/p/([^/]+)/' 22 _STEP_URL_PATTERN = re.compile(r'^https?://build\.chromium\.org/p/([^/]+)/'
19 'builders/([^/]+)/builds/([\d]+)/steps/' 23 'builders/([^/]+)/builds/([\d]+)/steps/'
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 94
91 95
92 def CreateStdioLogUrl(master_name, builder_name, build_number, step_name): 96 def CreateStdioLogUrl(master_name, builder_name, build_number, step_name):
93 builder_name = urllib.quote(builder_name) 97 builder_name = urllib.quote(builder_name)
94 step_name = urllib.quote(step_name) 98 step_name = urllib.quote(step_name)
95 return ('https://build.chromium.org/p/%s/builders/%s/builds/%s/' 99 return ('https://build.chromium.org/p/%s/builders/%s/builds/%s/'
96 'steps/%s/logs/stdio/text') % ( 100 'steps/%s/logs/stdio/text') % (
97 master_name, builder_name, build_number, step_name) 101 master_name, builder_name, build_number, step_name)
98 102
99 103
100 def GetBuildDataFromBuildMaster(master_name, 104 def CreateGtestResultPath(master_name, builder_name, build_number, step_name):
105 return ('/chrome-gtest-results/buildbot/%s/%s/%s/%s.json.gz') % (
106 master_name, builder_name, build_number, step_name)
107
108
109 def GetBuildDataFromBuildMaster(master_name,
101 builder_name, build_number, http_client): 110 builder_name, build_number, http_client):
102 """Returns the json-format data of the build from buildbot json API.""" 111 """Returns the json-format data of the build from buildbot json API."""
103 status_code, data = http_client.Get( 112 status_code, data = http_client.Get(
104 CreateBuildUrl(master_name, builder_name, build_number, json_api=True)) 113 CreateBuildUrl(master_name, builder_name, build_number, json_api=True))
105 if status_code != 200: 114 if status_code != 200:
106 return None 115 return None
107 else: 116 else:
108 return data 117 return data
109 118
110 119
111 def GetBuildDataFromArchive(master_name, 120 def GetBuildDataFromArchive(master_name,
112 builder_name, build_number, http_client): 121 builder_name, build_number, http_client):
113 """Returns the json-format data of the build from build archive.""" 122 """Returns the json-format data of the build from build archive."""
114 status_code, data = http_client.Get( 123 status_code, data = http_client.Get(
115 CreateArchivedBuildUrl(master_name, builder_name, build_number)) 124 CreateArchivedBuildUrl(master_name, builder_name, build_number))
116 if status_code != 200: 125 if status_code != 200:
117 return None 126 return None
118 else: 127 else:
119 return data 128 return data
120 129
121 130
122 def GetStepStdio(master_name, builder_name, build_number, 131 def GetStepStdio(master_name, builder_name, build_number,
123 step_name, http_client): 132 step_name, http_client):
124 """Returns the raw string of stdio of the specified step.""" 133 """Returns the raw string of stdio of the specified step."""
125 status_code, data = http_client.Get( 134 status_code, data = http_client.Get(
126 CreateStdioLogUrl(master_name, builder_name, build_number, step_name)) 135 CreateStdioLogUrl(master_name, builder_name, build_number, step_name))
127 if status_code != 200: 136 if status_code != 200:
128 return None 137 return None
129 else: 138 else:
130 return data 139 return data
131 140
132 141
142 def GetGtestResultLog(master_name,
143 builder_name, build_number, step_name): # pragma: no cover
144 """Returns the archived Step Log file."""
stgao 2015/05/22 01:30:36 This function is to return the content of the gtes
145 try:
146 with contextlib.closing(gcs.open(CreateGtestResultPath(
147 master_name, builder_name,
148 build_number, step_name))) as gtest_result_file:
149 with contextlib.closing(gzip.open(
150 gtest_result_file)) as unzipped_gtest_result_file:
151 return unzipped_gtest_result_file.read()
152 except gcs.NotFoundError:
153 return None
154
155
133 def GetStepResult(step_data_json): 156 def GetStepResult(step_data_json):
134 """Returns the result of a step.""" 157 """Returns the result of a step."""
135 result = step_data_json.get('results') 158 result = step_data_json.get('results')
136 if result is None and step_data_json.get('isFinished'): 159 if result is None and step_data_json.get('isFinished'):
137 # Without parameter filter=0 in the http request to the buildbot json api, 160 # Without parameter filter=0 in the http request to the buildbot json api,
138 # the value of the result of a passed step won't be present. 161 # the value of the result of a passed step won't be present.
139 return SUCCESS 162 return SUCCESS
140 163
141 while isinstance(result, list): 164 while isinstance(result, list):
142 result = result[0] 165 result = result[0]
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 build_info.result = GetBuildResult(data_json) 200 build_info.result = GetBuildResult(data_json)
178 201
179 changes = data_json.get('sourceStamp', {}).get('changes', []) 202 changes = data_json.get('sourceStamp', {}).get('changes', [])
180 for change in changes: 203 for change in changes:
181 build_info.blame_list.append(change['revision']) 204 build_info.blame_list.append(change['revision'])
182 205
183 steps = data_json.get('steps', []) 206 steps = data_json.get('steps', [])
184 for step_data in steps: 207 for step_data in steps:
185 step_name = step_data['name'] 208 step_name = step_data['name']
186 209
187 step_logs = step_data.get('logs') 210 gtest_results = step_data.get('logs')
stgao 2015/05/22 01:30:36 This is actually 'step_logs'. Let's keep it as it
188 if step_logs and 'preamble' == step_logs[0][0]: 211 if gtest_results and 'preamble' == gtest_results[0][0]:
189 # Skip a annotating step like "steps" or "slave_steps", which wraps other 212 # Skip a annotating step like "steps" or "slave_steps", which wraps other
190 # steps. A failed annotated step like "content_browsertests" will make 213 # steps. A failed annotated step like "content_browsertests" will make
191 # the annotating step like "steps" fail too. Such annotating steps have a 214 # the annotating step like "steps" fail too. Such annotating steps have a
192 # log with name "preamble". 215 # log with name "preamble".
193 continue 216 continue
194 217
195 if not step_data.get('isFinished', False): 218 if not step_data.get('isFinished', False):
196 # Skip steps that haven't started yet or are still running. 219 # Skip steps that haven't started yet or are still running.
197 continue 220 continue
198 221
199 step_result = GetStepResult(step_data) 222 step_result = GetStepResult(step_data)
200 if step_result in (SUCCESS, WARNINGS): 223 if step_result in (SUCCESS, WARNINGS):
201 build_info.passed_steps.append(step_name) 224 build_info.passed_steps.append(step_name)
202 elif step_result == FAILURE: 225 elif step_result == FAILURE:
203 build_info.failed_steps.append(step_name) 226 build_info.failed_steps.append(step_name)
204 227
205 return build_info 228 return build_info
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698