def testTracing(self):
    devtools_client = self._devtools_client
    if not devtools_client.IsChromeTracingSupported():
      self.skipTest('Browser does not support tracing, skipping test.')

    # Start Chrome tracing.
    config = tracing_config.TracingConfig()
    config.enable_chrome_trace = True
    devtools_client.StartChromeTracing(config)

    # Stop Chrome tracing and check that the resulting data is valid.
    builder = trace_data.TraceDataBuilder()
    devtools_client.StopChromeTracing()
    devtools_client.CollectChromeTracingData(builder)
    model.TimelineModel(builder.AsData())
Ejemplo n.º 2
0
 def testHighlight(self):
     self.assertEquals(self._tab.url, 'about:blank')
     self._browser.StartTracing(tracing_backend.DEFAULT_TRACE_CATEGORIES)
     self._tab.Highlight(bitmap.WEB_PAGE_TEST_ORANGE)
     self._tab.ClearHighlight(bitmap.WEB_PAGE_TEST_ORANGE)
     trace_data = self._browser.StopTracing()
     timeline_model = model.TimelineModel(trace_data)
     renderer_thread = timeline_model.GetRendererThreadFromTabId(
         self._tab.id)
     found_video_start_event = False
     for event in renderer_thread.async_slices:
         if event.name == '__ClearHighlight.video_capture_start':
             found_video_start_event = True
             break
     self.assertTrue(found_video_start_event)
Ejemplo n.º 3
0
  def testGetFirstRendererThread_singleTab(self):
    self.assertEqual(len(self.tabs), 1)  # We have a single tab/page.
    config = tracing_config.TracingConfig()
    config.chrome_trace_config.SetLowOverheadFilter()
    config.enable_chrome_trace = True
    self._browser.platform.tracing_controller.StartTracing(config)
    self._tab.AddTimelineMarker('single-tab-marker')
    trace_data, errors = self._browser.platform.tracing_controller.StopTracing()
    self.assertEqual(errors, [])
    timeline_model = model.TimelineModel(trace_data)

    # Check that we can find the marker injected into the trace.
    renderer_thread = timeline_model.GetFirstRendererThread(self._tab.id)
    markers = list(renderer_thread.IterTimelineMarkers('single-tab-marker'))
    self.assertEqual(len(markers), 1)
Ejemplo n.º 4
0
 def testStartAndStopTraceMultipleTimes(self):
     tracing_controller = self._browser.platform.tracing_controller
     options = tracing_options.TracingOptions()
     options.enable_chrome_trace = True
     tracing_controller.Start(
         options, tracing_category_filter.TracingCategoryFilter())
     self.assertFalse(
         tracing_controller.Start(
             options, tracing_category_filter.TracingCategoryFilter()))
     trace_data = tracing_controller.Stop()
     # Test that trace data is parsable
     model_module.TimelineModel(trace_data)
     self.assertFalse(tracing_controller.is_tracing_running)
     # Calling stop again will raise exception
     self.assertRaises(Exception, tracing_controller.Stop)
Ejemplo n.º 5
0
 def testImportSamplesMissingArgs(self):
   events = [
       {'name': 'a', 'pid': 52, 'ts': 548, 'cat': 'test',
        'tid': 53, 'ph': 'P'},
       {'name': 'b', 'pid': 52, 'ts': 548, 'cat': 'test',
        'tid': 53, 'ph': 'P'},
       {'name': 'c', 'pid': 52, 'ts': 549, 'cat': 'test',
        'tid': 53, 'ph': 'P'}
   ]
   trace_data = trace_data_module.CreateFromRawChromeEvents(events)
   m = timeline_model.TimelineModel(trace_data)
   p = m.GetAllProcesses()[0]
   t = p.threads[53]
   self.assertEqual(3, len(t.samples))
   self.assertEqual(0, len(m.import_errors))
Ejemplo n.º 6
0
  def testImportErrornousFlowEvent(self):
    events = [
        {'name': 'a', 'cat': 'foo', 'id': 70, 'pid': 52, 'tid': 53, 'ts': 548,
         'ph': 's', 'args': {}},
        {'name': 'a2', 'cat': 'foo', 'id': 70, 'pid': 52, 'tid': 53, 'ts': 550,
         'ph': 's', 'args': {}},
        {'name': 'b', 'cat': 'foo', 'id': 73, 'pid': 52, 'tid': 53, 'ts': 570,
         'ph': 'f', 'args': {}},
        {'name': 'a', 'cat': 'foo', 'id': 72, 'pid': 52, 'tid': 53, 'ts': 560,
         'ph': 't', 'args': {}},
    ]

    trace_data = trace_data_module.CreateFromRawChromeEvents(events)
    m = timeline_model.TimelineModel(trace_data)
    self.assertEqual(0, len(m.flow_events))
