예제 #1
0
 def _InstallCipdPackages(self, packages):
     for cipd_root, pkgs in self._IterVersionedCipdPackages(packages):
         logging.info('Installing packages in %s', cipd_root)
         if not os.path.exists(cipd_root):
             os.makedirs(cipd_root)
         ensure_path = os.path.join(cipd_root, '.ensure')
         with open(ensure_path, 'w') as ensure_file:
             # Make CIPD ensure that all files are present and correct,
             # even if it thinks the package is installed.
             ensure_file.write('$ParanoidMode CheckIntegrity\n\n')
             for pkg in pkgs:
                 ensure_file.write('%s %s\n' %
                                   (pkg.package_name, pkg.version))
                 logging.info('  %s %s', pkg.package_name, pkg.version)
         ensure_cmd = [
             'cipd',
             'ensure',
             '-ensure-file',
             ensure_path,
             '-root',
             cipd_root,
         ]
         try:
             for line in cmd_helper.IterCmdOutputLines(ensure_cmd):
                 logging.info('    %s', line)
         except subprocess.CalledProcessError as e:
             # avd.py is executed with python2.
             # pylint: disable=W0707
             raise AvdException('Failed to install CIPD packages: %s' %
                                str(e),
                                command=ensure_cmd)
예제 #2
0
 def testIterCmdOutputLines_exitStatusSkipped(self):
   for num, line in enumerate(
       cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True), 1):
     self.assertEquals(num, int(line))
     # no exception will be raised because we don't attempt to read past
     # the end of the output and, thus, the status never gets checked
     if num == 10:
       break
예제 #3
0
    def Install(self, packages=_ALL_PACKAGES):
        """Installs the requested CIPD packages.

    Returns: None
    Raises: AvdException on failure to install.
    """
        pkgs_by_dir = {}
        if packages is _ALL_PACKAGES:
            packages = [
                self._config.avd_package,
                self._config.emulator_package,
                self._config.system_image_package,
            ]
        for pkg in packages:
            if not pkg.dest_path in pkgs_by_dir:
                pkgs_by_dir[pkg.dest_path] = []
            pkgs_by_dir[pkg.dest_path].append(pkg)

        for pkg_dir, pkgs in pkgs_by_dir.iteritems():
            logging.info('Installing packages in %s', pkg_dir)
            cipd_root = os.path.join(constants.DIR_SOURCE_ROOT, pkg_dir)
            if not os.path.exists(cipd_root):
                os.makedirs(cipd_root)
            ensure_path = os.path.join(cipd_root, '.ensure')
            with open(ensure_path, 'w') as ensure_file:
                # Make CIPD ensure that all files are present, even if
                # it thinks the package is installed.
                ensure_file.write('$ParanoidMode CheckPresence\n\n')
                for pkg in pkgs:
                    ensure_file.write('%s %s\n' %
                                      (pkg.package_name, pkg.version))
                    logging.info('  %s %s', pkg.package_name, pkg.version)
            ensure_cmd = [
                'cipd',
                'ensure',
                '-ensure-file',
                ensure_path,
                '-root',
                cipd_root,
            ]
            try:
                for line in cmd_helper.IterCmdOutputLines(ensure_cmd):
                    logging.info('    %s', line)
            except subprocess.CalledProcessError as e:
                raise AvdException('Failed to install CIPD package %s: %s' %
                                   (pkg.package_name, str(e)),
                                   command=ensure_cmd)

        # The emulator requires that some files are writable.
        for dirname, _, filenames in os.walk(self._emulator_home):
            for f in filenames:
                path = os.path.join(dirname, f)
                mode = os.lstat(path).st_mode
                if mode & stat.S_IRUSR:
                    mode = mode | stat.S_IWUSR
                os.chmod(path, mode)
