def _GetAllTimelineBasedMetrics(): # TODO(nednguyen): use discovery pattern to return all the instances of # all TimelineBasedMetrics class in web_perf/metrics/ folder. # This cannot be done until crbug.com/460208 is fixed. return (smoothness.SmoothnessMetric(), responsiveness_metric.ResponsivenessMetric(), layout.LayoutMetric(), gpu_timeline.GPUTimelineMetric())
def Main(args): if len(args) is not 1: print 'Invalid arguments. Usage: measure_trace.py <trace file>' return 1 with open(args[0]) as trace_file: trace_data = tracing_timeline_data.TracingTimelineData( json.load(trace_file)) timeline_model = model.TimelineModel(trace_data) smoothness_metric = smoothness.SmoothnessMetric() formatters = [ buildbot_output_formatter.BuildbotOutputFormatter(sys.stdout) ] results = page_test_results.PageTestResults(output_formatters=formatters) for thread in timeline_model.GetAllThreads(): interaction_records = _ExtractInteractionsRecordFromThread( thread, timeline_model) if not any(interaction_records): continue records_label_to_records_map = collections.defaultdict(list) for r in interaction_records: records_label_to_records_map[r.label].append(r) for label, records in records_label_to_records_map.iteritems(): if records[0].is_smooth: page = page_module.Page('interaction-record://%s' % label) results.WillRunPage(page) smoothness_metric.AddResults(timeline_model, thread, records, results) results.DidRunPage(page) results.PrintSummary() return 0
def ValidateAndMeasurePage(self, _, tab, results): self._results = results trace_result = tab.browser.platform.tracing_controller.StopTracing() # TODO(charliea): This is part of a three-sided Chromium/Telemetry patch # where we're changing the return type of StopTracing from a TraceValue to a # (TraceValue, nonfatal_exception_list) tuple. Once the tuple return value # lands in Chromium, the non-tuple logic should be deleted. if isinstance(trace_result, tuple): trace_result = trace_result[0] trace_value = trace.TraceValue( results.current_page, trace_result, file_path=results.telemetry_info.trace_local_path, remote_path=results.telemetry_info.trace_remote_path, upload_bucket=results.telemetry_info.upload_bucket, cloud_url=results.telemetry_info.trace_remote_url) results.AddValue(trace_value) model = model_module.TimelineModel(trace_result) renderer_thread = model.GetRendererThreadFromTabId(tab.id) records = _CollectRecordsFromRendererThreads(model, renderer_thread) smoothness_metric = smoothness.SmoothnessMetric() smoothness_metric.AddResults(model, renderer_thread, records, results) thread_times_metric = timeline.ThreadTimesTimelineMetric() thread_times_metric.AddResults(model, renderer_thread, records, results)
def CreateMetricsForTimelineInteractionRecord(self, interaction): """ Subclass of TimelineBasedMeasurement overrides this method to customize the binding of interaction's flags to metrics. """ res = [] if interaction.is_smooth: res.append(smoothness.SmoothnessMetric()) return res
def _GetAllLegacyTimelineBasedMetrics(): # TODO(nednguyen): use discovery pattern to return all the instances of # all TimelineBasedMetrics class in web_perf/metrics/ folder. # This cannot be done until crbug.com/460208 is fixed. return (smoothness.SmoothnessMetric(), layout.LayoutMetric(), blob_timeline.BlobTimelineMetric(), indexeddb_timeline.IndexedDBTimelineMetric(), webrtc_rendering_timeline.WebRtcRenderingTimelineMetric())
def _GetMetricFromMetricType(metric_type): if metric_type == tir_module.IS_FAST: return fast_metric.FastMetric() if metric_type == tir_module.IS_SMOOTH: return smoothness.SmoothnessMetric() if metric_type == tir_module.IS_RESPONSIVE: return responsiveness_metric.ResponsivenessMetric() raise Exception('Unrecognized metric type: %s' % metric_type)
def _GetAllTimelineBasedMetrics(): # TODO(nednguyen): use discovery pattern to return all the instances of # all TimelineBasedMetrics class in web_perf/metrics/ folder. # This cannot be done until crbug.com/460208 is fixed. return (smoothness.SmoothnessMetric(), responsiveness_metric.ResponsivenessMetric(), layout.LayoutMetric(), gpu_timeline.GPUTimelineMetric(), blob_timeline.BlobTimelineMetric(), memory_timeline.MemoryTimelineMetric(), text_selection.TextSelectionMetric(), indexeddb_timeline.IndexedDBTimelineMetric(), webrtc_rendering_timeline.WebRtcRenderingTimelineMetric())
def testTimelineBasedMeasurementGestureAdjustmentSmoke(self): ps = self.CreateEmptyPageSet() ps.AddStory(TestTimelinebasedMeasurementPage( ps, ps.base_dir, trigger_scroll_gesture=True)) options = tbm_module.Options() options.SetLegacyTimelineBasedMetrics([smoothness.SmoothnessMetric()]) tbm = tbm_module.TimelineBasedMeasurement(options) results = self.RunMeasurement(tbm, ps, options=self._options) self.assertEquals(0, len(results.failures)) v = results.FindAllPageSpecificValuesFromIRNamed( 'Gesture_Scroll', 'frame_time_discrepancy') self.assertEquals(len(v), 1)
def AddResults(self, tab, results): # Add results of smoothness metric. This computes the smoothness metric for # the time ranges of gestures, if there is at least one, else the the time # ranges from the first action to the last action. renderer_thread = self._timeline_model.GetRendererThreadFromTabId( tab.id) run_smooth_actions_record = None smooth_records = [] for event in renderer_thread.async_slices: if not tir_module.IsTimelineInteractionRecord(event.name): continue r = tir_module.TimelineInteractionRecord.FromAsyncEvent(event) if r.logical_name == RUN_SMOOTH_ACTIONS: assert run_smooth_actions_record is None, ( 'SmoothnessController cannot issue more than 1 %s record' % RUN_SMOOTH_ACTIONS) run_smooth_actions_record = r elif r.is_smooth: smooth_records.append( smooth_gesture_util.GetAdjustedInteractionIfContainGesture( self._timeline_model, r)) # If there is no other smooth records, we make measurements on time range # marked smoothness_controller itself. # TODO(nednguyen): when crbug.com/239179 is marked fixed, makes sure that # page sets are responsible for issueing the markers themselves. if len(smooth_records) == 0: if run_smooth_actions_record is None: sys.stderr.write('Raw tracing data:\n') sys.stderr.write(repr(self._tracing_timeline_data.EventData())) sys.stderr.write('\n') raise Exception( 'SmoothnessController failed to issue markers for the ' 'whole interaction.') else: smooth_records = [run_smooth_actions_record] # Create an interaction_record for this legacy measurement. Since we don't # wrap the results that is sent to smoothnes metric, the logical_name will # not be used. smoothness_metric = smoothness.SmoothnessMetric() smoothness_metric.AddResults(self._timeline_model, renderer_thread, smooth_records, results) if tab.browser.platform.IsRawDisplayFrameRateSupported(): for r in tab.browser.platform.GetRawDisplayFrameRateMeasurements(): if r.value is None: raise MissingDisplayFrameRateError(r.name) results.Add(r.name, r.unit, r.value)
def CreateTimelineBasedMeasurementOptions(self): v8_gc_latency_categories = [ 'blink.console', 'renderer.scheduler', 'v8', 'webkit.console'] smoothness_categories = [ 'webkit.console', 'blink.console', 'benchmark', 'trace_event_overhead'] categories = list(set(v8_gc_latency_categories + smoothness_categories)) memory_categories = 'blink.console,disabled-by-default-memory-infra' category_filter = tracing_category_filter.TracingCategoryFilter( memory_categories) for category in categories: category_filter.AddIncludedCategory(category) options = timeline_based_measurement.Options(category_filter) options.SetTimelineBasedMetrics([v8_gc_latency.V8GCLatency(), smoothness.SmoothnessMetric(), memory_timeline.MemoryTimelineMetric()]) return options
def WillNavigateToPage(self, page, tab): # FIXME: Remove webkit.console when blink.console lands in chromium and # the ref builds are updated. crbug.com/386847 custom_categories = [ 'webkit.console', 'blink.console', 'benchmark', 'trace_event_overhead' ] category_filter = chrome_trace_category_filter.ChromeTraceCategoryFilter( ','.join(custom_categories)) options = timeline_based_measurement.Options(category_filter) options.config.enable_platform_display_trace = True options.SetLegacyTimelineBasedMetrics([smoothness.SmoothnessMetric()]) self._tbm = timeline_based_measurement.TimelineBasedMeasurement( options, self._results_wrapper) self._tbm.WillRunStory(tab.browser.platform)
def ValidateAndMeasurePage(self, _, tab, results): self._results = results trace_result = tab.browser.platform.tracing_controller.StopTracing()[0] trace_value = trace.TraceValue( results.current_page, trace_result, file_path=results.telemetry_info.trace_local_path, remote_path=results.telemetry_info.trace_remote_path, upload_bucket=results.telemetry_info.upload_bucket, cloud_url=results.telemetry_info.trace_remote_url) results.AddValue(trace_value) model = model_module.TimelineModel(trace_result) renderer_thread = model.GetRendererThreadFromTabId(tab.id) records = _CollectRecordsFromRendererThreads(model, renderer_thread) metric = smoothness.SmoothnessMetric() metric.AddResults(model, renderer_thread, records, results)
def ValidateAndMeasurePage(self, _, tab, results): self._results = results tab.browser.platform.tracing_controller.telemetry_info = ( results.telemetry_info) trace_result = tab.browser.platform.tracing_controller.StopTracing() # TODO(charliea): This is part of a three-sided Chromium/Telemetry patch # where we're changing the return type of StopTracing from a TraceValue to a # (TraceValue, nonfatal_exception_list) tuple. Once the tuple return value # lands in Chromium, the non-tuple logic should be deleted. if isinstance(trace_result, tuple): trace_result = trace_result[0] trace_value = trace.TraceValue( results.current_page, trace_result, file_path=results.telemetry_info.trace_local_path, remote_path=results.telemetry_info.trace_remote_path, upload_bucket=results.telemetry_info.upload_bucket, cloud_url=results.telemetry_info.trace_remote_url) results.AddValue(trace_value) model = model_module.TimelineModel(trace_result) renderer_thread = model.GetFirstRendererThread(tab.id) records = _CollectRecordsFromRendererThreads(model, renderer_thread) smoothness_metric = smoothness.SmoothnessMetric() smoothness_metric.AddResults(model, renderer_thread, records, results) thread_times_metric = timeline.ThreadTimesTimelineMetric() thread_times_metric.AddResults(model, renderer_thread, records, results) # TBMv2 metrics. mre_result = metric_runner.RunMetric( trace_value.filename, metrics=['renderingMetric'], extra_import_options={'trackDetailedModelStats': True}, report_progress=False, canonical_url=results.telemetry_info.trace_url) for f in mre_result.failures: results.Fail(f.stack) results.ImportHistogramDicts(mre_result.pairs.get('histograms', []), import_immediately=False)
def WillNavigateToPage(self, page, tab): # FIXME: Remove webkit.console when blink.console lands in chromium and # the ref builds are updated. crbug.com/386847 custom_categories = [ 'webkit.console', 'blink.console', 'benchmark', 'trace_event_overhead' ] category_filter = tracing_category_filter.TracingCategoryFilter( ','.join(custom_categories)) options = timeline_based_measurement.Options(category_filter) options.SetLegacyTimelineBasedMetrics([smoothness.SmoothnessMetric()]) for delay in page.GetSyntheticDelayCategories(): options.category_filter.AddSyntheticDelay(delay) self._tbm = timeline_based_measurement.TimelineBasedMeasurement( options, self._results_wrapper) self._tbm.WillRunStory(tab.browser.platform)
def AddResults(self, tab, results): # Add results of smoothness metric. This computes the smoothness metric for # the time ranges of gestures, if there is at least one, else the the time # ranges from the first action to the last action. results.AddValue( trace.TraceValue(results.current_page, self._trace_data)) renderer_thread = self._timeline_model.GetRendererThreadFromTabId( tab.id) smooth_records = [] for event in renderer_thread.async_slices: if not tir_module.IsTimelineInteractionRecord(event.name): continue r = tir_module.TimelineInteractionRecord.FromAsyncEvent(event) smooth_records.append( smooth_gesture_util.GetAdjustedInteractionIfContainGesture( self._timeline_model, r)) # If there is no other smooth records, we make measurements on time range # marked smoothness_controller itself. # TODO(nednguyen): when crbug.com/239179 is marked fixed, makes sure that # page sets are responsible for issueing the markers themselves. if len(smooth_records) == 0: raise page_test.Failure('Page failed to issue any markers.') # Check to make sure all smooth records have same label and repeatable if # there are more than one. need_repeatable_flag = len(smooth_records) > 1 record_label = smooth_records[0].label for r in smooth_records: if r.label != record_label: raise page_test.Failure( 'SmoothController does not support multiple interactions with ' 'different label. Interactions: %s' % repr(smooth_records)) if need_repeatable_flag and not r.repeatable: raise page_test.Failure( 'If there are more than one interaction record, each interaction ' 'must has repeatable flag. Interactions: %s' % repr(smooth_records)) # Create an interaction_record for this legacy measurement. Since we don't # wrap the results that are sent to smoothness metric, the label will # not be used. smoothness_metric = smoothness.SmoothnessMetric() smoothness_metric.AddResults(self._timeline_model, renderer_thread, smooth_records, results)
def testSmoothnessTimelineBasedMeasurementForSmoke(self): ps = self.CreateEmptyPageSet() ps.AddStory( TestTimelinebasedMeasurementPage(ps, ps.base_dir, trigger_animation=True)) options = tbm_module.Options() options.SetLegacyTimelineBasedMetrics([smoothness.SmoothnessMetric()]) tbm = tbm_module.TimelineBasedMeasurement(options) results = self.RunMeasurement(tbm, ps, options=self._options) self.assertFalse(results.had_failures) v = results.FindAllPageSpecificValuesFromIRNamed( 'CenterAnimation', 'frame_time_discrepancy') self.assertEquals(len(v), 1) v = results.FindAllPageSpecificValuesFromIRNamed( 'DrawerAnimation', 'frame_time_discrepancy') self.assertEquals(len(v), 1)
def setUp(self): self.metric = smoothness.SmoothnessMetric() self.page = page_module.Page('file://blank.html') self.good_timestamps = [[10, 20], [30, 40, 50]] self.not_enough_frames_timestamps = [[10], [20, 30, 40]]
def _GetAllLegacyTimelineBasedMetrics(): # TODO(nednguyen): use discovery pattern to return all the instances of # all TimelineBasedMetrics class in web_perf/metrics/ folder. # This cannot be done until crbug.com/460208 is fixed. return (smoothness.SmoothnessMetric(), )