| OLD | NEW |
| 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 | 13 from collections import defaultdict |
| 14 import httplib | 14 import httplib |
| 15 import json | 15 import json |
| 16 import pprint | 16 import pprint |
| 17 import subprocess |
| 17 import urllib | 18 import urllib |
| 18 import urllib2 | 19 import urllib2 |
| 19 | 20 |
| 20 | 21 |
| 21 _LOCAL_SERVER = "http://127.0.0.1:8080" | 22 _LOCAL_SERVER = "http://127.0.0.1:8080" |
| 22 | 23 |
| 23 | 24 |
| 24 class ChartDataRecorder(object): | 25 class ChartDataRecorder(object): |
| 25 """Allows one to record measurement values one by one and then generate the | 26 """Allows one to record measurement values one by one and then generate the |
| 26 JSON string that represents them in the 'chart_data' format expected by the | 27 JSON string that represents them in the 'chart_data' format expected by the |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 dashboard_group.add_argument( | 84 dashboard_group.add_argument( |
| 84 '--build-number', type=int, | 85 '--build-number', type=int, |
| 85 help='Build number, used to construct link to buildbot log by the ' | 86 help='Build number, used to construct link to buildbot log by the ' |
| 86 'dashboard.') | 87 'dashboard.') |
| 87 dashboard_group.add_argument( | 88 dashboard_group.add_argument( |
| 88 '--dry-run', action='store_true', default=False, | 89 '--dry-run', action='store_true', default=False, |
| 89 help='Display the server URL and the data to upload, but do not actually ' | 90 help='Display the server URL and the data to upload, but do not actually ' |
| 90 'upload the data.') | 91 'upload the data.') |
| 91 | 92 |
| 92 | 93 |
| 94 def _get_commit_count(): |
| 95 """Returns the number of git commits in the repository of the cwd.""" |
| 96 return subprocess.check_output( |
| 97 ["git", "rev-list", "HEAD", "--count"]).strip() |
| 98 |
| 99 |
| 100 def _get_current_commit(): |
| 101 """Returns the hash of the current commit in the repository of the cwd.""" |
| 102 return subprocess.check_output(["git", "rev-parse", "HEAD"]).strip() |
| 103 |
| 104 |
| 93 def upload_chart_data(master_name, bot_name, test_name, builder_name, | 105 def upload_chart_data(master_name, bot_name, test_name, builder_name, |
| 94 build_number, revision, chart_data, point_id, | 106 build_number, chart_data, server_url=None, dry_run=False): |
| 95 server_url=None, dry_run=False): | |
| 96 """Uploads the provided chart data to an instance of performance dashboard. | 107 """Uploads the provided chart data to an instance of performance dashboard. |
| 97 See the argparse help above for description of the arguments. | 108 See the argparse help above for description of the arguments. |
| 98 | 109 |
| 99 | 110 |
| 100 Returns: | 111 Returns: |
| 101 A boolean value indicating whether the operation succeeded or not. | 112 A boolean value indicating whether the operation succeeded or not. |
| 102 """ | 113 """ |
| 103 class _UploadException(Exception): | 114 class _UploadException(Exception): |
| 104 pass | 115 pass |
| 105 | 116 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 121 urllib2.urlopen(req) | 132 urllib2.urlopen(req) |
| 122 except urllib2.HTTPError as e: | 133 except urllib2.HTTPError as e: |
| 123 raise _UploadException("HTTPError: %d. Response: %s\n" | 134 raise _UploadException("HTTPError: %d. Response: %s\n" |
| 124 "JSON: %s\n" % (e.code, e.read(), json_data)) | 135 "JSON: %s\n" % (e.code, e.read(), json_data)) |
| 125 except urllib2.URLError as e: | 136 except urllib2.URLError as e: |
| 126 raise _UploadException("URLError: %s for JSON %s\n" % | 137 raise _UploadException("URLError: %s for JSON %s\n" % |
| 127 (str(e.reason), json_data)) | 138 (str(e.reason), json_data)) |
| 128 except httplib.HTTPException as e: | 139 except httplib.HTTPException as e: |
| 129 raise _UploadException("HTTPException for JSON %s\n" % json_data) | 140 raise _UploadException("HTTPException for JSON %s\n" % json_data) |
| 130 | 141 |
| 142 if (not master_name or not bot_name or not test_name or not builder_name or |
| 143 not build_number): |
| 144 print ('Cannot upload perf data to the dashboard because not all of the ' |
| 145 'following values are specified: master-name, bot-name, test_name, ' |
| 146 'builder-name, build-number.') |
| 147 return False |
| 148 |
| 149 point_id = _get_commit_count() |
| 150 cur_commit = _get_current_commit() |
| 151 |
| 131 # Wrap the |chart_data| with meta data as required by the spec. | 152 # Wrap the |chart_data| with meta data as required by the spec. |
| 132 formatted_data = { | 153 formatted_data = { |
| 133 "master": master_name, | 154 "master": master_name, |
| 134 "bot": bot_name, | 155 "bot": bot_name, |
| 135 "masterid": master_name, | 156 "masterid": master_name, |
| 136 "buildername": builder_name, | 157 "buildername": builder_name, |
| 137 "buildnumber": build_number, | 158 "buildnumber": build_number, |
| 138 "versions": { | 159 "versions": { |
| 139 "mojo": revision | 160 "mojo": cur_commit, |
| 140 }, | 161 }, |
| 141 "point_id": point_id, | 162 "point_id": point_id, |
| 142 "supplemental": {}, | 163 "supplemental": {}, |
| 143 "chart_data": chart_data | 164 "chart_data": chart_data, |
| 144 } | 165 } |
| 145 | 166 |
| 146 upload_url = server_url if server_url else _LOCAL_SERVER | 167 upload_url = server_url if server_url else _LOCAL_SERVER |
| 147 | 168 |
| 148 if dry_run: | 169 if dry_run: |
| 149 print "Won't upload because --dry-run is specified." | 170 print "Won't upload because --dry-run is specified." |
| 150 print "Server: %s" % upload_url | 171 print "Server: %s" % upload_url |
| 151 print "Data:" | 172 print "Data:" |
| 152 pprint.pprint(formatted_data) | 173 pprint.pprint(formatted_data) |
| 153 else: | 174 else: |
| 154 print "Uploading data to %s ..." % upload_url | 175 print "Uploading data to %s ..." % upload_url |
| 155 try: | 176 try: |
| 156 _upload(upload_url, json.dumps(formatted_data)) | 177 _upload(upload_url, json.dumps(formatted_data)) |
| 157 except _UploadException as e: | 178 except _UploadException as e: |
| 158 print e | 179 print e |
| 159 return False | 180 return False |
| 160 | 181 |
| 161 print "Done." | 182 print "Done." |
| 162 | 183 |
| 163 dashboard_params = urllib.urlencode({ | 184 dashboard_params = urllib.urlencode({ |
| 164 "masters": master_name, | 185 "masters": master_name, |
| 165 "bots": bot_name, | 186 "bots": bot_name, |
| 166 "tests": test_name, | 187 "tests": test_name, |
| 167 "rev": point_id | 188 "rev": point_id |
| 168 }) | 189 }) |
| 169 print "Results Dashboard: %s/report?%s" % (upload_url, dashboard_params) | 190 print "Results Dashboard: %s/report?%s" % (upload_url, dashboard_params) |
| 170 | 191 |
| 171 return True | 192 return True |
| OLD | NEW |