mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-14 06:10:40 +01:00

This effectively makes WebRTC upload histogram sets instead of Chart JSON. Histogram sets is the newest format used by Chromium. I'm doing this because it's nice to use the most modern thing, but mostly because it's the default for PinPoint. This means I don't have to implement and support a new read quest for Chart JSON. This script has to be source side, because we need third_party/catapult to write correct histograms. This script will be called from recipes. I also considered generating histogram JSON directly in test/testsupport/perf_test.cc, which could have avoided this conversion from Chart JSON to histogram sets, but I can't because there is no C++ API for histogram sets. Bug: webrtc:11084 Change-Id: If0d2315d2057112b3c2d54a9cfd12e59b5858a18 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/159780 Reviewed-by: Artem Titov <titovartem@webrtc.org> Commit-Queue: Patrik Höglund <phoglund@webrtc.org> Cr-Commit-Position: refs/heads/master@{#29818}
138 lines
5.1 KiB
Python
138 lines
5.1 KiB
Python
#!/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:]))
|