예제 #4
0
  def _IterRunDeviceAdbCmd(self, args, timeout):
    """Runs an adb command and returns an iterator over its output lines.

    Args:
      args: A list of arguments to adb.
      timeout: Timeout in seconds.

    Yields:
      The output of the command line by line.
    """
    return cmd_helper.IterCmdOutputLines(
      self._BuildAdbCmd(args, self._device_serial), timeout=timeout)
  def IterShell(self, command, timeout):
    """Runs a shell command and returns an iterator over its output lines.

    Args:
      command: A string with the shell command to run.
      timeout: Timeout in seconds.

    Yields:
      The output of the command line by line.
    """
    args = ['shell', command]
    return cmd_helper.IterCmdOutputLines(
      self._BuildAdbCmd(args, self._device_serial), timeout=timeout)
예제 #6
0
    def _IterRunDeviceAdbCmd(self, args, iter_timeout, timeout):
        """Runs an adb command and returns an iterator over its output lines.

    Args:
      args: A list of arguments to adb.
      iter_timeout: Timeout for each iteration in seconds.
      timeout: Timeout for the entire command in seconds.

    Yields:
      The output of the command line by line.
    """
        return cmd_helper.IterCmdOutputLines(self._BuildAdbCmd(
            args, self._device_serial),
                                             iter_timeout=iter_timeout,
                                             timeout=timeout,
                                             env=self._ADB_ENV)
예제 #7
0
def DexDump(dexfiles, file_summary=False):
  """A wrapper around the Android SDK's dexdump tool.

  Args:
    dexfiles: The dexfile or list of dex files to dump.
    file_summary: Display summary information from the file header. (-f)

  Returns:
    An iterable over the output lines.
  """
  # TODO(jbudorick): Add support for more options as necessary.
  if isinstance(dexfiles, basestring):
    dexfiles = [dexfiles]
  args = [_DEXDUMP_PATH] + dexfiles
  if file_summary:
    args.append('-f')

  return cmd_helper.IterCmdOutputLines(args)
예제 #8
0
파일: avd.py 프로젝트: wzis/chromium
  def Delete(self, avd_name):
    """Call `avdmanager delete`.

    Args:
      avd_name: name of the AVD to delete.
    """
    delete_cmd = [
        _DEFAULT_AVDMANAGER_PATH,
        '-v',
        'delete',
        'avd',
        '-n',
        avd_name,
    ]
    try:
      for line in cmd_helper.IterCmdOutputLines(delete_cmd, env=self._env):
        logging.info('  %s', line)
    except subprocess.CalledProcessError as e:
      raise AvdException('AVD deletion failed: %s' % str(e), command=delete_cmd)
예제 #9
0
파일: avd.py 프로젝트: wzis/chromium
  def _InstallCipdPackages(self, packages):
    pkgs_by_dir = {}
    if packages is _ALL_PACKAGES:
      packages = [
          self._config.avd_package,
          self._config.emulator_package,
          self._config.system_image_package,
      ]
    for pkg in packages:
      if not pkg.dest_path in pkgs_by_dir:
        pkgs_by_dir[pkg.dest_path] = []
      pkgs_by_dir[pkg.dest_path].append(pkg)

    for pkg_dir, pkgs in pkgs_by_dir.items():
      logging.info('Installing packages in %s', pkg_dir)
      cipd_root = os.path.join(constants.DIR_SOURCE_ROOT, pkg_dir)
      if not os.path.exists(cipd_root):
        os.makedirs(cipd_root)
      ensure_path = os.path.join(cipd_root, '.ensure')
      with open(ensure_path, 'w') as ensure_file:
        # Make CIPD ensure that all files are present and correct,
        # even if it thinks the package is installed.
        ensure_file.write('$ParanoidMode CheckIntegrity\n\n')
        for pkg in pkgs:
          ensure_file.write('%s %s\n' % (pkg.package_name, pkg.version))
          logging.info('  %s %s', pkg.package_name, pkg.version)
      ensure_cmd = [
          'cipd',
          'ensure',
          '-ensure-file',
          ensure_path,
          '-root',
          cipd_root,
      ]
      try:
        for line in cmd_helper.IterCmdOutputLines(ensure_cmd):
          logging.info('    %s', line)
      except subprocess.CalledProcessError as e:
        raise AvdException(
            'Failed to install CIPD package %s: %s' % (pkg.package_name,
                                                       str(e)),
            command=ensure_cmd)