Ejemplo n.º 7
0
 def testImport(self):
     messages = [_BACKGROUND_MESSAGE, _SAMPLE_MESSAGE]
     timeline_data = inspector_timeline_data.InspectorTimelineData(messages)
     m = model.TimelineModel(timeline_data=timeline_data,
                             shift_world_to_zero=False)
     self.assertEquals(1, len(m.processes))
     process = m.processes.values()[0]
     threads = process.threads
     self.assertEquals(2, len(threads))
     renderer_thread = threads[0]
     self.assertEquals(1, len(renderer_thread.toplevel_slices))
     self.assertEquals('Program', renderer_thread.toplevel_slices[0].name)
     second_thread = threads['2']
     self.assertEquals(1, len(second_thread.toplevel_slices))
     self.assertEquals('BeginFrame', second_thread.toplevel_slices[0].name)
Ejemplo n.º 8
0
 def testImport(self):
     builder = trace_data.TraceDataBuilder()
     builder.AddEventsTo(trace_data.INSPECTOR_TRACE_PART,
                         [_BACKGROUND_MESSAGE, _SAMPLE_MESSAGE])
     m = model.TimelineModel(builder.AsData(), shift_world_to_zero=False)
     self.assertEquals(1, len(m.processes))
     process = m.processes.values()[0]
     threads = process.threads
     self.assertEquals(2, len(threads))
     renderer_thread = threads[0]
     self.assertEquals(1, len(renderer_thread.toplevel_slices))
     self.assertEquals('Program', renderer_thread.toplevel_slices[0].name)
     second_thread = threads['2']
     self.assertEquals(1, len(second_thread.toplevel_slices))
     self.assertEquals('BeginFrame', second_thread.toplevel_slices[0].name)
Ejemplo n.º 9
0
    def ValidateAndMeasurePage(self, page, tab, results):
        trace_cpu_time_metrics = {}
        if tab.EvaluateJavaScript('testRunner.tracingCategories'):
            trace_data = tab.browser.platform.tracing_controller.StopTracing(
            )[0]
            # TODO(#763375): Rely on results.telemetry_info.trace_local_path/etc.
            kwargs = {}
            if hasattr(results.telemetry_info, 'trace_local_path'):
                kwargs['file_path'] = results.telemetry_info.trace_local_path
                kwargs[
                    'remote_path'] = results.telemetry_info.trace_remote_path
                kwargs['upload_bucket'] = results.telemetry_info.upload_bucket
                kwargs['cloud_url'] = results.telemetry_info.trace_remote_url
            trace_value = trace.TraceValue(page, trace_data, **kwargs)
            results.AddValue(trace_value)

            trace_events_to_measure = tab.EvaluateJavaScript(
                'window.testRunner.traceEventsToMeasure')
            model = model_module.TimelineModel(trace_data)
            renderer_thread = model.GetRendererThreadFromTabId(tab.id)
            trace_cpu_time_metrics = _ComputeTraceEventsThreadTimeForBlinkPerf(
                model, renderer_thread, trace_events_to_measure)

        log = tab.EvaluateJavaScript(
            'document.getElementById("log").innerHTML')

        for line in log.splitlines():
            if line.startswith("FATAL: "):
                print line
                continue
            if not line.startswith('values '):
                continue
            parts = line.split()
            values = [float(v.replace(',', '')) for v in parts[1:-1]]
            units = parts[-1]
            metric = page.name.split('.')[0].replace('/', '_')
            if values:
                results.AddValue(
                    list_of_scalar_values.ListOfScalarValues(
                        results.current_page, metric, units, values))
            else:
                raise legacy_page_test.MeasurementFailure('Empty test results')

            break

        print log

        self.PrintAndCollectTraceEventMetrics(trace_cpu_time_metrics, results)
