blob: a35868069353cabe913ef6e7f2a7200fbfe4b3b0 [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import json
import os
import sys
from telemetry import benchmark
from telemetry.internal.browser import browser_finder
from telemetry.internal.util import path as path_module
sys.path.append(os.path.join(os.path.dirname(__file__), '..',
'..', 'variations'))
import fieldtrial_util # pylint: disable=import-error
# This function returns a list of two-tuples designed to extend
# browser_options.profile_files_to_copy. On success, it will return two entries:
# 1. The actual indexed ruleset file, which will be placed in a destination
# directory as specified by the version found in the prefs file.
# 2. A default prefs 'Local State' file, which contains information about the ad
# tagging ruleset's version.
def GetAdTaggingProfileFiles(chrome_output_directory):
"""Gets ad tagging tuples for browser_options.profile_files_to_copy.
This function looks for input files related to ad tagging, and returns tuples
indicating where those files should be copied to in the resulting perf
benchmark profile directory.
Args:
chrome_output_directory: path to the output directory for this benchmark
(e.g. out/Default).
Returns:
A list of two-tuples designed to extend profile_files_to_copy in
BrowserOptions. If no ad tagging related input files could be found,
returns an empty list.
"""
if chrome_output_directory is None:
return []
gen_path = os.path.join(chrome_output_directory, 'gen', 'components',
'subresource_filter', 'tools')
ruleset_path = os.path.join(gen_path, 'GeneratedRulesetData')
if not os.path.exists(ruleset_path):
return []
local_state_path = os.path.join(gen_path, 'default_local_state.json')
if not os.path.exists(local_state_path):
return []
with open(local_state_path, 'r') as f:
state_json = json.load(f)
ruleset_version = state_json['subresource_filter']['ruleset_version']
# The ruleset should reside in:
# Subresource Filter/Indexed Rules/<iv>/<uv>/Ruleset Data
# Where iv = indexed version and uv = unindexed version
ruleset_format_str = '%d' % ruleset_version['format']
ruleset_dest = os.path.join('Subresource Filter', 'Indexed Rules',
ruleset_format_str, ruleset_version['content'],
'Ruleset Data')
return [(ruleset_path, ruleset_dest), (local_state_path, 'Local State')]
class PerfBenchmark(benchmark.Benchmark):
""" Super class for all benchmarks in src/tools/perf/benchmarks directory.
All the perf benchmarks must subclass from this one to to make sure that
the field trial configs are activated for the browser during benchmark runs.
For more info, see: https://goo.gl/4uvaVM
"""
def SetExtraBrowserOptions(self, options):
"""To be overridden by perf benchmarks."""
pass
def CustomizeBrowserOptions(self, options):
# Subclass of PerfBenchmark should override SetExtraBrowserOptions to add
# more browser options rather than overriding CustomizeBrowserOptions.
super(PerfBenchmark, self).CustomizeBrowserOptions(options)
# Enable taking screen shot on failed pages for all perf benchmarks.
options.take_screenshot_for_failed_page = True
# The current field trial config is used for an older build in the case of
# reference. This is a problem because we are then subjecting older builds
# to newer configurations that may crash. To work around this problem,
# don't add the field trials to reference builds.
#
# The same logic applies to the ad filtering ruleset, which could be in a
# binary format that an older build does not expect.
if options.browser_type != 'reference' and ('no-field-trials' not in
options.compatibility_mode):
variations = self._GetVariationsBrowserArgs(options.finder_options)
options.AppendExtraBrowserArgs(variations)
options.profile_files_to_copy.extend(
GetAdTaggingProfileFiles(self._GetOutDirectoryEstimate(options)))
# A non-sandboxed, 15-seconds-delayed gpu process is currently running in
# the browser to collect gpu info. A command line switch is added here to
# skip this gpu process for all perf tests to prevent any interference
# with the test results.
options.AppendExtraBrowserArgs(
'--disable-gpu-process-for-dx12-vulkan-info-collection')
# TODO(crbug.com/881469): remove this once Webview support surface
# synchronization and viz.
if options.browser_type and 'android-webview' in options.browser_type:
options.AppendExtraBrowserArgs(
'--disable-features=SurfaceSynchronization,VizDisplayCompositor')
# Switch Chrome to use Perfetto instead of TraceLog as the tracing backend,
# needed until the feature gets turned on by default everywhere.
if options.browser_type != 'reference':
options.AppendExtraBrowserArgs(
'--enable-features=TracingPerfettoBackend')
self.SetExtraBrowserOptions(options)
@staticmethod
def FixupTargetOS(target_os):
if target_os == 'darwin':
return 'mac'
if target_os.startswith('win'):
return 'windows'
if target_os.startswith('linux'):
return 'linux'
if target_os == 'cros':
return 'chromeos'
return target_os
def _GetVariationsBrowserArgs(self, finder_options):
chrome_root = finder_options.chrome_root
if chrome_root is None:
chrome_root = path_module.GetChromiumSrcDir()
variations_dir = os.path.join(chrome_root, 'testing', 'variations')
possible_browser = browser_finder.FindBrowser(finder_options)
if not possible_browser:
return []
return fieldtrial_util.GenerateArgs(
os.path.join(variations_dir, 'fieldtrial_testing_config.json'),
[self.FixupTargetOS(possible_browser.target_os)])
@staticmethod
def _GetPossibleBuildDirectories(chrome_src_dir, browser_type):
possible_directories = path_module.GetBuildDirectories(chrome_src_dir)
# Special case "android-chromium" and "any" and check all
# possible out directories.
if browser_type in ('android-chromium', 'any'):
return possible_directories
# For all other browser types, just consider directories which match.
return (p for p in possible_directories
if os.path.basename(p).lower() == browser_type)
def _GetOutDirectoryEstimate(self, options):
"""Gets an estimate of the output directory for this build.
Note that as an estimate, this may be incorrect. Callers should be aware of
this and ensure that in the case that this returns an existing but
incorrect directory, nothing should critically break.
"""
finder_options = options.finder_options
if finder_options.chromium_output_dir is not None:
return finder_options.chromium_output_dir
possible_directories = self._GetPossibleBuildDirectories(
finder_options.chrome_root, options.browser_type)
return next((p for p in possible_directories if os.path.exists(p)), None)
@staticmethod
def IsSvelte(possible_browser):
"""Returns whether a possible_browser is on a svelte Android build."""
if possible_browser.target_os == 'android':
return possible_browser.platform.IsSvelte()
return False