예제 #10
0
  def _IterRunDeviceAdbCmd(self, args, iter_timeout, timeout, check_error=True):
    """Runs an adb command and returns an iterator over its output lines.

    Args:
      args: A list of arguments to adb.
      iter_timeout: Timeout for each iteration in seconds.
      timeout: Timeout for the entire command in seconds.
      check_error: Check that the command succeeded. This does check the
        error status of the adb command but DOES NOT check the exit status
        of shell commands.

    Yields:
      The output of the command line by line.
    """
    return cmd_helper.IterCmdOutputLines(
        self._BuildAdbCmd(args, self._device_serial),
        iter_timeout=iter_timeout,
        timeout=timeout,
        env=self._ADB_ENV,
        check_status=check_error)
예제 #11
0
def main():
    parser = argparse.ArgumentParser(description=(__doc__))
    parser.add_argument(
        'mapping_file',
        help='ProGuard mapping file from build which the stacktrace is from.')
    parser.add_argument('--stacktrace',
                        help='Stacktrace file to be deobfuscated.')
    args = parser.parse_args()

    retrace_path = os.path.join(_THIRD_PARTY_DIR, 'proguard', 'lib',
                                'retrace.jar')

    base_args = [
        'java', '-jar', retrace_path, '-regex', _LINE_PARSE_REGEX,
        args.mapping_file
    ]
    if args.stacktrace:
        subprocess.call(base_args + [args.stacktrace])
    else:
        for line in cmd_helper.IterCmdOutputLines(base_args):
            print line
예제 #12
0
 def testIterCmdOutputLines_exitStatusFail(self):
   with self.assertRaises(subprocess.CalledProcessError):
     for num, line in enumerate(
         cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True), 1):
       self.assertEquals(num, int(line))
