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

Side by Side Diff: dashboard/dashboard/add_histograms.py

Issue 3000853002: Make add_histograms use reserved GenericSet names. (Closed)
Patch Set: Created 3 years, 4 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 | dashboard/dashboard/add_histograms_queue_test.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 2017 The Chromium Authors. All rights reserved. 1 # Copyright 2017 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 """URL endpoint for adding new histograms to the dashboard.""" 5 """URL endpoint for adding new histograms to the dashboard."""
6 6
7 import json 7 import json
8 import sys 8 import sys
9 9
10 from google.appengine.api import taskqueue 10 from google.appengine.api import taskqueue
11 from google.appengine.ext import ndb 11 from google.appengine.ext import ndb
12 12
13 from dashboard import add_point_queue 13 from dashboard import add_point_queue
14 from dashboard.api import api_request_handler 14 from dashboard.api import api_request_handler
15 from dashboard.common import datastore_hooks 15 from dashboard.common import datastore_hooks
16 from dashboard.common import stored_object 16 from dashboard.common import stored_object
17 from dashboard.models import histogram 17 from dashboard.models import histogram
18 from tracing.value import histogram as histogram_module
19 from tracing.value import histogram_set 18 from tracing.value import histogram_set
20 from tracing.value.diagnostics import diagnostic 19 from tracing.value.diagnostics import diagnostic
21 from tracing.value.diagnostics import reserved_infos 20 from tracing.value.diagnostics import reserved_infos
22 21
23 SUITE_LEVEL_SPARSE_DIAGNOSTIC_NAMES = set( 22 SUITE_LEVEL_SPARSE_DIAGNOSTIC_NAMES = set([
24 [reserved_infos.ARCHITECTURES.name, 23 reserved_infos.ARCHITECTURES.name,
25 reserved_infos.BUG_COMPONENTS.name, 24 reserved_infos.BENCHMARKS.name,
26 reserved_infos.GPUS.name, 25 reserved_infos.BOTS.name,
27 reserved_infos.MEMORY_AMOUNTS.name, 26 reserved_infos.BUG_COMPONENTS.name,
28 reserved_infos.OS_NAMES.name, 27 reserved_infos.GPUS.name,
29 reserved_infos.OS_VERSIONS.name, 28 reserved_infos.MASTERS.name,
30 reserved_infos.OWNERS.name, 29 reserved_infos.MEMORY_AMOUNTS.name,
31 reserved_infos.PRODUCT_VERSIONS.name]) 30 reserved_infos.OS_NAMES.name,
32 # TODO(#3507): Make BuildbotInfo into GenericSet diagnostics and remove all 31 reserved_infos.OS_VERSIONS.name,
33 # logic regarding picking diagnostics by type. 32 reserved_infos.OWNERS.name,
34 SUITE_LEVEL_SPARSE_DIAGNOSTIC_TYPES = set( 33 reserved_infos.PRODUCT_VERSIONS.name,
35 [histogram_module.BuildbotInfo]) 34 reserved_infos.TAG_MAP.name,
36 HISTOGRAM_LEVEL_SPARSE_DIAGNOSTIC_TYPES = set( 35 ])
37 [histogram_module.TelemetryInfo]) 36
38 SPARSE_DIAGNOSTIC_TYPES = SUITE_LEVEL_SPARSE_DIAGNOSTIC_TYPES.union( 37 HISTOGRAM_LEVEL_SPARSE_DIAGNOSTIC_NAMES = set([
39 HISTOGRAM_LEVEL_SPARSE_DIAGNOSTIC_TYPES) 38 reserved_infos.GPUS.name,
eakuefner 2017/08/18 23:32:21 GPUs we may have to double-check -- I think the in
39 reserved_infos.MEMORY_AMOUNTS.name,
40 reserved_infos.PRODUCT_VERSIONS.name,
41 reserved_infos.RELATED_NAMES.name,
42 reserved_infos.STORIES.name,
43 reserved_infos.STORYSET_REPEATS.name,
44 reserved_infos.STORY_TAGS.name,
45 ])
46
47 SPARSE_DIAGNOSTIC_NAMES = SUITE_LEVEL_SPARSE_DIAGNOSTIC_NAMES.union(
48 HISTOGRAM_LEVEL_SPARSE_DIAGNOSTIC_NAMES)
40 49
41 50
42 TASK_QUEUE_NAME = 'histograms-queue' 51 TASK_QUEUE_NAME = 'histograms-queue'
43 52
44 53
45 def _CheckRequest(condition, msg): 54 def _CheckRequest(condition, msg):
46 if not condition: 55 if not condition:
47 raise api_request_handler.BadRequestError(msg) 56 raise api_request_handler.BadRequestError(msg)
48 57
49 58
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 for hist in histograms: 93 for hist in histograms:
85 for name, diag in hist.diagnostics.iteritems(): 94 for name, diag in hist.diagnostics.iteritems():
86 if name in SUITE_LEVEL_SPARSE_DIAGNOSTIC_NAMES: 95 if name in SUITE_LEVEL_SPARSE_DIAGNOSTIC_NAMES:
87 if diagnostic_names_added.get(name) is None: 96 if diagnostic_names_added.get(name) is None:
88 diagnostic_names_added[name] = diag.guid 97 diagnostic_names_added[name] = diag.guid
89 98
90 if diagnostic_names_added.get(name) != diag.guid: 99 if diagnostic_names_added.get(name) != diag.guid:
91 raise ValueError( 100 raise ValueError(
92 name + ' diagnostics must be the same for all histograms') 101 name + ' diagnostics must be the same for all histograms')
93 102
94 if (name in SUITE_LEVEL_SPARSE_DIAGNOSTIC_NAMES or 103 if name in SUITE_LEVEL_SPARSE_DIAGNOSTIC_NAMES:
95 type(diag) in SUITE_LEVEL_SPARSE_DIAGNOSTIC_TYPES):
96 suite_level_sparse_diagnostic_entities.append( 104 suite_level_sparse_diagnostic_entities.append(
97 histogram.SparseDiagnostic( 105 histogram.SparseDiagnostic(
98 id=diag.guid, data=diag.AsDict(), test=suite_key, 106 id=diag.guid, data=diag.AsDict(), test=suite_key,
99 start_revision=revision, end_revision=sys.maxint, name=name)) 107 start_revision=revision, end_revision=sys.maxint, name=name))
100 108
101 # TODO(eakuefner): Refactor master/bot computation to happen above this line 109 # TODO(eakuefner): Refactor master/bot computation to happen above this line
102 # so that we can replace with a DiagnosticRef rather than a full diagnostic. 110 # so that we can replace with a DiagnosticRef rather than a full diagnostic.
103 new_guids_to_old_diagnostics = DeduplicateAndPut( 111 new_guids_to_old_diagnostics = DeduplicateAndPut(
104 suite_level_sparse_diagnostic_entities, suite_key, revision) 112 suite_level_sparse_diagnostic_entities, suite_key, revision)
105 for new_guid, old_diagnostic in new_guids_to_old_diagnostics.iteritems(): 113 for new_guid, old_diagnostic in new_guids_to_old_diagnostics.iteritems():
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 176
169 177
170 def _IsDifferent(diagnostic_a, diagnostic_b): 178 def _IsDifferent(diagnostic_a, diagnostic_b):
171 return (diagnostic.Diagnostic.FromDict(diagnostic_a) != 179 return (diagnostic.Diagnostic.FromDict(diagnostic_a) !=
172 diagnostic.Diagnostic.FromDict(diagnostic_b)) 180 diagnostic.Diagnostic.FromDict(diagnostic_b))
173 181
174 182
175 def FindHistogramLevelSparseDiagnostics(guid, histograms): 183 def FindHistogramLevelSparseDiagnostics(guid, histograms):
176 hist = histograms.LookupHistogram(guid) 184 hist = histograms.LookupHistogram(guid)
177 diagnostics = [] 185 diagnostics = []
178 for diag in hist.diagnostics.itervalues(): 186 for name, diag in hist.diagnostics.iteritems():
179 if type(diag) in HISTOGRAM_LEVEL_SPARSE_DIAGNOSTIC_TYPES: 187 if name in HISTOGRAM_LEVEL_SPARSE_DIAGNOSTIC_NAMES:
180 diagnostics.append(diag) 188 diagnostics.append(diag)
181 return diagnostics 189 return diagnostics
182 190
183 191
184 def GetSuiteKey(histograms): 192 def GetSuiteKey(histograms):
185 assert len(histograms) > 0 193 assert len(histograms) > 0
186 # TODO(eakuefner): Refactor this to coalesce the boilerplate (note that this 194 # TODO(eakuefner): Refactor this to coalesce the boilerplate (note that this
187 # is all also being done in add_histograms_queue's post handler) 195 # is all also being done in add_histograms_queue's post handler)
188 master, bot, benchmark = _GetMasterBotBenchmarkFromHistogram( 196 master, bot, benchmark = _GetMasterBotBenchmarkFromHistogram(
189 histograms.GetFirstHistogram()) 197 histograms.GetFirstHistogram())
190 bot_whitelist = stored_object.Get(add_point_queue.BOT_WHITELIST_KEY) 198 bot_whitelist = stored_object.Get(add_point_queue.BOT_WHITELIST_KEY)
191 internal_only = add_point_queue.BotInternalOnly(bot, bot_whitelist) 199 internal_only = add_point_queue.BotInternalOnly(bot, bot_whitelist)
192 return add_point_queue.GetOrCreateAncestors( 200 return add_point_queue.GetOrCreateAncestors(
193 master, bot, benchmark, internal_only).key 201 master, bot, benchmark, internal_only).key
194 202
195 203
196 def ComputeTestPath(guid, histograms): 204 def ComputeTestPath(guid, histograms):
197 hist = histograms.LookupHistogram(guid) 205 hist = histograms.LookupHistogram(guid)
198 suite_path = '%s/%s/%s' % _GetMasterBotBenchmarkFromHistogram(hist) 206 suite_path = '%s/%s/%s' % _GetMasterBotBenchmarkFromHistogram(hist)
199 telemetry_info = hist.diagnostics[reserved_infos.TELEMETRY.name]
200 story_display_name = telemetry_info.story_display_name
201
202 path = '%s/%s' % (suite_path, hist.name) 207 path = '%s/%s' % (suite_path, hist.name)
203 208
204 if story_display_name != '': 209 story_name = hist.diagnostics.get(reserved_infos.STORIES.name)
205 path += '/%s' % story_display_name 210 if story_name and len(story_name) == 1:
211 path += '/' + list(story_name)[0]
eakuefner 2017/08/18 23:32:21 Can we have GenericSet.GetOnlyElement?
206 212
207 return path 213 return path
208 214
209 215
210 def _GetMasterBotBenchmarkFromHistogram(hist): 216 def _GetMasterBotBenchmarkFromHistogram(hist):
211 _CheckRequest(reserved_infos.BUILDBOT.name in hist.diagnostics,
212 'Histograms must have BuildbotInfo attached')
213 buildbot_info = hist.diagnostics[reserved_infos.BUILDBOT.name]
214 _CheckRequest( 217 _CheckRequest(
215 reserved_infos.TELEMETRY.name in hist.diagnostics, 218 reserved_infos.MASTERS.name in hist.diagnostics,
216 'Histograms must have TelemetryInfo attached') 219 'Histograms must have "%s" diagnostic' % reserved_infos.MASTERS.name)
217 telemetry_info = hist.diagnostics[reserved_infos.TELEMETRY.name] 220 master = hist.diagnostics[reserved_infos.MASTERS.name]
221 _CheckRequest(
222 len(master) == 1,
223 'Histograms must have exactly 1 "%s"' % reserved_infos.MASTERS.name)
224 master = list(master)[0]
218 225
219 master = buildbot_info.display_master_name 226 _CheckRequest(
220 bot = buildbot_info.display_bot_name 227 reserved_infos.BOTS.name in hist.diagnostics,
221 benchmark = telemetry_info.benchmark_name 228 'Histograms must have "%s" diagnostic' % reserved_infos.BOTS.name)
229 bot = hist.diagnostics[reserved_infos.BOTS.name]
230 _CheckRequest(
231 len(bot) == 1,
232 'Histograms must have exactly 1 "%s"' % reserved_infos.BOTS.name)
eakuefner 2017/08/18 23:32:21 We may need to revisit this in the per-story shard
233 bot = list(bot)[0]
234
235 _CheckRequest(
236 reserved_infos.BENCHMARKS.name in hist.diagnostics,
237 'Histograms must have "%s" diagnostic' % reserved_infos.BENCHMARKS.name)
238 benchmark = hist.diagnostics[reserved_infos.BENCHMARKS.name]
239 _CheckRequest(
240 len(benchmark) == 1,
241 'Histograms must have exactly 1 "%s"' % reserved_infos.BENCHMARKS.name)
242 benchmark = list(benchmark)[0]
222 243
223 return master, bot, benchmark 244 return master, bot, benchmark
224 245
225 246
226 def ComputeRevision(histograms): 247 def ComputeRevision(histograms):
227 _CheckRequest(len(histograms) > 0, 'Must upload at least one histogram') 248 _CheckRequest(len(histograms) > 0, 'Must upload at least one histogram')
228 diagnostics = histograms.GetFirstHistogram().diagnostics 249 diagnostics = histograms.GetFirstHistogram().diagnostics
229 _CheckRequest(reserved_infos.CHROMIUM_COMMIT_POSITIONS.name in diagnostics, 250 _CheckRequest(reserved_infos.CHROMIUM_COMMIT_POSITIONS.name in diagnostics,
230 'Histograms must have Chromium commit position attached') 251 'Histograms must have Chromium commit position attached')
231 chromium_commit_position = list(diagnostics[ 252 chromium_commit_position = list(diagnostics[
232 reserved_infos.CHROMIUM_COMMIT_POSITIONS.name]) 253 reserved_infos.CHROMIUM_COMMIT_POSITIONS.name])
233 254
234 _CheckRequest(len(chromium_commit_position) == 1, 255 _CheckRequest(len(chromium_commit_position) == 1,
235 'Chromium commit position must have 1 value') 256 'Chromium commit position must have 1 value')
236 257
237 # TODO(eakuefner): Allow users to specify other types of revisions to be used 258 # TODO(eakuefner): Allow users to specify other types of revisions to be used
238 # for computing revisions of dashboard points. See 259 # for computing revisions of dashboard points. See
239 # https://github.com/catapult-project/catapult/issues/3623. 260 # https://github.com/catapult-project/catapult/issues/3623.
240 return chromium_commit_position[0] 261 return chromium_commit_position[0]
241 262
242 263
243 def InlineDenseSharedDiagnostics(histograms): 264 def InlineDenseSharedDiagnostics(histograms):
244 # TODO(eakuefner): Delete inlined diagnostics from the set 265 # TODO(eakuefner): Delete inlined diagnostics from the set
245 for hist in histograms: 266 for hist in histograms:
246 diagnostics = hist.diagnostics 267 diagnostics = hist.diagnostics
247 for name, diag in diagnostics.iteritems(): 268 for name, diag in diagnostics.iteritems():
248 if (type(diag) not in SPARSE_DIAGNOSTIC_TYPES and 269 if name not in SPARSE_DIAGNOSTIC_NAMES:
249 name not in SUITE_LEVEL_SPARSE_DIAGNOSTIC_NAMES):
250 diag.Inline() 270 diag.Inline()
OLDNEW
« no previous file with comments | « no previous file | dashboard/dashboard/add_histograms_queue_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698