Ejemplo n.º 10
0
    def testDumpMemorySuccess(self):
        # Check that dumping memory before tracing starts raises an exception.
        self.assertRaises(Exception, self._browser.DumpMemory)

        # Start tracing with memory dumps enabled.
        config = tracing_config.TracingConfig()
        config.chrome_trace_config.category_filter.AddDisabledByDefault(
            'disabled-by-default-memory-infra')
        config.chrome_trace_config.SetMemoryDumpConfig(
            chrome_trace_config.MemoryDumpConfig())
        config.enable_chrome_trace = True
        self._tracing_controller.StartTracing(config)

        # Request several memory dumps in a row and test that they were all
        # successfully created with unique IDs.
        expected_dump_ids = []
        for _ in xrange(self._REQUESTED_DUMP_COUNT):
            dump_id = self._browser.DumpMemory()
            self.assertIsNotNone(dump_id)
            self.assertNotIn(dump_id, expected_dump_ids)
            expected_dump_ids.append(dump_id)

        tracing_data = self._tracing_controller.StopTracing()

        # Check that clock sync data is in tracing data.
        clock_sync_found = False
        trace_handles = tracing_data.GetTracesFor(trace_data.CHROME_TRACE_PART)
        self.assertEqual(len(trace_handles), 1)
        with open(trace_handles[0].file_path) as f:
            trace = json.load(f)
        for event in trace['traceEvents']:
            if event['name'] == 'clock_sync' or 'ClockSyncEvent' in event[
                    'name']:
                clock_sync_found = True
                break
        self.assertTrue(clock_sync_found)

        # Check that dumping memory after tracing stopped raises an exception.
        self.assertRaises(Exception, self._browser.DumpMemory)

        # Test that trace data is parsable.
        model = model_module.TimelineModel(tracing_data)
        self.assertGreater(len(model.processes), 0)

        # Test that the resulting model contains the requested memory dumps in the
        # correct order (and nothing more).
        actual_dump_ids = [d.dump_id for d in model.IterGlobalMemoryDumps()]
        self.assertEqual(actual_dump_ids, expected_dump_ids)
Ejemplo n.º 11
0
    def testBothDrmAndDisplayStats(self):
        timeline = model.TimelineModel()
        timer = MockTimer()
        vblank_timer = MockVblankTimer()

        ref_stats = ReferenceRenderingStats()
        ref_stats.AppendNewRange()
        gpu = timeline.GetOrCreateProcess(pid=6)
        gpu.name = 'GPU Process'
        gpu_drm_thread = gpu.GetOrCreateThread(tid=61)
        renderer = timeline.GetOrCreateProcess(pid=2)
        browser = timeline.GetOrCreateProcess(pid=3)
        browser_main = browser.GetOrCreateThread(tid=31)
        browser_main.BeginSlice('webkit.console', 'ActionA',
                                timer.AdvanceAndGet(2, 4), '')
        vblank_timer.TvAdvance(2000, 4000)

        # Create drm flip stats and display rendering stats.
        for i in xrange(0, 10):
            first = (i == 0)
            AddDrmEventFlipStats(timer, vblank_timer, gpu_drm_thread, first,
                                 ref_stats)
            timer.Advance(2, 4)
            vblank_timer.TvAdvance(2000, 4000)

        for i in xrange(0, 10):
            first = (i == 0)
            AddDisplayRenderingStats(timer, browser_main, first, None)
            timer.Advance(5, 10)
            vblank_timer.TvAdvance(5000, 10000)

        browser_main.EndSlice(timer.AdvanceAndGet())
        timer.Advance(2, 4)
        vblank_timer.TvAdvance(2000, 4000)

        browser.FinalizeImport()
        renderer.FinalizeImport()
        timeline_markers = timeline.FindTimelineMarkers(['ActionA'])
        records = [
            tir_module.TimelineInteractionRecord(e.name, e.start, e.end)
            for e in timeline_markers
        ]
        stats = rendering_stats.RenderingStats(renderer, browser, gpu, records)

        # Compare rendering stats to reference - Only drm flip stats should
        # count
        self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps)
        self.assertEquals(stats.frame_times, ref_stats.frame_times)
Ejemplo n.º 12
0
 def testBrowserProcess(self):
   trace = trace_data.CreateFromRawChromeEvents([
       {
           "name": "process_name",
           "args": {"name": "Browser"},
           "pid": 5,
           "ph": "M"
       }, {
           "name": "thread_name",
           "args": {"name": "CrBrowserMain"},
           "pid": 5,
           "tid": 32578,
           "ph": "M"
       }])
   model = timeline_model.TimelineModel(trace)
   self.assertEquals(5, model.browser_process.pid)
Ejemplo n.º 13
0
  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)