예제 #13
0
파일: avd.py 프로젝트: wzis/chromium
  def Create(self,
             force=False,
             snapshot=False,
             keep=False,
             cipd_json_output=None,
             dry_run=False):
    """Create an instance of the AVD CIPD package.

    This method:
     - installs the requisite system image
     - creates the AVD
     - modifies the AVD's ini files to support running chromium tests
       in chromium infrastructure
     - optionally starts & stops the AVD for snapshotting (default no)
     - By default creates and uploads an instance of the AVD CIPD package
       (can be turned off by dry_run flag).
     - optionally deletes the AVD (default yes)

    Args:
      force: bool indicating whether to force create the AVD.
      snapshot: bool indicating whether to snapshot the AVD before creating
        the CIPD package.
      keep: bool indicating whether to keep the AVD after creating
        the CIPD package.
      cipd_json_output: string path to pass to `cipd create` via -json-output.
      dry_run: When set to True, it will skip the CIPD package creation
        after creating the AVD.
    """
    logging.info('Installing required packages.')
    self._InstallCipdPackages(packages=[
        self._config.emulator_package,
        self._config.system_image_package,
    ])

    android_avd_home = os.path.join(self._emulator_home, 'avd')

    if not os.path.exists(android_avd_home):
      os.makedirs(android_avd_home)

    avd_manager = _AvdManagerAgent(
        avd_home=android_avd_home, sdk_root=self._emulator_sdk_root)

    logging.info('Creating AVD.')
    avd_manager.Create(
        avd_name=self._config.avd_name,
        system_image=self._config.system_image_name,
        force=force)

    try:
      logging.info('Modifying AVD configuration.')

      # Clear out any previous configuration or state from this AVD.
      root_ini = os.path.join(android_avd_home,
                              '%s.ini' % self._config.avd_name)
      features_ini = os.path.join(self._emulator_home, 'advancedFeatures.ini')
      avd_dir = os.path.join(android_avd_home, '%s.avd' % self._config.avd_name)
      config_ini = os.path.join(avd_dir, 'config.ini')

      with ini.update_ini_file(root_ini) as root_ini_contents:
        root_ini_contents['path.rel'] = 'avd/%s.avd' % self._config.avd_name

      with ini.update_ini_file(features_ini) as features_ini_contents:
        # features_ini file will not be refreshed by avdmanager during
        # creation. So explicitly clear its content to exclude any leftover
        # from previous creation.
        features_ini_contents.clear()
        features_ini_contents.update(self.avd_settings.advanced_features)

      with ini.update_ini_file(config_ini) as config_ini_contents:
        height = self.avd_settings.screen.height or _DEFAULT_SCREEN_HEIGHT
        width = self.avd_settings.screen.width or _DEFAULT_SCREEN_WIDTH
        density = self.avd_settings.screen.density or _DEFAULT_SCREEN_DENSITY

        config_ini_contents.update({
            'disk.dataPartition.size': '4G',
            'hw.keyboard': 'yes',
            'hw.lcd.density': density,
            'hw.lcd.height': height,
            'hw.lcd.width': width,
        })

        if self.avd_settings.ram_size:
          config_ini_contents['hw.ramSize'] = self.avd_settings.ram_size

      # Start & stop the AVD.
      self._Initialize()
      instance = _AvdInstance(self._emulator_path, self._emulator_home,
                              self._config)
      # Enable debug for snapshot when it is set to True
      debug_tags = 'init,snapshot' if snapshot else None
      instance.Start(
          read_only=False, snapshot_save=snapshot, debug_tags=debug_tags)
      # Android devices with full-disk encryption are encrypted on first boot,
      # and then get decrypted to continue the boot process (See details in
      # https://bit.ly/3agmjcM).
      # Wait for this step to complete since it can take a while for old OSs
      # like M, otherwise the avd may have "Encryption Unsuccessful" error.
      device_utils.DeviceUtils(instance.serial).WaitUntilFullyBooted(
          decrypt=True, timeout=180, retries=0)
      instance.Stop()

      # The multiinstance lock file seems to interfere with the emulator's
      # operation in some circumstances (beyond the obvious -read-only ones),
      # and there seems to be no mechanism by which it gets closed or deleted.
      # See https://bit.ly/2pWQTH7 for context.
      multiInstanceLockFile = os.path.join(avd_dir, 'multiinstance.lock')
      if os.path.exists(multiInstanceLockFile):
        os.unlink(multiInstanceLockFile)

      package_def_content = {
          'package':
          self._config.avd_package.package_name,
          'root':
          self._emulator_home,
          'install_mode':
          'copy',
          'data': [{
              'dir': os.path.relpath(avd_dir, self._emulator_home)
          }, {
              'file': os.path.relpath(root_ini, self._emulator_home)
          }, {
              'file': os.path.relpath(features_ini, self._emulator_home)
          }],
      }

      logging.info('Creating AVD CIPD package.')
      logging.debug('ensure file content: %s',
                    json.dumps(package_def_content, indent=2))

      with tempfile_ext.TemporaryFileName(suffix='.json') as package_def_path:
        with open(package_def_path, 'w') as package_def_file:
          json.dump(package_def_content, package_def_file)

        logging.info('  %s', self._config.avd_package.package_name)
        cipd_create_cmd = [
            'cipd',
            'create',
            '-pkg-def',
            package_def_path,
            '-tag',
            'emulator_version:%s' % self._config.emulator_package.version,
            '-tag',
            'system_image_version:%s' %
            self._config.system_image_package.version,
        ]
        if cipd_json_output:
          cipd_create_cmd.extend([
              '-json-output',
              cipd_json_output,
          ])
        logging.info('running %r%s', cipd_create_cmd,
                     ' (dry_run)' if dry_run else '')
        if not dry_run:
          try:
            for line in cmd_helper.IterCmdOutputLines(cipd_create_cmd):
              logging.info('    %s', line)
          except subprocess.CalledProcessError as e:
            raise AvdException(
                'CIPD package creation failed: %s' % str(e),
                command=cipd_create_cmd)

    finally:
      if not keep:
        logging.info('Deleting AVD.')
        avd_manager.Delete(avd_name=self._config.avd_name)
