1# Copyright 2019 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5from collections import defaultdict 6 7from core import path_util 8path_util.AddTracingToPath() 9from core import perf_benchmark 10 11from contrib.cluster_telemetry import ct_benchmarks_util 12from contrib.cluster_telemetry import page_set as ct_page_set 13import page_sets 14from telemetry import benchmark 15from telemetry import timeline 16from telemetry.page import legacy_page_test 17 18from tracing.trace_data import trace_data as trace_data_module 19 20 21class _GenericTraceMeasurement(legacy_page_test.LegacyPageTest): 22 23 def __init__(self, options): 24 super(_GenericTraceMeasurement, self).__init__() 25 self._trace_categories = ','.join(options.trace_categories) 26 trace_names = ','.join(options.trace_names).split(',') 27 self._trace_names = [name for name in trace_names if name] 28 29 def WillNavigateToPage(self, page, tab): 30 config = timeline.tracing_config.TracingConfig() 31 config.enable_chrome_trace = True 32 config.chrome_trace_config.category_filter.AddFilterString( 33 self._trace_categories) 34 tab.browser.platform.tracing_controller.StartTracing(config) 35 36 def ValidateAndMeasurePage(self, page, tab, results): 37 with tab.browser.platform.tracing_controller.StopTracing() as trace_builder: 38 trace_data = trace_builder.AsData() 39 measurements = defaultdict(list) 40 for trace in trace_data.GetTracesFor(trace_data_module.CHROME_TRACE_PART): 41 for event in trace['traceEvents']: 42 # We collect data from duration begin, complete, instant and count 43 # events. See benchmark documentation for details. 44 if event['ph'] not in ('B', 'X', 'I', 'C'): 45 continue 46 if self._trace_names and event['name'] not in self._trace_names: 47 continue 48 for arg_name, arg_value in event.get('args', {}).iteritems(): 49 if not isinstance(arg_value, int): 50 continue 51 value_name = '/'.join([event['cat'], event['name'], arg_name]) 52 measurements[value_name].append(arg_value) 53 for name, value in measurements.items(): 54 results.AddMeasurement(name, 'count', value) 55 56 57class _GenericTraceBenchmark(perf_benchmark.PerfBenchmark): 58 @classmethod 59 def AddBenchmarkCommandLineArgs(cls, parser): 60 parser.add_option('--trace-categories', default=[], action='append', 61 help='Trace categories to enable') 62 parser.add_option('--trace-names', default=[], action='append', 63 help='Names of trace event to collect ' 64 'If not specified, all trace events in the enabled ' 65 'categories will be collected') 66 67 @classmethod 68 def ProcessCommandLineArgs(cls, parser, args): 69 if not args.trace_categories: 70 parser.error('--trace-categories is required') 71 72 def CreatePageTest(self, options): 73 return _GenericTraceMeasurement(options) 74 75 76@benchmark.Info(emails=['wangxianzhu@chromium.org'], 77 documentation_url='https://bit.ly/2DIOVy3') 78# For local verification. 79class GenericTraceTop25(_GenericTraceBenchmark): 80 page_set = page_sets.StaticTop25PageSet 81 82 @classmethod 83 def Name(cls): 84 return 'generic_trace.top25' 85 86 87@benchmark.Info(emails=['wangxianzhu@chromium.org'], 88 documentation_url='https://bit.ly/2DIOVy3') 89class GenericTraceClusterTelemetry(_GenericTraceBenchmark): 90 @classmethod 91 def Name(cls): 92 return 'generic_trace_ct' 93 94 @classmethod 95 def AddBenchmarkCommandLineArgs(cls, parser): 96 _GenericTraceBenchmark.AddBenchmarkCommandLineArgs(parser) 97 ct_benchmarks_util.AddBenchmarkCommandLineArgs(parser) 98 99 @classmethod 100 def ProcessCommandLineArgs(cls, parser, args): 101 _GenericTraceBenchmark.ProcessCommandLineArgs(parser, args) 102 ct_benchmarks_util.ValidateCommandLineArgs(parser, args) 103 104 def CreateStorySet(self, options): 105 return ct_page_set.CTPageSet( 106 options.urls_list, options.user_agent, options.archive_data_file) 107