Ejemplo n.º 14
0
    def __init__(self, options):
        self._model = model_module.TimelineModel()
        renderer_process = self._model.GetOrCreateProcess(1)
        self._renderer_thread = renderer_process.GetOrCreateThread(2)
        self._renderer_thread.name = 'CrRendererMain'
        self._foo_thread = renderer_process.GetOrCreateThread(3)
        self._foo_thread.name = 'CrFoo'

        self._results_wrapper = tbm_module._TBMResultWrapper()
        self._results = page_test_results.PageTestResults()
        self._results.telemetry_info.benchmark_name = 'benchmark'
        self._results.telemetry_info.benchmark_start_epoch = 123
        self._results.telemetry_info.benchmark_descriptions = 'foo'
        self._story_set = None
        self._threads_to_records_map = None
        self._tbm_options = options
  def testImportStringWithMissingCloseSquareBracketAndNewline(self):
    events = [
      {'name': 'a', 'args': {}, 'pid': 52, 'ts': 524, 'cat': 'foo',
       'tid': 53, 'ph': 'B'},
      {'name': 'a', 'args': {}, 'pid': 52, 'ts': 560, 'cat': 'foo',
       'tid': 53, 'ph': 'E'}
    ]

    tmp = json.dumps(events)
    self.assertEqual(']', tmp[-1])

    # Drop off the trailing ] and add a newline
    dropped = tmp[:-1]
    timeline_data = tracing_timeline_data.TracingTimelineData(dropped + '\n')
    m = timeline_model.TimelineModel(timeline_data=timeline_data)
    self.assertEqual(1, len(m.GetAllProcesses()))
Ejemplo n.º 16
0
    def ValidateAndMeasurePage(self, page, tab, results):
        del page  # unused
        timeline_data = tab.browser.platform.tracing_controller.StopTracing()
        timeline_model = model.TimelineModel(timeline_data)

        pt_avg = self.ComputeAverageOfDurations(
            timeline_model,
            'LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees')

        results.AddValue(
            scalar.ScalarValue(
                results.current_page,
                'PT_avg_cost',
                'ms',
                pt_avg,
                description='Average time spent processing property trees'))
Ejemplo n.º 17
0
  def StopTimelineRecording(self):
    builder = trace_data_module.TraceDataBuilder()

    data = self._timeline.Stop()
    if data:
      builder.AddEventsTo(trace_data_module.INSPECTOR_TRACE_PART, data)

    data = self._network.timeline_recorder.Stop()
    if data:
      builder.AddEventsTo(trace_data_module.INSPECTOR_TRACE_PART, data)

    if builder.HasEventsFor(trace_data_module.INSPECTOR_TRACE_PART):
      self._timeline_model = timeline_model_module.TimelineModel(
          builder.AsData(), shift_world_to_zero=False)
    else:
      self._timeline_model = None
  def testArgumentDupeCreatesNonFailingImportError(self):
    events = [
        {'name': 'a', 'args': {'x': 1}, 'pid': 1, 'ts': 520, 'cat': 'foo',
         'tid': 1, 'ph': 'B'},
        {'name': 'a', 'args': {'x': 2}, 'pid': 1, 'ts': 560, 'cat': 'foo',
         'tid': 1, 'ph': 'E'}
    ]

    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
    m = timeline_model.TimelineModel(trace_data)
    processes = m.GetAllProcesses()
    t = processes[0].threads[1]
    slice_a = FindEventNamed(t.all_slices, 'a')

    self.assertEqual(2, slice_a.args['x'])
    self.assertEqual(1, len(m.import_errors))
Ejemplo n.º 19
0
 def testOutOfOrderData(self):
     builder = trace_data.TraceDataBuilder()
     builder.AddTraceFor(trace_data.INSPECTOR_TRACE_PART, [{
         'startTime':
         5295.004,
         'endTime':
         5305.004,
         'data': {},
         'type':
         'Program',
         'children': [{
             'startTime': 5295.004,
             'data': {
                 'id': 0
             },
             'type': 'BeginFrame',
         }, {
             'startTime': 4492.973,
             'endTime': 4493.086,
             'data': {
                 'rootNode': -3
             },
             'type': 'PaintSetup'
         }, {
             'startTime': 5298.004,
             'endTime': 5301.004,
             'type': 'Paint',
             'frameId': '53228.1',
             'data': {
                 'rootNode': -3,
                 'clip': [0, 0, 1018, 0, 1018, 764, 0, 764],
                 'layerId': 10
             },
             'children': []
         }, {
             'startTime': 5301.004,
             'endTime': 5305.004,
             'data': {},
             'type': 'CompositeLayers',
             'children': []
         }, {
             'startTime': 5305.004,
             'data': {},
             'type': 'MarkFirstPaint'
         }]
     }])
     model.TimelineModel(builder.AsData(), shift_world_to_zero=False)
