blob: d04374a5134ef70586043aaa1f172488da37cf06 [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
"""Converts and uploads results to the Chrome perf dashboard.
This conversion step is needed because test/testsupport/perf_test.cc can't
output histograms natively. There is, unfortunately, no C++ API for histograms.
This script is in python so it can depend on Catapult's python API instead.
See histogram_util.py for how this is done. We should move to the C++ API and
delete the scripts in this dir as soon as there is a C++ API (less conversions =
easier to understand).
This script can't be in recipes, because we can't access the catapult APIs from
there. It needs to be here source-side.
This script is adapted from the downstream variant like this:
* Follows upstream naming conventions.
* Downstream-only parameters and concepts go away.
* oAuth tokens are generated by luci-auth.
"""
import argparse
import httplib2
import json
import sys
import subprocess
import zlib
import histogram_util
def _GenerateOauthToken():
args = ['luci-auth', 'token']
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if p.wait() == 0:
output = p.stdout.read()
return output.strip()
else:
raise RuntimeError(
'Error generating authentication token.\nStdout: %s\nStderr:%s' %
(p.stdout.read(), p.stderr.read()))
def _SendHistogramSetJson(url, histogram_json, oauth_token):
"""Make a HTTP POST with the given JSON to the Performance Dashboard.
Args:
url: URL of Performance Dashboard instance, e.g.
"https://chromeperf.appspot.com".
histogram_json: a JSON object that contains the data to be sent.
oauth_token: An oauth token to use for authorization.
"""
headers = {'Authorization': 'Bearer %s' % oauth_token}
serialized = json.dumps(histogram_json.AsDicts(), indent=4)
data = zlib.compress(serialized)
http = httplib2.Http()
response, content = http.request(url + '/add_histograms', method='POST',
body=data, headers=headers)
return response, content
def _LoadHistogramSetJson(options):
with options.input_results_file as f:
json_data = json.load(f)
histograms = histogram_util.LoadHistograms(json_data)
hs = histogram_util.MakeWebRtcHistogramSet(
stats=histograms,
commit_pos=options.commit_position,
commit_hash=options.webrtc_git_hash,
master=options.perf_dashboard_machine_group,
bot=options.bot,
test_suite=options.test_suite,
build_url=options.build_page_url)
return hs
def _CreateParser():
parser = argparse.ArgumentParser()
parser.add_argument('--perf-dashboard-machine-group', required=True,
help='The "master" the bots are grouped under. This '
'string is the group in the the perf dashboard path '
'group/bot/perf_id/metric/subtest.')
parser.add_argument('--bot', required=True,
help='The bot running the test (e.g. '
'webrtc-win-large-tests).')
parser.add_argument('--test-suite', required=True,
help='The key for the test in the dashboard (i.e. what '
'you select in the top-level test suite selector in the '
'dashboard')
parser.add_argument('--webrtc-git-hash', required=True,
help='webrtc.googlesource.com commit hash.')
parser.add_argument('--commit-position', type=int, required=True,
help='Commit pos corresponding to the git hash.')
parser.add_argument('--build-page-url', required=True,
help='URL to the build page for this build.')
parser.add_argument('--dashboard-url', required=True,
help='Which dashboard to use.')
parser.add_argument('--input-results-file', type=argparse.FileType(),
required=True,
help='A JSON file with output from WebRTC tests.')
parser.add_argument('--output-json-file', type=argparse.FileType('w'),
help='Where to write the output (for debugging).')
return parser
def main(args):
parser = _CreateParser()
options = parser.parse_args(args)
histogram_json = _LoadHistogramSetJson(options)
if options.output_json_file:
with options.output_json_file as output_file:
json.dump(histogram_json.AsDicts(), output_file, indent=4)
oauth_token = _GenerateOauthToken()
response, content = _SendHistogramSetJson(
options.dashboard_url, histogram_json, oauth_token)
if response.status == 200:
return 0
else:
print("Upload failed with %d: %s\n\n%s" % (response.status, response.reason,
content))
return 1
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))