blob: 96d1080d45e75b5da163e79b693a47bf801544c3 [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
Patrik Höglund620bed12020-03-17 09:59:10 +010016from tracing.value import histogram
Patrik Höglund0569a122020-03-13 12:26:42 +010017from tracing.value import histogram_set
18from tracing.value.diagnostics import generic_set
19from tracing.value.diagnostics import reserved_infos
20
21
22def _GenerateOauthToken():
23 args = ['luci-auth', 'token']
24 p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
25 if p.wait() == 0:
26 output = p.stdout.read()
27 return output.strip()
28 else:
29 raise RuntimeError(
30 'Error generating authentication token.\nStdout: %s\nStderr:%s' %
31 (p.stdout.read(), p.stderr.read()))
32
33
34def _SendHistogramSet(url, histograms, oauth_token):
35 """Make a HTTP POST with the given JSON to the Performance Dashboard.
36
37 Args:
38 url: URL of Performance Dashboard instance, e.g.
39 "https://chromeperf.appspot.com".
40 histograms: a histogram set object that contains the data to be sent.
41 oauth_token: An oauth token to use for authorization.
42 """
43 headers = {'Authorization': 'Bearer %s' % oauth_token}
44
Patrik Höglunda89ad612020-03-13 16:08:08 +010045 serialized = json.dumps(_ApplyHacks(histograms.AsDicts()), indent=4)
Patrik Höglund0569a122020-03-13 12:26:42 +010046
47 if url.startswith('http://localhost'):
48 # The catapult server turns off compression in developer mode.
49 data = serialized
50 else:
51 data = zlib.compress(serialized)
52
53 print 'Sending %d bytes to %s.' % (len(data), url + '/add_histograms')
54
55 http = httplib2.Http()
56 response, content = http.request(url + '/add_histograms', method='POST',
57 body=data, headers=headers)
58 return response, content
59
60
Patrik Höglund457c8cf2020-03-13 14:43:21 +010061# TODO(https://crbug.com/1029452): HACKHACK
Patrik Höglund620bed12020-03-17 09:59:10 +010062# Remove once we have doubles in the proto and handle -infinity correctly.
Patrik Höglunda89ad612020-03-13 16:08:08 +010063def _ApplyHacks(dicts):
Patrik Höglund457c8cf2020-03-13 14:43:21 +010064 for d in dicts:
Patrik Höglund620bed12020-03-17 09:59:10 +010065 if 'running' in d:
66 def _NoInf(value):
67 if value == float('inf'):
68 return histogram.JS_MAX_VALUE
69 if value == float('-inf'):
70 return -histogram.JS_MAX_VALUE
71 return value
72 d['running'] = [_NoInf(value) for value in d['running']]
Patrik Höglund457c8cf2020-03-13 14:43:21 +010073
74 return dicts
75
76
Patrik Höglund0569a122020-03-13 12:26:42 +010077def _LoadHistogramSetFromProto(options):
78 hs = histogram_set.HistogramSet()
79 with options.input_results_file as f:
80 hs.ImportProto(f.read())
81
82 return hs
83
84
85def _AddBuildInfo(histograms, options):
86 common_diagnostics = {
87 reserved_infos.MASTERS: options.perf_dashboard_machine_group,
88 reserved_infos.BOTS: options.bot,
89 reserved_infos.POINT_ID: options.commit_position,
90 reserved_infos.BENCHMARKS: options.test_suite,
91 reserved_infos.WEBRTC_REVISIONS: str(options.webrtc_git_hash),
92 reserved_infos.BUILD_URLS: options.build_page_url,
93 }
94
95 for k, v in common_diagnostics.items():
96 histograms.AddSharedDiagnosticToAllHistograms(
97 k.name, generic_set.GenericSet([v]))
98
99
100def _DumpOutput(histograms, output_file):
101 with output_file:
Patrik Höglunda89ad612020-03-13 16:08:08 +0100102 json.dump(_ApplyHacks(histograms.AsDicts()), output_file, indent=4)
Patrik Höglund0569a122020-03-13 12:26:42 +0100103
104
105# TODO(https://crbug.com/1029452): Remove this once
106# https://chromium-review.googlesource.com/c/catapult/+/2094312 lands.
107def _HackSummaryOptions(histograms):
Patrik Höglund620bed12020-03-17 09:59:10 +0100108 for h in histograms:
109 h.CustomizeSummaryOptions({
Patrik Höglund0569a122020-03-13 12:26:42 +0100110 'avg': False,
111 'std': False,
112 'count': False,
113 'sum': False,
114 'min': False,
115 'max': False,
116 'nans': False,
117 })
118
119
120def UploadToDashboard(options):
121 histograms = _LoadHistogramSetFromProto(options)
122 _AddBuildInfo(histograms, options)
123 _HackSummaryOptions(histograms)
124
125 if options.output_json_file:
126 _DumpOutput(histograms, options.output_json_file)
127
128 oauth_token = _GenerateOauthToken()
129 response, content = _SendHistogramSet(
130 options.dashboard_url, histograms, oauth_token)
131
132 if response.status == 200:
133 print 'Received 200 from dashboard.'
134 return 0
135 else:
136 print('Upload failed with %d: %s\n\n%s' % (response.status, response.reason,
137 content))
138 return 1