def __init__(self, browser_type, finder_options, android_platform,
                 backend_settings, apk_name):
        super(PossibleAndroidBrowser,
              self).__init__(browser_type, 'android',
                             backend_settings.supports_tab_control)
        assert browser_type in FindAllBrowserTypes(finder_options), (
            'Please add %s to android_browser_finder.FindAllBrowserTypes' %
            browser_type)
        self._platform = android_platform
        self._platform_backend = (android_platform._platform_backend)  # pylint: disable=protected-access
        self._backend_settings = backend_settings
        self._local_apk = None

        if browser_type == 'exact':
            if not os.path.exists(apk_name):
                raise exceptions.PathMissingError(
                    'Unable to find exact apk %s specified by --browser-executable'
                    % apk_name)
            self._local_apk = apk_name
        elif apk_name:
            assert finder_options.chrome_root, (
                'Must specify Chromium source to use apk_name')
            chrome_root = finder_options.chrome_root
            candidate_apks = []
            for build_dir, build_type in util.GetBuildDirectories():
                apk_full_name = os.path.join(chrome_root, build_dir,
                                             build_type, 'apks', apk_name)
                if os.path.exists(apk_full_name):
                    last_changed = os.path.getmtime(apk_full_name)
                    candidate_apks.append((last_changed, apk_full_name))

            if candidate_apks:
                # Find the candidate .apk with the latest modification time.
                newest_apk_path = sorted(candidate_apks)[-1][1]
                self._local_apk = newest_apk_path
예제 #2
0
def GetBuildTypeOfPath(path):
    if not path:
        return None
    for build_dir, build_type in util.GetBuildDirectories():
        if os.path.join(build_dir, build_type) in path:
            return build_type
    return None
예제 #3
0
    def __init__(self, browser_type, finder_options, android_platform,
                 backend_settings, apk_name):
        super(PossibleAndroidBrowser,
              self).__init__(browser_type, 'android',
                             backend_settings.supports_tab_control)
        assert browser_type in FindAllBrowserTypes(finder_options), (
            'Please add %s to android_browser_finder.FindAllBrowserTypes' %
            browser_type)
        self._platform = android_platform
        self._platform_backend = (android_platform._platform_backend)  # pylint: disable=W0212
        self._backend_settings = backend_settings
        self._local_apk = None

        chrome_root = util.GetChromiumSrcDir()
        if apk_name:
            candidate_apks = []
            for build_dir, build_type in util.GetBuildDirectories():
                apk_full_name = os.path.join(chrome_root, build_dir,
                                             build_type, 'apks', apk_name)
                if os.path.exists(apk_full_name):
                    last_changed = os.path.getmtime(apk_full_name)
                    candidate_apks.append((last_changed, apk_full_name))

            if candidate_apks:
                # Find the canadidate .apk with the latest modification time.
                newest_apk_path = sorted(candidate_apks)[-1][1]
                self._local_apk = newest_apk_path
예제 #4
0
def _FindMatchingUnstrippedLibraryOnHost(device, lib):
    lib_base = os.path.basename(lib)

    device_md5sums = md5sum.CalculateDeviceMd5Sums([lib], device)
    if lib not in device_md5sums:
        return None

    device_md5 = device_md5sums[lib]

    def FindMatchingStrippedLibrary(out_path):
        # First find a matching stripped library on the host. This avoids the need
        # to pull the stripped library from the device, which can take tens of
        # seconds.
        # Check the GN stripped lib path first, and the GYP ones afterwards.
        host_lib_path = os.path.join(out_path, lib_base)
        host_lib_pattern = os.path.join(out_path, '*_apk', 'libs', '*',
                                        lib_base)
        for stripped_host_lib in [host_lib_path] + glob.glob(host_lib_pattern):
            if os.path.exists(stripped_host_lib):
                with open(stripped_host_lib) as f:
                    host_md5 = hashlib.md5(f.read()).hexdigest()
                    if host_md5 == device_md5:
                        return stripped_host_lib
        return None

    out_path = None
    stripped_host_lib = None
    for out_path in util.GetBuildDirectories():
        stripped_host_lib = FindMatchingStrippedLibrary(out_path)
        if stripped_host_lib:
            break

    if not stripped_host_lib:
        return None

    # The corresponding unstripped library will be under lib.unstripped for GN, or
    # lib for GYP.
    unstripped_host_lib_paths = [
        os.path.join(out_path, 'lib.unstripped', lib_base),
        os.path.join(out_path, 'lib', lib_base)
    ]
    unstripped_host_lib = next(
        (lib for lib in unstripped_host_lib_paths if os.path.exists(lib)),
        None)
    if unstripped_host_lib is None:
        return None

    # Make sure the unstripped library matches the stripped one. We do this
    # by comparing the hashes of text sections in both libraries. This isn't an
    # exact guarantee, but should still give reasonable confidence that the
    # libraries are compatible.
    # TODO(skyostil): Check .note.gnu.build-id instead once we're using
    # --build-id=sha1.
    # pylint: disable=undefined-loop-variable
    if (_ElfSectionMd5Sum(unstripped_host_lib, _TEXT_SECTION) !=
            _ElfSectionMd5Sum(stripped_host_lib, _TEXT_SECTION)):
        return None
    return unstripped_host_lib
