blob: ab7c4f792aceb1b180a5a2f01277f2aabb646e14 [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
Patrik Höglund457c8cf2020-03-13 14:43:21 +010044 serialized = json.dumps(_ApplyAllBinsHack(histograms.AsDicts()), indent=4)
Patrik Höglund0569a122020-03-13 12:26:42 +010045
46 if url.startswith('http://localhost'):
47 # The catapult server turns off compression in developer mode.
48 data = serialized
49 else:
50 data = zlib.compress(serialized)
51
52 print 'Sending %d bytes to %s.' % (len(data), url + '/add_histograms')
53
54 http = httplib2.Http()
55 response, content = http.request(url + '/add_histograms', method='POST',
56 body=data, headers=headers)
57 return response, content
58
59
Patrik Höglund457c8cf2020-03-13 14:43:21 +010060# TODO(https://crbug.com/1029452): HACKHACK
61# Remove once we set bin bounds correctly in the proto writer.
62def _ApplyAllBinsHack(dicts):
63 for d in dicts:
64 if 'name' in d:
65 d['allBins'] = [[1]]
66
67 return dicts
68
69
Patrik Höglund0569a122020-03-13 12:26:42 +010070def _LoadHistogramSetFromProto(options):
71 hs = histogram_set.HistogramSet()
72 with options.input_results_file as f:
73 hs.ImportProto(f.read())
74
75 return hs
76
77
78def _AddBuildInfo(histograms, options):
79 common_diagnostics = {
80 reserved_infos.MASTERS: options.perf_dashboard_machine_group,
81 reserved_infos.BOTS: options.bot,
82 reserved_infos.POINT_ID: options.commit_position,
83 reserved_infos.BENCHMARKS: options.test_suite,
84 reserved_infos.WEBRTC_REVISIONS: str(options.webrtc_git_hash),
85 reserved_infos.BUILD_URLS: options.build_page_url,
86 }
87
88 for k, v in common_diagnostics.items():
89 histograms.AddSharedDiagnosticToAllHistograms(
90 k.name, generic_set.GenericSet([v]))
91
92
93def _DumpOutput(histograms, output_file):
94 with output_file:
Patrik Höglund457c8cf2020-03-13 14:43:21 +010095 json.dump(_ApplyAllBinsHack(histograms.AsDicts()), output_file, indent=4)
Patrik Höglund0569a122020-03-13 12:26:42 +010096
97
98# TODO(https://crbug.com/1029452): Remove this once
99# https://chromium-review.googlesource.com/c/catapult/+/2094312 lands.
100def _HackSummaryOptions(histograms):
101 for histogram in histograms:
102 histogram.CustomizeSummaryOptions({
103 'avg': False,
104 'std': False,
105 'count': False,
106 'sum': False,
107 'min': False,
108 'max': False,
109 'nans': False,
110 })
111
112
113def UploadToDashboard(options):
114 histograms = _LoadHistogramSetFromProto(options)
115 _AddBuildInfo(histograms, options)
116 _HackSummaryOptions(histograms)
117
118 if options.output_json_file:
119 _DumpOutput(histograms, options.output_json_file)
120
121 oauth_token = _GenerateOauthToken()
122 response, content = _SendHistogramSet(
123 options.dashboard_url, histograms, oauth_token)
124
125 if response.status == 200:
126 print 'Received 200 from dashboard.'
127 return 0
128 else:
129 print('Upload failed with %d: %s\n\n%s' % (response.status, response.reason,
130 content))
131 return 1