Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: mojo/devtools/common/devtoolslib/perf_dashboard.py

Issue 1421823002: Move performance dashboard upload logic to devtoolslib. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Move the argparse part too. Created 5 years, 2 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
« no previous file with comments | « no previous file | mojo/tools/get_test_list.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 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 # Disable the line-too-long warning. 5 # Disable the line-too-long warning.
6 # pylint: disable=C0301 6 # pylint: disable=C0301
7 """This module implements the Chromium Performance Dashboard JSON v1.0 data 7 """This module implements the Chromium Performance Dashboard JSON v1.0 data
8 format. 8 format.
9 9
10 See http://www.chromium.org/developers/speed-infra/performance-dashboard/sending -data-to-the-performance-dashboard. 10 See http://www.chromium.org/developers/speed-infra/performance-dashboard/sending -data-to-the-performance-dashboard.
11 """ 11 """
12 12
13 from collections import defaultdict
14 import httplib
13 import json 15 import json
14 from collections import defaultdict 16 import pprint
17 import urllib
18 import urllib2
19
20
21 _LOCAL_SERVER = "http://127.0.0.1:8080"
15 22
16 23
17 class ChartDataRecorder(object): 24 class ChartDataRecorder(object):
18 """Allows one to record measurement values one by one and then generate the 25 """Allows one to record measurement values one by one and then generate the
19 JSON string that represents them in the 'chart_data' format expected by the 26 JSON string that represents them in the 'chart_data' format expected by the
20 performance dashboard. 27 performance dashboard.
21 """ 28 """
22 29
23 def __init__(self, benchmark_name): 30 def __init__(self, benchmark_name):
24 self.charts = defaultdict(list) 31 self.charts = defaultdict(list)
25 self.benchmark_name = benchmark_name 32 self.benchmark_name = benchmark_name
26 33
27 def record_scalar(self, chart_name, value_name, units, value): 34 def record_scalar(self, chart_name, value_name, units, value):
28 """Records a single measurement value of a scalar type.""" 35 """Records a single measurement value of a scalar type."""
29 self.charts[chart_name].append({ 36 self.charts[chart_name].append({
30 'type': 'scalar', 37 'type': 'scalar',
31 'name': value_name, 38 'name': value_name,
32 'units': units, 39 'units': units,
33 'value': value}) 40 'value': value})
34 41
35 def get_json(self): 42 def get_json(self):
36 """Returns the JSON string representing the recorded chart data, wrapping 43 """Returns the JSON string representing the recorded chart data, wrapping
37 it with the required meta data.""" 44 it with the required meta data."""
38 chart_data = { 45 chart_data = {
39 'format_version': '1.0', 46 'format_version': '1.0',
40 'benchmark_name': self.benchmark_name, 47 'benchmark_name': self.benchmark_name,
41 'charts': self.charts 48 'charts': self.charts
42 } 49 }
43 return json.dumps(chart_data) 50 return json.dumps(chart_data)
51
52
53 def add_argparse_server_arguments(parser):
54 """Adds argparse arguments needed to upload the chart data to a performance
55 dashboard to the given parser.
56 """
57 dashboard_group = parser.add_argument_group('Performance dashboard server',
58 'These arguments allow to specify the performance dashboard server '
59 'to upload the results to.')
60
61 dashboard_group.add_argument(
62 '--server-url',
63 help='Url of the server instance to upload the results to. By default a '
64 'local instance is assumed to be running on port 8080.')
65 dashboard_group.add_argument(
66 '--master-name',
67 help='Buildbot master name, used to construct link to buildbot log by '
68 'the dashboard, and also as the top-level category for the data.')
69 dashboard_group.add_argument(
70 '--perf-id',
71 help='Used as the second-level category for the data, usually the '
72 'platform type.')
73 dashboard_group.add_argument(
74 '--test-name',
75 help='Name of the test that the perf data was generated from.')
76 dashboard_group.add_argument(
77 '--builder-name',
78 help='Buildbot builder name, used to construct link to buildbot log by '
79 'the dashboard.')
80 dashboard_group.add_argument(
81 '--build-number', type=int,
82 help='Build number, used to construct link to buildbot log by the '
83 'dashboard.')
84 dashboard_group.add_argument(
85 '--dry-run', action='store_true', default=False,
86 help='Display the server URL and the data to upload, but do not actually '
87 'upload the data.')
88
89
90 def upload_chart_data(master_name, perf_id, test_name, builder_name,
91 build_number, revision, chart_data, point_id,
92 server_url=None, dry_run=False):
93 """Uploads the provided chart data to an instance of performance dashboard.
94 See the argparse help above for description of the arguments.
95
96
97 Returns:
98 A boolean value indicating whether the operation succeeded or not.
99 """
100 class _UploadException(Exception):
101 pass
102
103 def _upload(server_url, json_data):
104 """Make an HTTP POST with the given data to the performance dashboard.
105
106 Args:
107 server_url: URL of the performance dashboard instance.
108 json_data: JSON string that contains the data to be sent.
109
110 Raises:
111 _UploadException: An error occurred during uploading.
112 """
113 # When data is provided to urllib2.Request, a POST is sent instead of GET.
114 # The data must be in the application/x-www-form-urlencoded format.
115 data = urllib.urlencode({"data": json_data})
116 req = urllib2.Request("%s/add_point" % server_url, data)
117 try:
118 urllib2.urlopen(req)
119 except urllib2.HTTPError as e:
120 raise _UploadException("HTTPError: %d. Response: %s\n"
121 "JSON: %s\n" % (e.code, e.read(), json_data))
122 except urllib2.URLError as e:
123 raise _UploadException("URLError: %s for JSON %s\n" %
124 (str(e.reason), json_data))
125 except httplib.HTTPException as e:
126 raise _UploadException("HTTPException for JSON %s\n" % json_data)
127
128 # Wrap the |chart_data| with meta data as required by the spec.
129 formatted_data = {
130 "master": master_name,
131 "bot": perf_id,
132 "masterid": master_name,
133 "buildername": builder_name,
134 "buildnumber": build_number,
135 "versions": {
136 "mojo": revision
137 },
138 "point_id": point_id,
139 "supplemental": {},
140 "chart_data": chart_data
141 }
142
143 upload_url = server_url if server_url else _LOCAL_SERVER
144
145 if dry_run:
146 print "Won't upload because --dry-run is specified."
147 print "Server: %s" % upload_url
148 print "Data:"
149 pprint.pprint(formatted_data)
150 else:
151 print "Uploading data to %s ..." % upload_url
152 try:
153 _upload(upload_url, json.dumps(formatted_data))
154 except _UploadException as e:
155 print e
156 return False
157
158 print "Done."
159
160 dashboard_params = urllib.urlencode({
161 "masters": master_name,
162 "bots": perf_id,
163 "tests": test_name,
164 "rev": point_id
165 })
166 print "Results Dashboard: %s/report?%s" % (upload_url, dashboard_params)
167
168 return True
OLDNEW
« no previous file with comments | « no previous file | mojo/tools/get_test_list.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698