예제 #14
0
    def Create(self,
               force=False,
               snapshot=False,
               keep=False,
               additional_apks=None,
               privileged_apk_tuples=None,
               cipd_json_output=None,
               dry_run=False):
        """Create an instance of the AVD CIPD package.

    This method:
     - installs the requisite system image
     - creates the AVD
     - modifies the AVD's ini files to support running chromium tests
       in chromium infrastructure
     - optionally starts, installs additional apks and/or privileged apks, and
       stops the AVD for snapshotting (default no)
     - By default creates and uploads an instance of the AVD CIPD package
       (can be turned off by dry_run flag).
     - optionally deletes the AVD (default yes)

    Args:
      force: bool indicating whether to force create the AVD.
      snapshot: bool indicating whether to snapshot the AVD before creating
        the CIPD package.
      keep: bool indicating whether to keep the AVD after creating
        the CIPD package.
      additional_apks: a list of strings contains the paths to the APKs. These
        APKs will be installed after AVD is started.
      privileged_apk_tuples: a list of (apk_path, device_partition) tuples where
        |apk_path| is a string containing the path to the APK, and
        |device_partition| is a string indicating the system image partition on
        device that contains "priv-app" directory, e.g. "/system", "/product".
      cipd_json_output: string path to pass to `cipd create` via -json-output.
      dry_run: When set to True, it will skip the CIPD package creation
        after creating the AVD.
    """
        logging.info('Installing required packages.')
        self._InstallCipdPackages(packages=[
            self._config.emulator_package,
            self._config.system_image_package,
        ])

        android_avd_home = self._avd_home

        if not os.path.exists(android_avd_home):
            os.makedirs(android_avd_home)

        avd_manager = _AvdManagerAgent(avd_home=android_avd_home,
                                       sdk_root=self._emulator_sdk_root)

        logging.info('Creating AVD.')
        avd_manager.Create(avd_name=self._config.avd_name,
                           system_image=self._config.system_image_name,
                           force=force)

        try:
            logging.info('Modifying AVD configuration.')

            # Clear out any previous configuration or state from this AVD.
            root_ini = os.path.join(android_avd_home,
                                    '%s.ini' % self._config.avd_name)
            features_ini = os.path.join(self._emulator_home,
                                        'advancedFeatures.ini')
            avd_dir = self._avd_dir

            with ini.update_ini_file(root_ini) as root_ini_contents:
                root_ini_contents[
                    'path.rel'] = 'avd/%s.avd' % self._config.avd_name

            with ini.update_ini_file(features_ini) as features_ini_contents:
                # features_ini file will not be refreshed by avdmanager during
                # creation. So explicitly clear its content to exclude any leftover
                # from previous creation.
                features_ini_contents.clear()
                features_ini_contents.update(
                    self.avd_settings.advanced_features)

            with ini.update_ini_file(
                    self._config_ini_path) as config_ini_contents:
                height = self.avd_settings.screen.height or _DEFAULT_SCREEN_HEIGHT
                width = self.avd_settings.screen.width or _DEFAULT_SCREEN_WIDTH
                density = self.avd_settings.screen.density or _DEFAULT_SCREEN_DENSITY

                config_ini_contents.update({
                    'disk.dataPartition.size': '4G',
                    'hw.keyboard': 'yes',
                    'hw.lcd.density': density,
                    'hw.lcd.height': height,
                    'hw.lcd.width': width,
                    'hw.mainKeys': 'no',  # Show nav buttons on screen
                })

                if self.avd_settings.ram_size:
                    config_ini_contents[
                        'hw.ramSize'] = self.avd_settings.ram_size

                config_ini_contents['hw.sdCard'] = 'yes'
                if self.avd_settings.sdcard.size:
                    sdcard_path = os.path.join(avd_dir, _SDCARD_NAME)
                    mksdcard_path = os.path.join(
                        os.path.dirname(self._emulator_path), 'mksdcard')
                    cmd_helper.RunCmd([
                        mksdcard_path,
                        self.avd_settings.sdcard.size,
                        sdcard_path,
                    ])
                    config_ini_contents['hw.sdCard.path'] = sdcard_path

            # Start & stop the AVD.
            self._Initialize()
            instance = _AvdInstance(self._emulator_path, self._emulator_home,
                                    self._config)
            # Enable debug for snapshot when it is set to True
            debug_tags = 'init,snapshot' if snapshot else None
            # Installing privileged apks requires modifying the system image.
            writable_system = bool(privileged_apk_tuples)
            instance.Start(ensure_system_settings=False,
                           read_only=False,
                           writable_system=writable_system,
                           gpu_mode=_DEFAULT_GPU_MODE,
                           debug_tags=debug_tags)

            assert instance.device is not None, '`instance.device` not initialized.'
            # Android devices with full-disk encryption are encrypted on first boot,
            # and then get decrypted to continue the boot process (See details in
            # https://bit.ly/3agmjcM).
            # Wait for this step to complete since it can take a while for old OSs
            # like M, otherwise the avd may have "Encryption Unsuccessful" error.
            instance.device.WaitUntilFullyBooted(decrypt=True,
                                                 timeout=180,
                                                 retries=0)

            if additional_apks:
                for additional_apk in additional_apks:
                    instance.device.Install(additional_apk,
                                            allow_downgrade=True,
                                            reinstall=True)

            if privileged_apk_tuples:
                system_app.InstallPrivilegedApps(instance.device,
                                                 privileged_apk_tuples)

            # Always disable the network to prevent built-in system apps from
            # updating themselves, which could take over package manager and
            # cause shell command timeout.
            logging.info('Disabling the network.')
            settings.ConfigureContentSettings(
                instance.device, settings.NETWORK_DISABLED_SETTINGS)

            if snapshot:
                # Reboot so that changes like disabling network can take effect.
                instance.device.Reboot()
                instance.SaveSnapshot()

            instance.Stop()

            # The multiinstance lock file seems to interfere with the emulator's
            # operation in some circumstances (beyond the obvious -read-only ones),
            # and there seems to be no mechanism by which it gets closed or deleted.
            # See https://bit.ly/2pWQTH7 for context.
            multiInstanceLockFile = os.path.join(avd_dir, 'multiinstance.lock')
            if os.path.exists(multiInstanceLockFile):
                os.unlink(multiInstanceLockFile)

            package_def_content = {
                'package':
                self._config.avd_package.package_name,
                'root':
                self._emulator_home,
                'install_mode':
                'copy',
                'data': [{
                    'dir': os.path.relpath(avd_dir, self._emulator_home)
                }, {
                    'file': os.path.relpath(root_ini, self._emulator_home)
                }, {
                    'file':
                    os.path.relpath(features_ini, self._emulator_home)
                }],
            }

            logging.info('Creating AVD CIPD package.')
            logging.debug('ensure file content: %s',
                          json.dumps(package_def_content, indent=2))

            with tempfile_ext.TemporaryFileName(
                    suffix='.json') as package_def_path:
                with open(package_def_path, 'w') as package_def_file:
                    json.dump(package_def_content, package_def_file)

                logging.info('  %s', self._config.avd_package.package_name)
                cipd_create_cmd = [
                    'cipd',
                    'create',
                    '-pkg-def',
                    package_def_path,
                    '-tag',
                    'emulator_version:%s' %
                    self._config.emulator_package.version,
                    '-tag',
                    'system_image_version:%s' %
                    self._config.system_image_package.version,
                ]
                if cipd_json_output:
                    cipd_create_cmd.extend([
                        '-json-output',
                        cipd_json_output,
                    ])
                logging.info('running %r%s', cipd_create_cmd,
                             ' (dry_run)' if dry_run else '')
                if not dry_run:
                    try:
                        for line in cmd_helper.IterCmdOutputLines(
                                cipd_create_cmd):
                            logging.info('    %s', line)
                    except subprocess.CalledProcessError as e:
                        # avd.py is executed with python2.
                        # pylint: disable=W0707
                        raise AvdException('CIPD package creation failed: %s' %
                                           str(e),
                                           command=cipd_create_cmd)

        finally:
            if not keep:
                logging.info('Deleting AVD.')
                avd_manager.Delete(avd_name=self._config.avd_name)