예제 #5
0
def _FindLocalApk(chrome_root, apk_name):
    found_apk_path = None
    found_last_changed = None
    for build_path in util.GetBuildDirectories(chrome_root):
        apk_path = os.path.join(build_path, 'apks', apk_name)
        if os.path.exists(apk_path):
            last_changed = os.path.getmtime(apk_path)
            # Keep the most recently updated apk only.
            if last_changed is None or last_changed > found_last_changed:
                found_apk_path = apk_path
                found_last_changed = last_changed

    return found_apk_path
    def GetStackTrace(self):
        """Returns stack trace.

    The stack trace consists of raw logcat dump, logcat dump with symbols,
    and stack info from tomstone files.
    """
        def Decorate(title, content):
            return "%s\n%s\n%s\n" % (title, content, '*' * 80)

        # Get the UI nodes that can be found on the screen
        ret = Decorate('UI dump', '\n'.join(self.GetSystemUi().ScreenDump()))

        # Get the last lines of logcat (large enough to contain stacktrace)
        logcat = self.GetLogCat()
        ret += Decorate('Logcat', logcat)
        stack = os.path.join(util.GetChromiumSrcDir(), 'third_party',
                             'android_platform', 'development', 'scripts',
                             'stack')
        # Try to symbolize logcat.
        if os.path.exists(stack):
            cmd = [stack]
            arch = self.GetArchName()
            arch = _ARCH_TO_STACK_TOOL_ARCH.get(arch, arch)
            cmd.append('--arch=%s' % arch)
            for build_path in util.GetBuildDirectories():
                if os.path.exists(build_path):
                    cmd.append('--output-directory=%s' % build_path)
                    break
            p = subprocess.Popen(cmd,
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE)
            ret += Decorate('Stack from Logcat',
                            p.communicate(input=logcat)[0])

        # Try to get tombstones.
        tombstones = os.path.join(util.GetChromiumSrcDir(), 'build', 'android',
                                  'tombstones.py')
        if os.path.exists(tombstones):
            tombstones_cmd = [
                tombstones,
                '-w',
                '--device',
                self._device.adb.GetDeviceSerial(),
                '--adb-path',
                self._device.adb.GetAdbPath(),
            ]
            ret += Decorate(
                'Tombstones',
                subprocess.Popen(tombstones_cmd,
                                 stdout=subprocess.PIPE).communicate()[0])
        return (True, ret)
예제 #7
0
    def _FindNewestFlushUtility(self):
        flush_command = None
        flush_command_mtime = 0

        chrome_root = util.GetChromiumSrcDir()
        for build_dir, build_type in util.GetBuildDirectories():
            candidate = os.path.join(chrome_root, build_dir, build_type,
                                     self.GetFlushUtilityName())
            if os.access(candidate, os.X_OK):
                candidate_mtime = os.stat(candidate).st_mtime
                if candidate_mtime > flush_command_mtime:
                    flush_command = candidate
                    flush_command_mtime = candidate_mtime

        return flush_command