Ejemplo n.º 20
0
    def testNoDeviceTraceResults(self):
        """Test expected results when missing device traces."""
        model = model_module.TimelineModel()
        test_thread = model.GetOrCreateProcess(1).GetOrCreateThread(2)
        service_slice, _ = _CreateGPUSlices(test_thread, 'test_item', 100, 10)
        _AddSliceToThread(test_thread, service_slice)
        model.FinalizeImport()

        metric = gpu_timeline.GPUTimelineMetric()
        results = self.GetResults(metric,
                                  model=model,
                                  renderer_thread=test_thread,
                                  interaction_records=INTERACTION_RECORDS)

        for name, source_type in (('swap', None), ('total', 'cpu')):
            results.AssertHasPageSpecificScalarValue(
                gpu_timeline.TimelineName(name, source_type, 'max'), 'ms', 10)
            results.AssertHasPageSpecificScalarValue(
                gpu_timeline.TimelineName(name, source_type, 'mean'), 'ms', 10)
            results.AssertHasPageSpecificScalarValue(
                gpu_timeline.TimelineName(name, source_type, 'stddev'), 'ms',
                0)

        self.assertRaises(AssertionError, results.GetPageSpecificValueNamed,
                          gpu_timeline.TimelineName('total', 'gpu', 'max'))
        self.assertRaises(AssertionError, results.GetPageSpecificValueNamed,
                          gpu_timeline.TimelineName('total', 'gpu', 'mean'))
        self.assertRaises(AssertionError, results.GetPageSpecificValueNamed,
                          gpu_timeline.TimelineName('total', 'gpu', 'stddev'))

        for name in gpu_timeline.TRACKED_GL_CONTEXT_NAME.values():
            results.AssertHasPageSpecificScalarValue(
                gpu_timeline.TimelineName(name, 'cpu', 'max'), 'ms', 0)
            results.AssertHasPageSpecificScalarValue(
                gpu_timeline.TimelineName(name, 'cpu', 'mean'), 'ms', 0)
            results.AssertHasPageSpecificScalarValue(
                gpu_timeline.TimelineName(name, 'cpu', 'stddev'), 'ms', 0)

            self.assertRaises(AssertionError,
                              results.GetPageSpecificValueNamed,
                              gpu_timeline.TimelineName(name, 'gpu', 'max'))
            self.assertRaises(AssertionError,
                              results.GetPageSpecificValueNamed,
                              gpu_timeline.TimelineName(name, 'gpu', 'mean'))
            self.assertRaises(AssertionError,
                              results.GetPageSpecificValueNamed,
                              gpu_timeline.TimelineName(name, 'gpu', 'stddev'))
  def testInstanceCounter(self):
    events = [
        {'name': 'ctr', 'args': {'value': 0}, 'pid': 1, 'ts': 0, 'cat': 'foo',
         'tid': 1,
         'ph': 'C', 'id': 0},
        {'name': 'ctr', 'args': {'value': 10}, 'pid': 1, 'ts': 10, 'cat': 'foo',
         'tid': 1,
         'ph': 'C', 'id': 0},
        {'name': 'ctr', 'args': {'value': 10}, 'pid': 1, 'ts': 10, 'cat': 'foo',
         'tid': 1,
         'ph': 'C', 'id': 1},
        {'name': 'ctr', 'args': {'value': 20}, 'pid': 1, 'ts': 15, 'cat': 'foo',
         'tid': 1,
         'ph': 'C', 'id': 1},
        {'name': 'ctr', 'args': {'value': 30}, 'pid': 1, 'ts': 18, 'cat': 'foo',
         'tid': 1,
         'ph': 'C', 'id': 1},
        {'name': 'ctr', 'args': {'value': 40}, 'pid': 1, 'ts': 20, 'cat': 'bar',
         'tid': 1,
         'ph': 'C', 'id': 2}
    ]
    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
    m = timeline_model.TimelineModel(trace_data)
    p = m.GetAllProcesses()[0]
    ctr = p.counters['foo.ctr[0]']
    self.assertEqual('ctr[0]', ctr.name)
    self.assertEqual('foo', ctr.category)
    self.assertEqual(2, ctr.num_samples)
    self.assertEqual(1, ctr.num_series)
    self.assertEqual([0, 0.01], ctr.timestamps)
    self.assertEqual([0, 10], ctr.samples)

    ctr = m.GetAllProcesses()[0].counters['foo.ctr[1]']
    self.assertEqual('ctr[1]', ctr.name)
    self.assertEqual('foo', ctr.category)
    self.assertEqual(3, ctr.num_samples)
    self.assertEqual(1, ctr.num_series)
    self.assertEqual([0.01, 0.015, 0.018], ctr.timestamps)
    self.assertEqual([10, 20, 30], ctr.samples)

    ctr = m.GetAllProcesses()[0].counters['bar.ctr[2]']
    self.assertEqual('ctr[2]', ctr.name)
    self.assertEqual('bar', ctr.category)
    self.assertEqual(1, ctr.num_samples)
    self.assertEqual(1, ctr.num_series)
    self.assertEqual([0.02], ctr.timestamps)
    self.assertEqual([40], ctr.samples)
  def testAutoclosingWithEventsOutsideBounds(self):
    events = [
        # Slice that begins before min and ends after max of the other threads.
        {'name': 'a', 'args': {}, 'pid': 1, 'ts': 0, 'tts': 0, 'cat': 'foo',
         'tid': 1, 'ph': 'B'},
        {'name': 'b', 'args': {}, 'pid': 1, 'ts': 6, 'tts': 3, 'cat': 'foo',
         'tid': 1, 'ph': 'B'},

        # Slice that does finish to give an 'end time' to establish a basis
        {'name': 'c', 'args': {}, 'pid': 1, 'ts': 2, 'tts': 1, 'cat': 'bar',
         'tid': 2, 'ph': 'B'},
        {'name': 'c', 'args': {}, 'pid': 1, 'ts': 4, 'tts': 2, 'cat': 'bar',
         'tid': 2, 'ph': 'E'}
    ]
    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
    m = timeline_model.TimelineModel(trace_data, shift_world_to_zero=False)
    p = m.GetAllProcesses()[0]
    t1 = p.threads[1]
    t1_thread_time_bounds = (
        m._thread_time_bounds[t1]) # pylint: disable=protected-access
    self.assertAlmostEqual(0.000, t1_thread_time_bounds.min)
    self.assertAlmostEqual(0.003, t1_thread_time_bounds.max)
    self.assertEqual(2, len(t1.all_slices))

    slice_event = FindEventNamed(t1.all_slices, 'a')
    self.assertEqual('a', slice_event.name)
    self.assertEqual('foo', slice_event.category)
    self.assertAlmostEqual(0, slice_event.start)
    self.assertAlmostEqual(0.006, slice_event.duration)
    self.assertAlmostEqual(0, slice_event.thread_start)
    self.assertAlmostEqual(0.003, slice_event.thread_duration)

    t2 = p.threads[2]
    t2_thread_time_bounds = (
        m._thread_time_bounds[t2]) # pylint: disable=protected-access
    self.assertAlmostEqual(0.001, t2_thread_time_bounds.min)
    self.assertAlmostEqual(0.002, t2_thread_time_bounds.max)
    slice2 = FindEventNamed(t2.all_slices, 'c')
    self.assertEqual('c', slice2.name)
    self.assertEqual('bar', slice2.category)
    self.assertAlmostEqual(0.002, slice2.start)
    self.assertAlmostEqual(0.002, slice2.duration)
    self.assertAlmostEqual(0.001, slice2.thread_start)
    self.assertAlmostEqual(0.001, slice2.thread_duration)

    self.assertAlmostEqual(0.000, m.bounds.min)
    self.assertAlmostEqual(0.006, m.bounds.max)
