| Index: mojo/devtools/common/devtoolslib/perf_dashboard.py
|
| diff --git a/mojo/devtools/common/devtoolslib/perf_dashboard.py b/mojo/devtools/common/devtoolslib/perf_dashboard.py
|
| index 74eb8cabdc0d448528c227e921303e2d0d5e9a0e..71fd1435519460129599aee5e44eb4ad5524782d 100644
|
| --- a/mojo/devtools/common/devtoolslib/perf_dashboard.py
|
| +++ b/mojo/devtools/common/devtoolslib/perf_dashboard.py
|
| @@ -10,8 +10,15 @@ format.
|
| See http://www.chromium.org/developers/speed-infra/performance-dashboard/sending-data-to-the-performance-dashboard.
|
| """
|
|
|
| -import json
|
| from collections import defaultdict
|
| +import httplib
|
| +import json
|
| +import pprint
|
| +import urllib
|
| +import urllib2
|
| +
|
| +
|
| +_LOCAL_SERVER = "http://127.0.0.1:8080"
|
|
|
|
|
| class ChartDataRecorder(object):
|
| @@ -41,3 +48,121 @@ class ChartDataRecorder(object):
|
| 'charts': self.charts
|
| }
|
| return json.dumps(chart_data)
|
| +
|
| +
|
| +def add_argparse_server_arguments(parser):
|
| + """Adds argparse arguments needed to upload the chart data to a performance
|
| + dashboard to the given parser.
|
| + """
|
| + dashboard_group = parser.add_argument_group('Performance dashboard server',
|
| + 'These arguments allow to specify the performance dashboard server '
|
| + 'to upload the results to.')
|
| +
|
| + dashboard_group.add_argument(
|
| + '--server-url',
|
| + help='Url of the server instance to upload the results to. By default a '
|
| + 'local instance is assumed to be running on port 8080.')
|
| + dashboard_group.add_argument(
|
| + '--master-name',
|
| + help='Buildbot master name, used to construct link to buildbot log by '
|
| + 'the dashboard, and also as the top-level category for the data.')
|
| + dashboard_group.add_argument(
|
| + '--perf-id',
|
| + help='Used as the second-level category for the data, usually the '
|
| + 'platform type.')
|
| + dashboard_group.add_argument(
|
| + '--test-name',
|
| + help='Name of the test that the perf data was generated from.')
|
| + dashboard_group.add_argument(
|
| + '--builder-name',
|
| + help='Buildbot builder name, used to construct link to buildbot log by '
|
| + 'the dashboard.')
|
| + dashboard_group.add_argument(
|
| + '--build-number', type=int,
|
| + help='Build number, used to construct link to buildbot log by the '
|
| + 'dashboard.')
|
| + dashboard_group.add_argument(
|
| + '--dry-run', action='store_true', default=False,
|
| + help='Display the server URL and the data to upload, but do not actually '
|
| + 'upload the data.')
|
| +
|
| +
|
| +def upload_chart_data(master_name, perf_id, test_name, builder_name,
|
| + build_number, revision, chart_data, point_id,
|
| + server_url=None, dry_run=False):
|
| + """Uploads the provided chart data to an instance of performance dashboard.
|
| + See the argparse help above for description of the arguments.
|
| +
|
| +
|
| + Returns:
|
| + A boolean value indicating whether the operation succeeded or not.
|
| + """
|
| + class _UploadException(Exception):
|
| + pass
|
| +
|
| + def _upload(server_url, json_data):
|
| + """Make an HTTP POST with the given data to the performance dashboard.
|
| +
|
| + Args:
|
| + server_url: URL of the performance dashboard instance.
|
| + json_data: JSON string that contains the data to be sent.
|
| +
|
| + Raises:
|
| + _UploadException: An error occurred during uploading.
|
| + """
|
| + # When data is provided to urllib2.Request, a POST is sent instead of GET.
|
| + # The data must be in the application/x-www-form-urlencoded format.
|
| + data = urllib.urlencode({"data": json_data})
|
| + req = urllib2.Request("%s/add_point" % server_url, data)
|
| + try:
|
| + urllib2.urlopen(req)
|
| + except urllib2.HTTPError as e:
|
| + raise _UploadException("HTTPError: %d. Response: %s\n"
|
| + "JSON: %s\n" % (e.code, e.read(), json_data))
|
| + except urllib2.URLError as e:
|
| + raise _UploadException("URLError: %s for JSON %s\n" %
|
| + (str(e.reason), json_data))
|
| + except httplib.HTTPException as e:
|
| + raise _UploadException("HTTPException for JSON %s\n" % json_data)
|
| +
|
| + # Wrap the |chart_data| with meta data as required by the spec.
|
| + formatted_data = {
|
| + "master": master_name,
|
| + "bot": perf_id,
|
| + "masterid": master_name,
|
| + "buildername": builder_name,
|
| + "buildnumber": build_number,
|
| + "versions": {
|
| + "mojo": revision
|
| + },
|
| + "point_id": point_id,
|
| + "supplemental": {},
|
| + "chart_data": chart_data
|
| + }
|
| +
|
| + upload_url = server_url if server_url else _LOCAL_SERVER
|
| +
|
| + if dry_run:
|
| + print "Won't upload because --dry-run is specified."
|
| + print "Server: %s" % upload_url
|
| + print "Data:"
|
| + pprint.pprint(formatted_data)
|
| + else:
|
| + print "Uploading data to %s ..." % upload_url
|
| + try:
|
| + _upload(upload_url, json.dumps(formatted_data))
|
| + except _UploadException as e:
|
| + print e
|
| + return False
|
| +
|
| + print "Done."
|
| +
|
| + dashboard_params = urllib.urlencode({
|
| + "masters": master_name,
|
| + "bots": perf_id,
|
| + "tests": test_name,
|
| + "rev": point_id
|
| + })
|
| + print "Results Dashboard: %s/report?%s" % (upload_url, dashboard_params)
|
| +
|
| + return True
|
|
|