예제 #8
0
def _FindLocallyBuiltPath(binary_name):
    """Finds the most recently built |binary_name|."""
    command = None
    command_mtime = 0
    required_mode = os.X_OK
    if binary_name.endswith('.apk'):
        required_mode = os.R_OK
    for build_path in util.GetBuildDirectories():
        candidate = os.path.join(build_path, binary_name)
        if os.path.isfile(candidate) and os.access(candidate, required_mode):
            candidate_mtime = os.stat(candidate).st_mtime
            if candidate_mtime > command_mtime:
                command = candidate
                command_mtime = candidate_mtime
    return command
예제 #9
0
def FindLocallyBuiltPath(binary_name):
  """Finds the most recently built |binary_name|."""
  command = None
  command_mtime = 0
  chrome_root = util.GetChromiumSrcDir()
  required_mode = os.X_OK
  if binary_name.endswith('.apk'):
    required_mode = os.R_OK
  for build_dir, build_type in util.GetBuildDirectories():
    candidate = os.path.join(chrome_root, build_dir, build_type, binary_name)
    if os.path.isfile(candidate) and os.access(candidate, required_mode):
      candidate_mtime = os.stat(candidate).st_mtime
      if candidate_mtime > command_mtime:
        command = candidate
        command_mtime = candidate_mtime
  return command
  def _InstallNfcApk(self):
    """Installs the APK that allows VR tests to simulate a headset NFC scan."""
    chromium_root = path_util.GetChromiumSrcDir()
    # Find the most recently build APK
    candidate_apks = []
    for build_path in util.GetBuildDirectories(chromium_root):
      apk_path = os.path.join(build_path, 'apks', 'VrNfcSimulator.apk')
      if os.path.exists(apk_path):
        last_changed = os.path.getmtime(apk_path)
        candidate_apks.append((last_changed, apk_path))

    if not candidate_apks:
      raise RuntimeError(
          'Could not find VrNfcSimulator.apk in a build output directory')
    newest_apk_path = sorted(candidate_apks)[-1][1]
    self._platform.InstallApplication(
        os.path.join(chromium_root, newest_apk_path))
예제 #11
0
def _FindMatchingUnstrippedLibraryOnHost(device, lib):
    lib_base = os.path.basename(lib)

    device_md5 = device.RunShellCommand('md5 "%s"' % lib, as_root=True)[0]
    device_md5 = device_md5.split(' ', 1)[0]

    def FindMatchingStrippedLibrary(out_path):
        # First find a matching stripped library on the host. This avoids the need
        # to pull the stripped library from the device, which can take tens of
        # seconds.
        host_lib_pattern = os.path.join(out_path, '*_apk', 'libs', '*',
                                        lib_base)
        for stripped_host_lib in glob.glob(host_lib_pattern):
            with open(stripped_host_lib) as f:
                host_md5 = hashlib.md5(f.read()).hexdigest()
                if host_md5 == device_md5:
                    return stripped_host_lib
        return None

    out_path = None
    stripped_host_lib = None
    for out_path in util.GetBuildDirectories():
        stripped_host_lib = FindMatchingStrippedLibrary(out_path)
        if stripped_host_lib:
            break

    if not stripped_host_lib:
        return None

    # The corresponding unstripped library will be under out/Release/lib.
    unstripped_host_lib = os.path.join(out_path, 'lib', lib_base)

    # Make sure the unstripped library matches the stripped one. We do this
    # by comparing the hashes of text sections in both libraries. This isn't an
    # exact guarantee, but should still give reasonable confidence that the
    # libraries are compatible.
    # TODO(skyostil): Check .note.gnu.build-id instead once we're using
    # --build-id=sha1.
    # pylint: disable=undefined-loop-variable
    if (_ElfSectionMd5Sum(unstripped_host_lib, _TEXT_SECTION) !=
            _ElfSectionMd5Sum(stripped_host_lib, _TEXT_SECTION)):
        return None
    return unstripped_host_lib
  def __init__(self, browser_type, finder_options, backend_settings, apk_name):
    super(PossibleAndroidBrowser, self).__init__(browser_type, finder_options)
    self._backend_settings = backend_settings
    self._local_apk = None

    chrome_root = util.GetChromiumSrcDir()
    if apk_name:
      candidate_apks = []
      for build_dir, build_type in util.GetBuildDirectories():
        apk_full_name = os.path.join(chrome_root, build_dir, build_type, 'apks',
                                     apk_name)
        if os.path.exists(apk_full_name):
          last_changed = os.path.getmtime(apk_full_name)
          candidate_apks.append((last_changed, apk_full_name))

      if candidate_apks:
        # Find the canadidate .apk with the latest modification time.
        newest_apk_path = sorted(candidate_apks)[-1][1]
        self._local_apk = newest_apk_path