Ejemplo n.º 23
0
    def testGetRendererThreadFromTabId(self):
        self.assertEquals(self._tab.url, 'about:blank')
        # Create 3 tabs. The third tab is closed before we call
        # tracing_controller.StartTracing.
        first_tab = self._tab
        second_tab = self._browser.tabs.New()
        second_tab.Navigate('about:blank')
        second_tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
        third_tab = self._browser.tabs.New()
        third_tab.Navigate('about:blank')
        third_tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
        third_tab.Close()
        config = tracing_config.TracingConfig()
        config.chrome_trace_config.SetLowOverheadFilter()
        config.enable_chrome_trace = True
        self._browser.platform.tracing_controller.StartTracing(config)
        first_tab.ExecuteJavaScript('console.time("first-tab-marker");')
        first_tab.ExecuteJavaScript('console.timeEnd("first-tab-marker");')
        second_tab.ExecuteJavaScript('console.time("second-tab-marker");')
        second_tab.ExecuteJavaScript('console.timeEnd("second-tab-marker");')
        trace_data = self._browser.platform.tracing_controller.StopTracing()
        timeline_model = model.TimelineModel(trace_data)

        # Assert that the renderer_thread of the first tab contains
        # 'first-tab-marker'.
        renderer_thread = timeline_model.GetRendererThreadFromTabId(
            first_tab.id)
        first_tab_markers = [
            renderer_thread.IterAllSlicesOfName('first-tab-marker')
        ]
        self.assertEquals(1, len(first_tab_markers))

        # Close second tab and assert that the renderer_thread of the second tab
        # contains 'second-tab-marker'.
        second_tab.Close()
        renderer_thread = timeline_model.GetRendererThreadFromTabId(
            second_tab.id)
        second_tab_markers = [
            renderer_thread.IterAllSlicesOfName('second-tab-marker')
        ]
        self.assertEquals(1, len(second_tab_markers))

        # Third tab wasn't available when we start tracing, so there is no
        # renderer_thread corresponding to it in the the trace.
        self.assertIs(None,
                      timeline_model.GetRendererThreadFromTabId(third_tab.id))
