#!/usr/bin/env python2.7
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Script to pull chromium.perf stats from chrome-infra-stats API.
Currently this just pulls success rates from the API, averages daily per
builder, and uploads to perf dashboard. It could be improved to provide more
detailed success rates.
The API documentation for chrome-infra-stats is at:
https://apis-explorer.appspot.com/apis-explorer/?
base=https://chrome-infra-stats.appspot.com/_ah/api#p/
"""
import calendar
import datetime
import json
import sys
import urllib
import urllib2
BUILDER_LIST_URL = ('https://chrome-infra-stats.appspot.com/'
'_ah/api/stats/v1/masters/chromium.perf')
BUILDER_STATS_URL = ('https://chrome-infra-stats.appspot.com/_ah/api/stats/v1/'
'stats/chromium.perf/%s/overall__build__result__/%s')
USAGE = ('Usage: chrome_perf_stats.py <year> <month> <day>. If date is not '
'specified, yesterday will be used.')
def main():
if len(sys.argv) == 2 and sys.argv[0] == '--help':
print USAGE
sys.exit(0)
year = None
month = None
days = None
if len(sys.argv) == 4 or len(sys.argv) == 3:
year = int(sys.argv[1])
if year > 2016 or year < 2014:
print USAGE
sys.exit(0)
month = int(sys.argv[2])
if month > 12 or month <= 0:
print USAGE
sys.exit(0)
if len(sys.argv) == 3:
days = range(1, calendar.monthrange(year, month)[1] + 1)
else:
day = int(sys.argv[3])
if day > 31 or day <= 0:
print USAGE
sys.exit(0)
days = [day]
elif len(sys.argv) != 1:
print USAGE
sys.exit(0)
else:
yesterday = datetime.date.today() - datetime.timedelta(days=1)
year = yesterday.year
month = yesterday.month
days = [yesterday.day]
response = urllib2.urlopen(BUILDER_LIST_URL)
builders = [builder['name'] for builder in json.load(response)['builders']]
success_rates = CalculateSuccessRates(year, month, days, builders)
UploadToPerfDashboard(success_rates)
def _UpdateSuccessRatesWithResult(
success_rates, results, date_dict_str, builder):
count = int(results['count'])
if count == 0:
return
success_count = count - int(results['failure_count'])
success_rates.setdefault(date_dict_str, {})
success_rates[date_dict_str].setdefault(builder, {
'count': 0,
'success_count': 0
})
success_rates[date_dict_str][builder]['count'] += count
success_rates[date_dict_str][builder]['success_count'] += success_count
def _SummarizeSuccessRates(success_rates):
overall_success_rates = []
for day, results in success_rates.iteritems():
success_rate_sum = 0
success_rate_count = 0
for rates in results.values():
if rates['count'] == 0:
continue
success_rate_sum += (
float(rates['success_count']) / float(rates['count']))
success_rate_count += 1
overall_success_rates.append(
[day, float(success_rate_sum) / float(success_rate_count)])
return overall_success_rates
def UploadToPerfDashboard(success_rates):
for success_rate in success_rates:
date_str = '%s-%s-%s' % (success_rate[0][0:4],
success_rate[0][4:6],
success_rate[0][6:8])
dashboard_data = {
'master': 'WaterfallStats',
'bot': 'ChromiumPerf',
'point_id': int(success_rate[0]),
'supplemental': {},
'versions': {
'date': date_str,
},
'chart_data': {
'benchmark_name': 'success_rate',
'benchmark_description': 'Success rates averaged per-builder',
'format_version': 1.0,
'charts': {
'overall_success_rate': {
'summary': {
'name': 'overall_success_rate',
'type': 'scalar',
'units': '%',
'value': success_rate[1]
}
}
}
}
}
url = 'https://chromeperf.appspot.com/add_point'
data = urllib.urlencode({'data': json.dumps(dashboard_data)})
urllib2.urlopen(url=url, data=data).read()
def CalculateSuccessRates(year, month, days, builders):
success_rates = {}
for day in days:
for hour in range(24):
date_str = '%d-%02d-%02dT%02d:00Z' % (year, month, day, hour)
date_dict_str = '%d%02d%02d' % (year, month, day)
for builder in builders:
url = BUILDER_STATS_URL % (
urllib.quote(builder), urllib.quote(date_str))
response = urllib2.urlopen(url)
results = json.load(response)
_UpdateSuccessRatesWithResult(
success_rates, results, date_dict_str, builder)
return _SummarizeSuccessRates(success_rates)
if __name__ == "__main__":
main()