blob: d0b02f8c9c99007f032e59299fc3392683c30675 [file] [log] [blame]
Patrik Höglund0569a122020-03-13 12:26:42 +01001#!/usr/bin/env python
2# Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3#
4# Use of this source code is governed by a BSD-style license
5# that can be found in the LICENSE file in the root of the source
6# tree. An additional intellectual property rights grant can be found
7# in the file PATENTS. All contributing project authors may
8# be found in the AUTHORS file in the root of the source tree.
9
10
11import httplib2
12import json
13import subprocess
14import zlib
15
16from tracing.value import histogram_set
17from tracing.value.diagnostics import generic_set
18from tracing.value.diagnostics import reserved_infos
19
20
21def _GenerateOauthToken():
22 args = ['luci-auth', 'token']
23 p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
24 if p.wait() == 0:
25 output = p.stdout.read()
26 return output.strip()
27 else:
28 raise RuntimeError(
29 'Error generating authentication token.\nStdout: %s\nStderr:%s' %
30 (p.stdout.read(), p.stderr.read()))
31
32
33def _SendHistogramSet(url, histograms, oauth_token):
34 """Make a HTTP POST with the given JSON to the Performance Dashboard.
35
36 Args:
37 url: URL of Performance Dashboard instance, e.g.
38 "https://chromeperf.appspot.com".
39 histograms: a histogram set object that contains the data to be sent.
40 oauth_token: An oauth token to use for authorization.
41 """
42 headers = {'Authorization': 'Bearer %s' % oauth_token}
43
44 # TODO(https://crbug.com/1029452): HACKHACK
45 # Remove once we set bin bounds correctly in the proto writer.
46 dicts = histograms.AsDicts()
47 for d in dicts:
48 if 'name' in d:
49 d['allBins'] = [[1]]
50
51 serialized = json.dumps(dicts, indent=4)
52
53 if url.startswith('http://localhost'):
54 # The catapult server turns off compression in developer mode.
55 data = serialized
56 else:
57 data = zlib.compress(serialized)
58
59 print 'Sending %d bytes to %s.' % (len(data), url + '/add_histograms')
60
61 http = httplib2.Http()
62 response, content = http.request(url + '/add_histograms', method='POST',
63 body=data, headers=headers)
64 return response, content
65
66
67def _LoadHistogramSetFromProto(options):
68 hs = histogram_set.HistogramSet()
69 with options.input_results_file as f:
70 hs.ImportProto(f.read())
71
72 return hs
73
74
75def _AddBuildInfo(histograms, options):
76 common_diagnostics = {
77 reserved_infos.MASTERS: options.perf_dashboard_machine_group,
78 reserved_infos.BOTS: options.bot,
79 reserved_infos.POINT_ID: options.commit_position,
80 reserved_infos.BENCHMARKS: options.test_suite,
81 reserved_infos.WEBRTC_REVISIONS: str(options.webrtc_git_hash),
82 reserved_infos.BUILD_URLS: options.build_page_url,
83 }
84
85 for k, v in common_diagnostics.items():
86 histograms.AddSharedDiagnosticToAllHistograms(
87 k.name, generic_set.GenericSet([v]))
88
89
90def _DumpOutput(histograms, output_file):
91 with output_file:
92 json.dump(histograms.AsDicts(), output_file, indent=4)
93
94
95# TODO(https://crbug.com/1029452): Remove this once
96# https://chromium-review.googlesource.com/c/catapult/+/2094312 lands.
97def _HackSummaryOptions(histograms):
98 for histogram in histograms:
99 histogram.CustomizeSummaryOptions({
100 'avg': False,
101 'std': False,
102 'count': False,
103 'sum': False,
104 'min': False,
105 'max': False,
106 'nans': False,
107 })
108
109
110def UploadToDashboard(options):
111 histograms = _LoadHistogramSetFromProto(options)
112 _AddBuildInfo(histograms, options)
113 _HackSummaryOptions(histograms)
114
115 if options.output_json_file:
116 _DumpOutput(histograms, options.output_json_file)
117
118 oauth_token = _GenerateOauthToken()
119 response, content = _SendHistogramSet(
120 options.dashboard_url, histograms, oauth_token)
121
122 if response.status == 200:
123 print 'Received 200 from dashboard.'
124 return 0
125 else:
126 print('Upload failed with %d: %s\n\n%s' % (response.status, response.reason,
127 content))
128 return 1