예제 #13
0
    def testNoAdTaggingRuleset(self):
        # This tests (badly) assumes that util.GetBuildDirectories() will always
        # return a list of multiple directories, with Debug ordered before Release.
        # This is not the case if CHROMIUM_OUTPUT_DIR is set or a build.ninja file
        # exists in the current working directory - in those cases, only a single
        # directory is returned. So, abort early if we only get back one directory.
        num_dirs = 0
        for _ in util.GetBuildDirectories(self._chrome_root):
            num_dirs += 1
        if num_dirs < 2:
            return

        benchmark = perf_benchmark.PerfBenchmark()
        options = options_for_unittests.GetCopy()

        # Set the chrome root to avoid using a ruleset from an existing "Release"
        # out dir.
        options.chrome_root = self._output_dir
        benchmark.CustomizeOptions(options)
        self._ExpectAdTaggingProfileFiles(options.browser_options, False)
예제 #14
0
    def testAdTaggingRulesetOutputDirNotFound(self):
        # Same as the above test but use Debug instead of Release. This should
        # cause the benchmark to fail to find the ruleset because we only check
        # directories matching the browser_type.
        self._PopulateGenFiles(os.path.join(self._chrome_root, 'out', 'Debug'))

        # This tests (badly) assumes that util.GetBuildDirectories() will always
        # return a list of multiple directories, with Debug ordered before Release.
        # This is not the case if CHROMIUM_OUTPUT_DIR is set or a build.ninja file
        # exists in the current working directory - in those cases, only a single
        # directory is returned. So, abort early if we only get back one directory.
        num_dirs = 0
        for _ in util.GetBuildDirectories(self._chrome_root):
            num_dirs += 1
        if num_dirs < 2:
            return

        benchmark = perf_benchmark.PerfBenchmark()
        options = options_for_unittests.GetCopy()
        options.chrome_root = self._chrome_root
        options.browser_options.browser_type = "release"

        benchmark.CustomizeOptions(options)
        self._ExpectAdTaggingProfileFiles(options.browser_options, False)
예제 #15
0
    # to pull the stripped library from the presentation.device, which can take tens of
    # seconds.
    # Check the GN stripped lib path first, and the GYP ones afterwards.
    host_lib_path = os.path.join(out_path, lib_base)
    host_lib_pattern = os.path.join(out_path, '*_apk', 'libs', '*', lib_base)
    for stripped_host_lib in [host_lib_path] + glob.glob(host_lib_pattern):
      if os.path.exists(stripped_host_lib):
        with open(stripped_host_lib) as f:
          host_md5 = hashlib.md5(f.read()).hexdigest()
          if host_md5 == device_md5:
            return stripped_host_lib
    return None

  out_path = None
  stripped_host_lib = None
  for out_path in util.GetBuildDirectories():
    stripped_host_lib = FindMatchingStrippedLibrary(out_path)
    if stripped_host_lib:
      break

  if not stripped_host_lib:
    return None

  # The corresponding unstripped library will be under lib.unstripped for GN, or
  # lib for GYP.
  unstripped_host_lib_paths = [
      os.path.join(out_path, 'lib.unstripped', lib_base),
      os.path.join(out_path, 'lib', lib_base)
  ]
  unstripped_host_lib = next(
      (lib for lib in unstripped_host_lib_paths if os.path.exists(lib)), None)