예제 #15
0
 def testIterCmdOutputLines_exitStatusIgnored(self):
   for num, line in enumerate(
       cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True,
                                     check_status=False), 1):
     self.assertEquals(num, int(line))
예제 #16
0
    def Create(self,
               force=False,
               snapshot=False,
               keep=False,
               cipd_json_output=None):
        """Create an instance of the AVD CIPD package.

    This method:
     - installs the requisite system image
     - creates the AVD
     - modifies the AVD's ini files to support running chromium tests
       in chromium infrastructure
     - optionally starts & stops the AVD for snapshotting (default no)
     - creates and uploads an instance of the AVD CIPD package
     - optionally deletes the AVD (default yes)

    Args:
      force: bool indicating whether to force create the AVD.
      snapshot: bool indicating whether to snapshot the AVD before creating
        the CIPD package.
      keep: bool indicating whether to keep the AVD after creating
        the CIPD package.
      cipd_json_output: string path to pass to `cipd create` via -json-output.
    """
        logging.info('Installing required packages.')
        self.Install(packages=[
            self._config.emulator_package,
            self._config.system_image_package,
        ])

        android_avd_home = os.path.join(self._emulator_home, 'avd')

        if not os.path.exists(android_avd_home):
            os.makedirs(android_avd_home)

        avd_manager = _AvdManagerAgent(avd_home=android_avd_home,
                                       sdk_root=self._emulator_sdk_root)

        logging.info('Creating AVD.')
        avd_manager.Create(avd_name=self._config.avd_name,
                           system_image=self._config.system_image_name,
                           force=force,
                           sdcard=self._config.avd_settings.sdcard.size)

        try:
            logging.info('Modifying AVD configuration.')

            # Clear out any previous configuration or state from this AVD.
            root_ini = os.path.join(android_avd_home,
                                    '%s.ini' % self._config.avd_name)
            avd_dir = os.path.join(android_avd_home,
                                   '%s.avd' % self._config.avd_name)
            config_ini = os.path.join(avd_dir, 'config.ini')

            with open(root_ini, 'a') as root_ini_file:
                root_ini_file.write('path.rel=avd/%s.avd\n' %
                                    self._config.avd_name)

            height = (self._config.avd_settings.screen.height
                      or _DEFAULT_SCREEN_HEIGHT)
            width = (self._config.avd_settings.screen.width
                     or _DEFAULT_SCREEN_WIDTH)
            density = (self._config.avd_settings.screen.density
                       or _DEFAULT_SCREEN_DENSITY)

            with open(config_ini, 'a') as config_ini_file:
                config_ini_contents = _CONFIG_INI_CONTENTS.format(
                    density=density, height=height, width=width)
                config_ini_file.write(config_ini_contents)

            # Start & stop the AVD.
            self._Initialize()
            instance = _AvdInstance(self._emulator_path, self._config.avd_name,
                                    self._emulator_home)
            instance.Start(read_only=False, snapshot_save=snapshot)
            device_utils.DeviceUtils(instance.serial).WaitUntilFullyBooted(
                timeout=180, retries=0)
            instance.Stop()

            # The multiinstance lock file seems to interfere with the emulator's
            # operation in some circumstances (beyond the obvious -read-only ones),
            # and there seems to be no mechanism by which it gets closed or deleted.
            # See https://bit.ly/2pWQTH7 for context.
            multiInstanceLockFile = os.path.join(avd_dir, 'multiinstance.lock')
            if os.path.exists(multiInstanceLockFile):
                os.unlink(multiInstanceLockFile)

            package_def_content = {
                'package':
                self._config.avd_package.package_name,
                'root':
                self._emulator_home,
                'install_mode':
                'copy',
                'data': [
                    {
                        'dir': os.path.relpath(avd_dir, self._emulator_home)
                    },
                    {
                        'file': os.path.relpath(root_ini, self._emulator_home)
                    },
                ],
            }

            logging.info('Creating AVD CIPD package.')
            logging.debug('ensure file content: %s',
                          json.dumps(package_def_content, indent=2))

            with tempfile_ext.TemporaryFileName(
                    suffix='.json') as package_def_path:
                with open(package_def_path, 'w') as package_def_file:
                    json.dump(package_def_content, package_def_file)

                logging.info('  %s', self._config.avd_package.package_name)
                cipd_create_cmd = [
                    'cipd',
                    'create',
                    '-pkg-def',
                    package_def_path,
                ]
                if cipd_json_output:
                    cipd_create_cmd.extend([
                        '-json-output',
                        cipd_json_output,
                    ])
                try:
                    for line in cmd_helper.IterCmdOutputLines(cipd_create_cmd):
                        logging.info('    %s', line)
                except subprocess.CalledProcessError as e:
                    raise AvdException('CIPD package creation failed: %s' %
                                       str(e),
                                       command=cipd_create_cmd)

        finally:
            if not keep:
                logging.info('Deleting AVD.')
                avd_manager.Delete(avd_name=self._config.avd_name)
