import itertools
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
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']
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
"""
SCHEDULED = True
@classmethod
def IsScheduled(cls):
if cls.Name().startswith("UNSCHEDULED_"):
return False
return cls.SCHEDULED
def SetExtraBrowserOptions(self, options):
"""To be overridden by perf benchmarks."""
def SetExtraBrowserOptionsWithBrowser(self, options, possible_browser):
"""To be overridden by perf benchmarks. Run after SetExtraBrowserOptions."""
def CustomizeOptions(self, finder_options, possible_browser=None):
super(PerfBenchmark, self).CustomizeOptions(finder_options)
browser_options = finder_options.browser_options
browser_options.take_screenshot_for_failed_page = True
if (browser_options.browser_type != 'reference' and
'no-field-trials' not in browser_options.compatibility_mode):
variations = self._GetVariationsBrowserArgs(
finder_options, browser_options.extra_browser_args, possible_browser)
browser_options.AppendExtraBrowserArgs(variations)
browser_options.profile_files_to_copy.extend(
GetAdTaggingProfileFiles(
self._GetOutDirectoryEstimate(finder_options)))
browser_options.AppendExtraBrowserArgs(
'--disable-gpu-process-for-dx12-info-collection')
browser_options.AppendExtraBrowserArgs('--propagate-iph-for-testing')
self.SetExtraBrowserOptions(browser_options)
self.SetExtraBrowserOptionsWithBrowser(browser_options, possible_browser)
def GetExtraOutDirectories(self):
return []
@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'
if target_os == 'lacros':
return 'chromeos_lacros'
return target_os
def _GetVariationsBrowserArgs(self,
finder_options,
current_args,
possible_browser=None):
if possible_browser is None:
possible_browser = browser_finder.FindBrowser(finder_options)
if not possible_browser:
return []
if not self.IsAndroid(possible_browser):
return '--enable-field-trial-config'
variations_dir = os.path.join(path_module.GetChromiumSrcDir(), 'testing',
'variations')
return fieldtrial_util.GenerateArgs(
os.path.join(variations_dir, 'fieldtrial_testing_config.json'),
self.FixupTargetOS(possible_browser.target_os),
current_args)
@staticmethod
def _GetPossibleBuildDirectories(chrome_src_dir, browser_type):
possible_directories = path_module.GetBuildDirectories(chrome_src_dir)
if browser_type in ('android-chromium', 'any'):
return possible_directories
return (p for p in possible_directories
if os.path.basename(p).lower() == browser_type)
def _GetOutDirectoryEstimate(self, finder_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.
"""
if finder_options.chromium_output_dir is not None:
return finder_options.chromium_output_dir
possible_directories = itertools.chain(
self._GetPossibleBuildDirectories(
finder_options.chrome_root,
finder_options.browser_options.browser_type),
self.GetExtraOutDirectories())
return next((p for p in possible_directories if os.path.exists(p)), None)
@staticmethod
def IsAndroid(possible_browser):
"""Returns whether a possible_browser is on an Android build."""
return possible_browser.target_os.startswith('android')
@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
@staticmethod
def NeedsSoftwareCompositing():
if 'CHROME_REMOTE_DESKTOP_SESSION' in os.environ:
return True
if 'XVFB_DISPLAY' in os.environ:
return True
return False