Ejemplo n.º 24
0
    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)
Ejemplo n.º 25
0
  def testRepr(self):
    # Create a renderer thread.
    model = model_module.TimelineModel()
    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
    model.FinalizeImport()

    s = async_slice.AsyncSlice(
        'cat', 'Interaction.Test/is_smooth',
        timestamp=0, duration=200, start_thread=renderer_main,
        end_thread=renderer_main, thread_start=30, thread_duration=30)
    record = tir_module.TimelineInteractionRecord.FromAsyncEvent(s)
    expected_repr = (
        'TimelineInteractionRecord(label=\'Test\', '
        'start=0.000000, end=200.000000, flags=is_smooth, '
        'async_event=TimelineEvent(name=\'Interaction.Test/is_smooth\','
        ' start=0.000000, duration=200, thread_start=30, thread_duration=30))')
    self.assertEquals(expected_repr, repr(record))
Ejemplo n.º 26
0
  def testHasDrmStats(self):
    timeline = model.TimelineModel()
    timer = MockTimer()
    vblank_timer = MockVblankTimer()

    # A process without drm stats
    process_without_stats = timeline.GetOrCreateProcess(pid=5)
    thread_without_stats = process_without_stats.GetOrCreateThread(tid=51)
    process_without_stats.FinalizeImport()
    self.assertFalse(rendering_stats.HasDrmStats(thread_without_stats))

    # A process with drm stats and frames in them
    process_with_frames = timeline.GetOrCreateProcess(pid=6)
    thread_with_frames = process_with_frames.GetOrCreateThread(tid=61)
    AddDrmEventFlipStats(timer, vblank_timer, thread_with_frames, True, None)
    process_with_frames.FinalizeImport()
    self.assertTrue(rendering_stats.HasDrmStats(thread_with_frames))
Ejemplo n.º 27
0
    def ValidateAndMeasurePage(self, page, tab, results):
        timeline_data = tab.browser.platform.tracing_controller.StopTracing(
        )[0]
        timeline_model = model.TimelineModel(timeline_data)
        self._power_metric.Stop(page, tab)
        self._power_metric.AddResults(tab, results)

        def _IsDone():
            return tab.EvaluateJavaScript('isDone')

        decode_image_events = timeline_model.GetAllEventsOfName(
            'ImageFrameGenerator::decode')
        # FIXME: Remove this when impl-side painting is on everywhere.
        if not decode_image_events:
            decode_image_events = timeline_model.GetAllEventsOfName(
                'Decode Image')

        # If it is a real image page, then store only the last-minIterations
        # decode tasks.
        if (hasattr(
                page,
                'image_decoding_measurement_limit_results_to_min_iterations')
                and
                page.image_decoding_measurement_limit_results_to_min_iterations
            ):
            assert _IsDone()
            min_iterations = tab.EvaluateJavaScript('minIterations')
            decode_image_events = decode_image_events[-min_iterations:]

        durations = [d.duration for d in decode_image_events]
        assert durations, 'Failed to find image decode trace events.'

        image_decoding_avg = sum(durations) / len(durations)
        results.AddValue(
            scalar.ScalarValue(
                results.current_page,
                'ImageDecoding_avg',
                'ms',
                image_decoding_avg,
                description='Average decode time for images in 4 different '
                'formats: gif, png, jpg, and webp. The image files are '
                'located at chrome/test/data/image_decoding.'))
        results.AddValue(
            scalar.ScalarValue(
                results.current_page, 'ImageLoading_avg', 'ms',
                tab.EvaluateJavaScript('averageLoadingTimeMs()')))