def FindAllAvailableBrowsers(finder_options):
    """Finds all the desktop browsers available on this machine."""
    browsers = []

    if not CanFindAvailableBrowsers():
        return []

    has_display = True
    if (sys.platform.startswith('linux') and os.getenv('DISPLAY') == None):
        has_display = False

    # Look for a browser in the standard chrome build locations.
    if finder_options.chrome_root:
        chrome_root = finder_options.chrome_root
    else:
        chrome_root = util.GetChromiumSrcDir()

    flash_bin_dir = os.path.join(chrome_root, 'third_party', 'adobe', 'flash',
                                 'binaries', 'ppapi')

    chromium_app_names = []
    if sys.platform == 'darwin':
        chromium_app_names.append('Chromium.app/Contents/MacOS/Chromium')
        chromium_app_names.append(
            'Google Chrome.app/Contents/MacOS/Google Chrome')
        content_shell_app_name = 'Content Shell.app/Contents/MacOS/Content Shell'
        flash_bin = 'PepperFlashPlayer.plugin'
        flash_path = os.path.join(flash_bin_dir, 'mac', flash_bin)
        flash_path_64 = os.path.join(flash_bin_dir, 'mac_64', flash_bin)
    elif sys.platform.startswith('linux'):
        chromium_app_names.append('chrome')
        content_shell_app_name = 'content_shell'
        flash_bin = 'libpepflashplayer.so'
        flash_path = os.path.join(flash_bin_dir, 'linux', flash_bin)
        flash_path_64 = os.path.join(flash_bin_dir, 'linux_x64', flash_bin)
    elif sys.platform.startswith('win'):
        chromium_app_names.append('chrome.exe')
        content_shell_app_name = 'content_shell.exe'
        flash_bin = 'pepflashplayer.dll'
        flash_path = os.path.join(flash_bin_dir, 'win', flash_bin)
        flash_path_64 = os.path.join(flash_bin_dir, 'win_x64', flash_bin)
    else:
        raise Exception('Platform not recognized')

    def IsExecutable(path):
        return os.path.isfile(path) and os.access(path, os.X_OK)

    # Add the explicit browser executable if given.
    if finder_options.browser_executable:
        normalized_executable = os.path.expanduser(
            finder_options.browser_executable)
        if IsExecutable(normalized_executable):
            browser_directory = os.path.dirname(
                finder_options.browser_executable)
            browsers.append(
                PossibleDesktopBrowser('exact', finder_options,
                                       normalized_executable, flash_path,
                                       False, browser_directory))
        else:
            raise Exception(
                '%s specified by --browser-executable does not exist',
                normalized_executable)

    def AddIfFound(browser_type, build_dir, type_dir, app_name, content_shell):
        browser_directory = os.path.join(chrome_root, build_dir, type_dir)
        app = os.path.join(browser_directory, app_name)
        if IsExecutable(app):
            is_64 = browser_type.endswith('_x64')
            browsers.append(
                PossibleDesktopBrowser(browser_type,
                                       finder_options,
                                       app,
                                       flash_path_64 if is_64 else flash_path,
                                       content_shell,
                                       browser_directory,
                                       is_local_build=True))
            return True
        return False

    # Add local builds
    for build_dir, build_type in util.GetBuildDirectories():
        for chromium_app_name in chromium_app_names:
            AddIfFound(build_type.lower(), build_dir, build_type,
                       chromium_app_name, False)
        AddIfFound('content-shell-' + build_type.lower(), build_dir,
                   build_type, content_shell_app_name, True)

    # Mac-specific options.
    if sys.platform == 'darwin':
        mac_canary_root = '/Applications/Google Chrome Canary.app/'
        mac_canary = mac_canary_root + 'Contents/MacOS/Google Chrome Canary'
        mac_system_root = '/Applications/Google Chrome.app'
        mac_system = mac_system_root + '/Contents/MacOS/Google Chrome'
        if IsExecutable(mac_canary):
            browsers.append(
                PossibleDesktopBrowser('canary', finder_options, mac_canary,
                                       None, False, mac_canary_root))

        if IsExecutable(mac_system):
            browsers.append(
                PossibleDesktopBrowser('system', finder_options, mac_system,
                                       None, False, mac_system_root))

    # Linux specific options.
    if sys.platform.startswith('linux'):
        # Look for a google-chrome instance.
        found = False
        try:
            with open(os.devnull, 'w') as devnull:
                found = subprocess.call(['google-chrome', '--version'],
                                        stdout=devnull,
                                        stderr=devnull) == 0
        except OSError:
            pass
        if found:
            browsers.append(
                PossibleDesktopBrowser('system', finder_options,
                                       'google-chrome', None, False,
                                       '/opt/google/chrome'))

    # Win32-specific options.
    if sys.platform.startswith('win'):
        system_path = os.path.join('Google', 'Chrome', 'Application')
        canary_path = os.path.join('Google', 'Chrome SxS', 'Application')

        win_search_paths = [
            os.getenv('PROGRAMFILES(X86)'),
            os.getenv('PROGRAMFILES'),
            os.getenv('LOCALAPPDATA')
        ]

        def AddIfFoundWin(browser_name, search_path, app_path):
            browser_directory = os.path.join(search_path, app_path)
            for chromium_app_name in chromium_app_names:
                app = os.path.join(browser_directory, chromium_app_name)
                if IsExecutable(app):
                    browsers.append(
                        PossibleDesktopBrowser(browser_name, finder_options,
                                               app, None, False,
                                               browser_directory))
                    return True
            return False

        for path in win_search_paths:
            if not path:
                continue
            if AddIfFoundWin('canary', path, canary_path):
                break

        for path in win_search_paths:
            if not path:
                continue
            if AddIfFoundWin('system', path, system_path):
                break

    if len(browsers) and not has_display:
        logging.warning(
            'Found (%s), but you do not have a DISPLAY environment set.' %
            ','.join([b.browser_type for b in browsers]))
        return []

    return browsers