예제 #17
0
 def testIterCmdOutputLines_success(self):
   for num, line in enumerate(
       cmd_helper.IterCmdOutputLines(['seq', '10']), 1):
     self.assertEquals(num, int(line))
예제 #18
0
    def Create(self,
               force=False,
               snapshot=False,
               keep=False,
               cipd_json_output=None):
        """Create an instance of the AVD CIPD package.

    This method:
     - installs the requisite system image
     - creates the AVD
     - modifies the AVD's ini files to support running chromium tests
       in chromium infrastructure
     - optionally starts & stops the AVD for snapshotting (default no)
     - creates and uploads an instance of the AVD CIPD package
     - optionally deletes the AVD (default yes)

    Args:
      force: bool indicating whether to force create the AVD.
      snapshot: bool indicating whether to snapshot the AVD before creating
        the CIPD package.
      keep: bool indicating whether to keep the AVD after creating
        the CIPD package.
      cipd_json_output: string path to pass to `cipd create` via -json-output.
    """
        logging.info('Installing required packages.')
        self.Install(packages=[self._config.system_image_package])

        android_avd_home = os.path.join(self._emulator_home, 'avd')

        if not os.path.exists(android_avd_home):
            os.makedirs(android_avd_home)

        avd_manager = _AvdManagerAgent(avd_home=android_avd_home,
                                       sdk_root=self._emulator_sdk_root)

        logging.info('Creating AVD.')
        avd_manager.Create(avd_name=self._config.avd_name,
                           system_image=self._config.system_image_name,
                           force=force)

        try:
            logging.info('Modifying AVD configuration.')

            root_ini = os.path.join(android_avd_home,
                                    '%s.ini' % self._config.avd_name)
            avd_dir = os.path.join(android_avd_home,
                                   '%s.avd' % self._config.avd_name)
            config_ini = os.path.join(avd_dir, 'config.ini')

            with open(root_ini, 'a') as root_ini_file:
                root_ini_file.write('path.rel=avd/%s.avd\n' %
                                    self._config.avd_name)

            with open(config_ini, 'a') as config_ini_file:
                config_ini_file.write('disk.dataPartition.size=4G\n')

            # Start & stop the AVD.
            if snapshot:
                # TODO(crbug.com/922145): Implement support for snapshotting.
                raise NotImplementedError('Snapshotting is not supported yet.')

            package_def_content = {
                'package':
                self._config.avd_package.package_name,
                'root':
                self._emulator_home,
                'install_mode':
                'copy',
                'data': [
                    {
                        'dir': os.path.relpath(avd_dir, self._emulator_home)
                    },
                    {
                        'file': os.path.relpath(root_ini, self._emulator_home)
                    },
                ],
            }

            logging.info('Creating AVD CIPD package.')
            logging.debug('ensure file content: %s',
                          json.dumps(package_def_content, indent=2))

            with tempfile_ext.TemporaryFileName(
                    suffix='.json') as package_def_path:
                with open(package_def_path, 'w') as package_def_file:
                    json.dump(package_def_content, package_def_file)

                logging.info('  %s', self._config.avd_package.package_name)
                cipd_create_cmd = [
                    'cipd',
                    'create',
                    '-pkg-def',
                    package_def_path,
                ]
                if cipd_json_output:
                    cipd_create_cmd.extend([
                        '-json-output',
                        cipd_json_output,
                    ])
                try:
                    for line in cmd_helper.IterCmdOutputLines(cipd_create_cmd):
                        logging.info('    %s', line)
                except subprocess.CalledProcessError as e:
                    raise AvdException('CIPD package creation failed: %s' %
                                       str(e),
                                       command=cipd_create_cmd)

        finally:
            if not keep:
                logging.info('Deleting AVD.')
                avd_manager.Delete(avd_name=self._config.avd_name)