Ejemplo n.º 28
0
    def testNoSurfaceFlingerStats(self):
        timeline = model.TimelineModel()
        timer = MockTimer()

        ref_stats = ReferenceRenderingStats()
        ref_stats.AppendNewRange()
        surface_flinger = timeline.GetOrCreateProcess(pid=4)
        surface_flinger.name = 'SurfaceFlinger'
        renderer = timeline.GetOrCreateProcess(pid=2)
        browser = timeline.GetOrCreateProcess(pid=3)
        browser_main = browser.GetOrCreateThread(tid=31)
        browser_main.BeginSlice('webkit.console', 'ActionA',
                                timer.AdvanceAndGet(2, 4), '')

        for i in xrange(0, 10):
            first = (i == 0)
            AddDisplayRenderingStats(timer, browser_main, first, ref_stats)
            timer.Advance(5, 10)

        browser_main.EndSlice(timer.AdvanceAndGet())
        timer.Advance(2, 4)

        browser.FinalizeImport()
        renderer.FinalizeImport()
        timeline_markers = timeline.FindTimelineMarkers(['ActionA'])
        records = [
            tir_module.TimelineInteractionRecord(e.name, e.start, e.end)
            for e in timeline_markers
        ]
        metadata = [{
            'name': 'metadata',
            'value': {
                'surface_flinger': {
                    'refresh_period': 16.6666
                }
            }
        }]
        stats = rendering_stats.RenderingStats(renderer, browser,
                                               surface_flinger, None, records,
                                               metadata)

        # Compare rendering stats to reference - we should fallback to Display
        # Compositor stats, in absence of Surface Flinger stats.
        self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps)
        self.assertEquals(stats.frame_times, ref_stats.frame_times)
Ejemplo n.º 29
0
  def ValidateAndMeasurePage(self, page, tab, results):
    timeline_data = 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(timeline_data, tuple):
      timeline_data = timeline_data[0]

    timeline_model = model.TimelineModel(timeline_data)
    self._power_metric.Stop(page, tab)
    self._power_metric.AddResults(tab, results)

    def _IsDone():
      return tab.EvaluateJavaScript('isDone')

    decode_image_events = timeline_model.GetAllEventsOfName(
        'ImageFrameGenerator::decode')
    # FIXME: Remove this when impl-side painting is on everywhere.
    if not decode_image_events:
      decode_image_events = timeline_model.GetAllEventsOfName('Decode Image')

    # If it is a real image page, then store only the last-minIterations
    # decode tasks.
    if (hasattr(
            page,
            'image_decoding_measurement_limit_results_to_min_iterations') and
        page.image_decoding_measurement_limit_results_to_min_iterations):
      assert _IsDone()
      min_iterations = tab.EvaluateJavaScript('minIterations')
      decode_image_events = decode_image_events[-min_iterations:]

    durations = [d.duration for d in decode_image_events]
    assert durations, 'Failed to find image decode trace events.'

    image_decoding_avg = sum(durations) / len(durations)
    results.AddValue(scalar.ScalarValue(
        results.current_page, 'ImageDecoding_avg', 'ms', image_decoding_avg,
        description='Average decode time for images in 4 different '
                    'formats: gif, png, jpg, and webp. The image files are '
                    'located at chrome/test/data/image_decoding.'))
    results.AddValue(scalar.ScalarValue(
        results.current_page, 'ImageLoading_avg', 'ms',
        tab.EvaluateJavaScript('averageLoadingTimeMs()')))
    def testBothSurfaceFlingerAndDisplayStats(self):
        timeline = model.TimelineModel()
        timer = MockTimer()

        ref_stats = ReferenceRenderingStats()
        ref_stats.AppendNewRange()
        surface_flinger = timeline.GetOrCreateProcess(pid=4)
        surface_flinger.name = 'SurfaceFlinger'
        surface_flinger_thread = surface_flinger.GetOrCreateThread(tid=41)
        renderer = timeline.GetOrCreateProcess(pid=2)
        browser = timeline.GetOrCreateProcess(pid=3)
        browser_main = browser.GetOrCreateThread(tid=31)
        browser_main.BeginSlice('webkit.console', 'ActionA',
                                timer.AdvanceAndGet(2, 4), '')

        # Create SurfaceFlinger stats and display rendering stats.
        for i in xrange(0, 10):
            first = (i == 0)
            AddSurfaceFlingerStats(timer, surface_flinger_thread, first,
                                   ref_stats)
            timer.Advance(2, 4)

        for i in xrange(0, 10):
            first = (i == 0)
            AddDisplayRenderingStats(timer, browser_main, first, None)
            timer.Advance(5, 10)

        browser_main.EndSlice(timer.AdvanceAndGet())
        timer.Advance(2, 4)

        browser.FinalizeImport()
        renderer.FinalizeImport()
        timeline_markers = timeline.FindTimelineMarkers(['ActionA'])
        timeline_ranges = [
            bounds.Bounds.CreateFromEvent(marker)
            for marker in timeline_markers
        ]
        stats = rendering_stats.RenderingStats(renderer, browser,
                                               surface_flinger,
                                               timeline_ranges)

        # Compare rendering stats to reference - Only SurfaceFlinger stats should
        # count
        self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps)
        self.assertEquals(stats.frame_times, ref_stats.frame_times)