예제 #17
0
  def GetStackTrace(self):
    """Returns a recent stack trace from a crash.

    The stack trace consists of raw logcat dump, logcat dump with symbols,
    and stack info from tombstone files, all concatenated into one string.
    """
    def Decorate(title, content):
      if not content or content.isspace():
        content = ('**EMPTY** - could be explained by log messages '
                   'preceding the previous python Traceback - best wishes')
      return "%s\n%s\n%s\n" % (title, content, '*' * 80)

    # Get the UI nodes that can be found on the screen
    ret = Decorate('UI dump', '\n'.join(self.GetSystemUi().ScreenDump()))

    # Get the last lines of logcat (large enough to contain stacktrace)
    logcat = self.GetLogCat()
    ret += Decorate('Logcat', logcat)

    # Determine the build directory.
    build_path = '.'
    for b in util.GetBuildDirectories():
      if os.path.exists(b):
        build_path = b
        break

    # Try to symbolize logcat.
    chromium_src_dir = util.GetChromiumSrcDir()
    stack = os.path.join(chromium_src_dir, 'third_party', 'android_platform',
                         'development', 'scripts', 'stack')
    if _ExecutableExists(stack):
      cmd = [stack]
      arch = self.GetArchName()
      arch = _ARCH_TO_STACK_TOOL_ARCH.get(arch, arch)
      cmd.append('--arch=%s' % arch)
      cmd.append('--output-directory=%s' % build_path)
      p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
      ret += Decorate('Stack from Logcat', p.communicate(input=logcat)[0])

    # Try to get tombstones.
    tombstones = os.path.join(chromium_src_dir, 'build', 'android',
                              'tombstones.py')
    if _ExecutableExists(tombstones):
      tombstones_cmd = [
          tombstones, '-w',
          '--device', self._device.adb.GetDeviceSerial(),
          '--adb-path', self._device.adb.GetAdbPath(),
      ]
      ret += Decorate('Tombstones',
                      subprocess.Popen(tombstones_cmd,
                                       stdout=subprocess.PIPE).communicate()[0])

    # Attempt to get detailed stack traces with Crashpad.
    stackwalker_path = os.path.join(chromium_src_dir, 'build', 'android',
                                    'stacktrace', 'crashpad_stackwalker.py')
    minidump_stackwalk_path = os.path.join(build_path, 'minidump_stackwalk')
    if (_ExecutableExists(stackwalker_path) and
        _ExecutableExists(minidump_stackwalk_path)):
      crashpad_cmd = [
          stackwalker_path,
          '--device', self._device.adb.GetDeviceSerial(),
          '--adb-path', self._device.adb.GetAdbPath(),
          '--build-path', build_path,
          '--chrome-cache-path',
          os.path.join(
              self.GetProfileDir(
                  self._ExtractLastNativeCrashPackageFromLogcat(logcat)),
              'cache'),
      ]
      ret += Decorate('Crashpad stackwalk',
                      subprocess.Popen(crashpad_cmd,
                                       stdout=subprocess.PIPE).communicate()[0])
    return (True, ret)