def __init__(self, overhead_level=LOW_OVERHEAD_LEVEL): """As the amount of instrumentation increases, so does the overhead. The user of the measurement chooses the overhead level that is appropriate, and the tracing is filtered accordingly. overhead_level: Can either be a custom ChromeTraceCategoryFilter object or one of LOW_OVERHEAD_LEVEL, DEFAULT_OVERHEAD_LEVEL or DEBUG_OVERHEAD_LEVEL. """ self._config = tracing_config.TracingConfig() self._config.enable_chrome_trace = True self._config.enable_platform_display_trace = False if isinstance(overhead_level, chrome_trace_category_filter.ChromeTraceCategoryFilter): self._config.chrome_trace_config.SetCategoryFilter(overhead_level) elif overhead_level in ALL_OVERHEAD_LEVELS: if overhead_level == LOW_OVERHEAD_LEVEL: self._config.chrome_trace_config.SetLowOverheadFilter() elif overhead_level == DEFAULT_OVERHEAD_LEVEL: self._config.chrome_trace_config.SetDefaultOverheadFilter() else: self._config.chrome_trace_config.SetDebugOverheadFilter() else: raise Exception("Overhead level must be a ChromeTraceCategoryFilter " "object or valid overhead level string. Given overhead " "level: %s" % overhead_level) self._timeline_based_metrics = None self._legacy_timeline_based_metrics = []
def WillNavigateToPage(self, page, tab): config = tracing_config.TracingConfig() config.chrome_trace_config.category_filter.AddExcludedCategory('*') for cat in TOPLEVEL_CATEGORIES: config.chrome_trace_config.category_filter.AddDisabledByDefault( cat) config.enable_chrome_trace = True tab.browser.platform.tracing_controller.StartTracing(config, 60)
def WillNavigateToPage(self, page, tab): # FIXME: Remove webkit.console when blink.console lands in chromium and the # ref builds are updated. crbug.com/386847 config = tracing_config.TracingConfig() for c in ['webkit.console', 'blink.console', 'gpu']: config.chrome_trace_config.category_filter.AddIncludedCategory(c) config.enable_chrome_trace = True tab.browser.platform.tracing_controller.StartTracing(config, 60)
def WillNavigateToPage(self, page, tab): config = tracing_config.TracingConfig() for category in self._CATEGORIES: config.tracing_category_filter.AddIncludedCategory(category) config.enable_chrome_trace = True tab.browser.platform.tracing_controller.StartTracing( config, self._TIME_OUT_IN_SECONDS)
def setUp(self): finder_options = options_for_unittests.GetCopy() self.possible_browser = browser_finder.FindBrowser(finder_options) if not self.possible_browser: raise Exception('No browser found, cannot continue test.') self.browser_options = finder_options.browser_options self.config = tracing_config.TracingConfig() self.config.enable_chrome_trace = True
def _CreateTraceConfigFile(self, trace_options, category_filter): config = tracing_config.TracingConfig(trace_options, category_filter) if self._platform_backend.GetOSName() == 'android': self._CreateTraceConfigFileOnAndroid(config) elif self._platform_backend.GetOSName() in _DESKTOP_OS_NAMES: self._CreateTraceConfigFileOnDesktop(config) else: raise NotImplementedError
def testDefault(self): config = tracing_config.TracingConfig() config_string = config.GetChromeTraceConfigJsonString() self.assertEquals( '{' '"record_mode": "record-as-much-as-possible"' '}', config_string)
def testDefault(self): options = tracing_options.TracingOptions() category_filter = tracing_category_filter.TracingCategoryFilter() config = tracing_config.TracingConfig(options, category_filter) config_string = config.GetTraceConfigJsonString() self.assertEquals( '{' '"record_mode": "record-as-much-as-possible"' '}', config_string)
def CaptureTrace(self): tracing_controller = self._browser.platform.tracing_controller options = tracing_config.TracingConfig() options.enable_chrome_trace = True tracing_controller.StartTracing(options) try: yield finally: self._full_trace = tracing_controller.StopTracing()[0]
def testFlushTracing(self): subtrace_count = 5 tab = self._browser.tabs[0] def InjectMarker(index): marker = 'test-marker-%d' % index tab.EvaluateJavaScript('console.time({{ marker }});', marker=marker) tab.EvaluateJavaScript('console.timeEnd({{ marker }});', marker=marker) # Set up the tracing config. tracing_controller = self._browser.platform.tracing_controller config = tracing_config.TracingConfig() config.enable_chrome_trace = True # Start tracing and inject a unique marker into the sub-trace. tracing_controller.StartTracing(config) self.assertTrue(tracing_controller.is_tracing_running) InjectMarker(0) # Flush tracing |subtrace_count - 1| times and inject a unique marker into # the sub-trace each time. for i in xrange(1, subtrace_count): tracing_controller.FlushTracing() self.assertTrue(tracing_controller.is_tracing_running) InjectMarker(i) # Stop tracing. trace_data, errors = tracing_controller.StopTracing() self.assertEqual(errors, []) self.assertFalse(tracing_controller.is_tracing_running) # Test that trace data is parsable model = model_module.TimelineModel(trace_data) # Check that the markers 'test-marker-0', 'flush-tracing', 'test-marker-1', # ..., 'flush-tracing', 'test-marker-|subtrace_count - 1|' are monotonic. custom_markers = [ marker for i in xrange(subtrace_count) for marker in model.FindTimelineMarkers('test-marker-%d' % i) ] flush_markers = model.FindTimelineMarkers(['flush-tracing'] * (subtrace_count - 1)) markers = [ marker for group in zip(custom_markers, flush_markers) for marker in group ] + custom_markers[-1:] self.assertEquals(len(custom_markers), subtrace_count) self.assertEquals(len(flush_markers), subtrace_count - 1) self.assertEquals(len(markers), 2 * subtrace_count - 1) for i in xrange(1, len(markers)): self.assertLess(markers[i - 1].end, markers[i].start)
def setUp(self): self._config = tracing_config.TracingConfig() self._config.enable_cpu_trace = True if sys.platform.startswith('win'): self._desktop_backend = win_platform_backend.WinPlatformBackend() elif sys.platform.startswith('darwin'): self._desktop_backend = mac_platform_backend.MacPlatformBackend() else: self._desktop_backend = linux_platform_backend.LinuxPlatformBackend() self._agent = cpu_tracing_agent.CpuTracingAgent(self._desktop_backend)
def StartTracing(self, platform_backend, enable_chrome_trace=True): assert chrome_tracing_agent.ChromeTracingAgent.IsSupported( platform_backend) agent = chrome_tracing_agent.ChromeTracingAgent(platform_backend) config = tracing_config.TracingConfig() config.tracing_category_filter.AddIncludedCategory('foo') config.enable_chrome_trace = enable_chrome_trace agent._platform_backend.tracing_controller_backend.is_tracing_running = True agent.StartAgentTracing(config, 10) return agent
def CaptureTraceMarkers(self): tracing_controller = self._browser.platform.tracing_controller options = tracing_config.TracingConfig() options.enable_chrome_trace = True tracing_controller.StartTracing(options) try: yield finally: trace_data = tracing_controller.StopTracing() self.markers = trace_processor.ExtractTimelineMarkers(trace_data)
def testGotTrace(self): tracing_controller = self._browser.platform.tracing_controller config = tracing_config.TracingConfig() config.enable_chrome_trace = True tracing_controller.StartTracing(config) trace_data = tracing_controller.StopTracing() # Test that trace data is parsable model = model_module.TimelineModel(trace_data) assert len(model.processes) > 0
def testFlushTracing(self): SUBTRACE_COUNT = 5 tab = self._browser.tabs[0] def InjectMarker(index): marker = 'test-marker-%d' % index # TODO(catapult:#3028): Fix interpolation of JavaScript values. tab.EvaluateJavaScript('console.time("%s");' % marker) # TODO(catapult:#3028): Fix interpolation of JavaScript values. tab.EvaluateJavaScript('console.timeEnd("%s");' % marker) # Set up the tracing config. tracing_controller = self._browser.platform.tracing_controller config = tracing_config.TracingConfig() config.enable_chrome_trace = True # Start tracing and inject a unique marker into the sub-trace. tracing_controller.StartTracing(config) self.assertTrue(tracing_controller.is_tracing_running) InjectMarker(0) # Flush tracing |SUBTRACE_COUNT - 1| times and inject a unique marker into # the sub-trace each time. for i in xrange(1, SUBTRACE_COUNT): tracing_controller.FlushTracing() self.assertTrue(tracing_controller.is_tracing_running) InjectMarker(i) # Stop tracing. trace_data = tracing_controller.StopTracing() self.assertFalse(tracing_controller.is_tracing_running) # Test that trace data is parsable model = model_module.TimelineModel(trace_data) # Check that the markers 'test-marker-0', 'flush-tracing', 'test-marker-1', # ..., 'flush-tracing', 'test-marker-|SUBTRACE_COUNT - 1|' are monotonic. custom_markers = [ marker for i in xrange(SUBTRACE_COUNT) for marker in model.FindTimelineMarkers('test-marker-%d' % i) ] flush_markers = model.FindTimelineMarkers(['flush-tracing'] * (SUBTRACE_COUNT - 1)) markers = [ marker for group in zip(custom_markers, flush_markers) for marker in group ] + custom_markers[-1:] self.assertEquals(len(custom_markers), SUBTRACE_COUNT) self.assertEquals(len(flush_markers), SUBTRACE_COUNT - 1) self.assertEquals(len(markers), 2 * SUBTRACE_COUNT - 1) for i in xrange(1, len(markers)): self.assertLess(markers[i - 1].end, markers[i].start)
def testIsTracingRunning(self): tracing_controller = self._browser.platform.tracing_controller if not tracing_controller.IsChromeTracingSupported(): return self.assertFalse(tracing_controller.is_tracing_running) config = tracing_config.TracingConfig() config.enable_chrome_trace = True tracing_controller.StartTracing(config) self.assertTrue(tracing_controller.is_tracing_running) tracing_controller.StopTracing() self.assertFalse(tracing_controller.is_tracing_running)
def RunActualGpuTest(self, test_path, *args): test_params = args[0] assert 'browser_args' in test_params assert 'category' in test_params assert 'test_harness_script' in test_params assert 'finish_js_condition' in test_params browser_args = test_params['browser_args'] category = test_params['category'] test_harness_script = test_params['test_harness_script'] finish_js_condition = test_params['finish_js_condition'] success_eval_func = test_params['success_eval_func'] # Maximum repeat a flaky test 30 times for ii in range(_TEST_MAX_REPEATS): if ii > 0: logging.info('Try the test again: #%d', ii + 1) # The version of this test in the old GPU test harness restarted # the browser after each test, so continue to do that to match its # behavior. self.RestartBrowserWithArgs(self._AddDefaultArgs(browser_args)) # Set up tracing. config = tracing_config.TracingConfig() config.chrome_trace_config.category_filter.AddExcludedCategory('*') config.chrome_trace_config.category_filter.AddDisabledByDefault( category) config.enable_chrome_trace = True tab = self.tab tab.browser.platform.tracing_controller.StartTracing(config, 60) # Perform page navigation. url = self.UrlOfStaticFilePath(test_path) tab.Navigate(url, script_to_evaluate_on_commit=test_harness_script) tab.action_runner.WaitForJavaScriptCondition(finish_js_condition, timeout=30) # Stop tracing. timeline_data = tab.browser.platform.tracing_controller.StopTracing( )[0] # Evaluate success. timeline_model = model_module.TimelineModel(timeline_data) event_iter = timeline_model.IterAllEvents( event_type_predicate=timeline_model.IsSliceOrAsyncSlice) test_result = _TEST_DONE if success_eval_func: prefixed_func_name = '_EvaluateSuccess_' + success_eval_func test_result = getattr(self, prefixed_func_name)(category, event_iter) assert test_result in [_TEST_DONE, _TEST_REPEAT] if test_result == _TEST_DONE: break else: self.fail('Test failed all %d tries' % _TEST_MAX_REPEATS)
def testStartTracingFailure(self): self._inspector_socket.AddResponseHandler( 'Tracing.start', lambda req: {'error': {'message': 'Tracing is already started'}}) self._inspector_socket.AddResponseHandler( 'Tracing.hasCompleted', lambda req: {}) backend = tracing_backend.TracingBackend(self._inspector_socket) config = tracing_config.TracingConfig() self.assertRaisesRegexp( tracing_backend.TracingUnexpectedResponseException, 'Tracing is already started', backend.StartTracing, config.chrome_trace_config)
def _get_memory_usage(self): """Helper function to get the memory usage. It returns a tuple of six elements: (browser_usage, renderer_usage, gpu_usage, kernel_usage, total_usage, graphics_usage) All are expected in the unit of KB. browser_usage: the RSS of the browser process renderer_usage: the total RSS of all renderer processes gpu_usage: the total RSS of all gpu processes kernel_usage: the memory used in kernel total_usage: the sum of the above memory usages. The graphics_usage is not included because the composition of the graphics memory is much more complicated (could be from video card, user space, or kenerl space). It doesn't make so much sense to sum it up with others. graphics_usage: the memory usage reported by the graphics driver """ config = tracing_config.TracingConfig() config.chrome_trace_config.category_filter.AddExcludedCategory("*") 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.browser.platform.tracing_controller.StartTracing(config) # Force to collect garbage before measuring memory for t in self.browser.tabs: t.CollectGarbage() self.browser.DumpMemory() trace_data = self.browser.platform.tracing_controller.StopTracing()[0] model = TimelineModel(trace_data) memory_dump = model.IterGlobalMemoryDumps().next() process_memory = collections.defaultdict(int) for process_memory_dump in memory_dump.IterProcessMemoryDumps(): process_name = process_memory_dump.process_name process_memory[process_name] += sum( process_memory_dump.GetMemoryUsage().values()) result = (process_memory[KEY_BROWSER] / 1024, process_memory[KEY_RENDERER] / 1024, process_memory[KEY_GPU] / 1024, _get_kernel_memory_usage()) # total = browser + renderer + gpu + kernal result += (sum(result), _get_graphics_memory_usage()) return result
def _StartTracing(self, tab, tracing_categories): config = tracing_config.TracingConfig() config.enable_chrome_trace = True config.chrome_trace_config.category_filter.AddFilterString( 'blink.console') # This is always required for js land trace event config.chrome_trace_config.category_filter.AddFilterString( tracing_categories) if self._extra_chrome_categories: config.chrome_trace_config.category_filter.AddFilterString( self._extra_chrome_categories) if self._enable_systrace: config.chrome_trace_config.SetEnableSystrace() tab.browser.platform.tracing_controller.StartTracing(config)
def _ContinueTestRunWithTracing(self, tab): tracing_categories = tab.EvaluateJavaScript( 'testRunner.tracingCategories') config = tracing_config.TracingConfig() config.enable_chrome_trace = True config.chrome_trace_config.category_filter.AddFilterString( 'blink.console') # This is always required for js land trace event config.chrome_trace_config.category_filter.AddFilterString( tracing_categories) tab.browser.platform.tracing_controller.StartTracing(config) tab.EvaluateJavaScript('testRunner.scheduleTestRun()') tab.WaitForJavaScriptCondition('testRunner.isDone') return tab.browser.platform.tracing_controller.StopTracing()
def testCreateInteraction(self): action_runner = action_runner_module.ActionRunner(self._tab) self.Navigate('interaction_enabled_page.html') action_runner.Wait(1) config = tracing_config.TracingConfig() config.chrome_trace_config.SetLowOverheadFilter() config.enable_chrome_trace = True self._browser.platform.tracing_controller.StartTracing(config) with action_runner.CreateInteraction('InteractionName', repeatable=True): pass trace_data = self._browser.platform.tracing_controller.StopTracing() markers = trace_processor.ExtractTimelineMarkers(trace_data) self.assertIn('Interaction.InteractionName/repeatable', markers)
def testStartAndStopTraceMultipleTimes(self): tracing_controller = self._browser.platform.tracing_controller config = tracing_config.TracingConfig() config.enable_chrome_trace = True tracing_controller.StartTracing(config) self.assertFalse(tracing_controller.StartTracing(config)) trace_data = tracing_controller.StopTracing() # 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.StopTracing)
def WillNavigateToPage(self, page, tab): config = tracing_config.TracingConfig() config.enable_chrome_trace = True config.enable_platform_display_trace = True # Basic categories for smoothness. config.chrome_trace_config.SetLowOverheadFilter() # Extra categories from commandline flag. if self.options and self.options.extra_chrome_categories: config.chrome_trace_config.category_filter.AddFilterString( self.options.extra_chrome_categories) tab.browser.platform.tracing_controller.StartTracing(config)
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(builder) model.TimelineModel(builder.AsData())
def __init__(self, browser_backend, platform_backend, output_path, state, categories=None): super(TraceProfiler, self).__init__( browser_backend, platform_backend, output_path, state) assert self._browser_backend.supports_tracing # We always want flow events when tracing via telemetry. categories_with_flow = 'disabled-by-default-toplevel.flow' if categories: categories_with_flow += ',%s' % categories config = tracing_config.TracingConfig() config.enable_chrome_trace = True config.chrome_trace_config.SetCategoryFilter( chrome_trace_category_filter.ChromeTraceCategoryFilter( categories_with_flow)) self._browser_backend.StartTracing(config, timeout=10)
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 = self._browser.platform.tracing_controller.StopTracing() 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)
def SetUp(self, page, tab): """Starts gathering timeline data. """ # Resets these member variables incase this object is reused. self._model = None self._renderer_process = None if not tab.browser.platform.tracing_controller.IsChromeTracingSupported(): raise Exception('Not supported') config = tracing_config.TracingConfig() config.tracing_category_filter.AddFilterString(self.trace_categories) for delay in page.GetSyntheticDelayCategories(): config.tracing_category_filter.AddSyntheticDelay(delay) config.enable_chrome_trace = True tab.browser.platform.tracing_controller.StartTracing(config)
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)
def StartTracing(self, platform_backend, enable_chrome_trace=True, throw_exception=False): config = tracing_config.TracingConfig() config.enable_chrome_trace = enable_chrome_trace config.chrome_trace_config.category_filter.AddIncludedCategory('foo') agent = chrome_tracing_agent.ChromeTracingAgent(platform_backend, config) if throw_exception: agent._trace_config = True agent._platform_backend.tracing_controller_backend.is_tracing_running = True agent._test_config = config agent._transfer_mode = 'ReturnAsStream' with mock.patch(_CHROME_TRACING_AGENT_IMPORT_PATH + '._StartStartupTracing', return_value=True): agent.StartAgentTracing(config, 10) return agent