Exemplo n.º 1
0
def _GetAttachedDevices(test_device=None):
    """Get all attached devices.

  Args:
    test_device: Name of a specific device to use.

  Returns:
    A list of attached devices.
  """
    attached_devices = device_utils.DeviceUtils.HealthyDevices()
    if test_device:
        test_device = [d for d in attached_devices if d == test_device]
        if not test_device:
            raise device_errors.DeviceUnreachableError(
                'Did not find device %s among attached device. Attached devices: %s'
                % (test_device, ', '.join(attached_devices)))
        return test_device

    else:
        if not attached_devices:
            raise device_errors.NoDevicesError()
        return sorted(attached_devices)
Exemplo n.º 2
0
    def InitShell(self, origin='localhost', device=None):
        """
    Runs adb as root, starts an origin server, and installs the apk as needed.
    |origin| is the origin for mojo: URLs; if its value is 'localhost', a local
    http server will be set up to serve files from the build directory.
    |device| is the target device to run on, if multiple devices are connected.
    Returns 0 on success or a non-zero exit code on a terminal failure.
    """
        try:
            devices = device_utils.DeviceUtils.HealthyDevices()
            if device:
                self.device = next((d for d in devices if d == device), None)
                if not self.device:
                    raise device_errors.DeviceUnreachableError(device)
            elif devices:
                self.device = devices[0]
            else:
                raise device_errors.NoDevicesError()

            logging.getLogger().debug("Using device: %s", self.device)
            # Clean the logs on the device to avoid displaying prior activity.
            subprocess.check_call(self._CreateADBCommand(['logcat', '-c']))
            self.device.EnableRoot()
            self.device.Install(self.paths.apk_path)
        except base_error.BaseError as e:
            # Report "device not found" as infra failures. See http://crbug.com/493900
            print "Exception in AndroidShell.InitShell:\n%s" % str(e)
            if e.is_infra_error or "error: device not found" in str(e):
                return constants.INFRA_EXIT_CODE
            return constants.ERROR_EXIT_CODE

        if origin is 'localhost':
            origin = self._StartHttpServerForDirectory(self.paths.build_dir)
        if origin:
            self.shell_args.append("--origin=" + origin)
        return 0
Exemplo n.º 3
0
def ProvisionDevices(args):
    if args.blacklist_file:
        blacklist = device_blacklist.Blacklist(args.blacklist_file)
    else:
        # TODO(jbudorick): Remove once the bots have switched over.
        blacklist = device_blacklist.Blacklist(device_blacklist.BLACKLIST_JSON)

    devices = device_utils.DeviceUtils.HealthyDevices(blacklist)
    if args.device:
        devices = [d for d in devices if d == args.device]
        if not devices:
            raise device_errors.DeviceUnreachableError(args.device)

    parallel_devices = device_utils.DeviceUtils.parallel(devices)
    parallel_devices.pMap(ProvisionDevice, blacklist, args)
    if args.auto_reconnect:
        _LaunchHostHeartbeat()
    blacklisted_devices = blacklist.Read()
    if args.output_device_blacklist:
        with open(args.output_device_blacklist, 'w') as f:
            json.dump(blacklisted_devices, f)
    if all(d in blacklisted_devices for d in devices):
        raise device_errors.NoDevicesError
    return 0
    def _ParseTestOutput(self, p):
        """Process the test output.

    Args:
      p: An instance of pexpect spawn class.

    Returns:
      A TestRunResults object.
    """
        results = base_test_result.TestRunResults()

        log = ''
        try:
            while True:
                full_test_name = None

                found = p.expect([RE_RUN, RE_PASSED, RE_RUNNER_FAIL],
                                 timeout=self._timeout)
                if found == 1:  # RE_PASSED
                    break
                elif found == 2:  # RE_RUNNER_FAIL
                    break
                else:  # RE_RUN
                    full_test_name = p.match.group(1).replace('\r', '')
                    found = p.expect([RE_OK, RE_FAIL, RE_CRASH],
                                     timeout=self._timeout)
                    log = p.before.replace('\r', '')
                    if found == 0:  # RE_OK
                        if full_test_name == p.match.group(1).replace(
                                '\r', ''):
                            duration_ms = int(
                                p.match.group(3)) if p.match.group(3) else 0
                            results.AddResult(
                                base_test_result.BaseTestResult(
                                    full_test_name,
                                    base_test_result.ResultType.PASS,
                                    duration=duration_ms,
                                    log=log))
                    elif found == 2:  # RE_CRASH
                        results.AddResult(
                            base_test_result.BaseTestResult(
                                full_test_name,
                                base_test_result.ResultType.CRASH,
                                log=log))
                        break
                    else:  # RE_FAIL
                        duration_ms = int(
                            p.match.group(3)) if p.match.group(3) else 0
                        results.AddResult(
                            base_test_result.BaseTestResult(
                                full_test_name,
                                base_test_result.ResultType.FAIL,
                                duration=duration_ms,
                                log=log))
        except pexpect.EOF:
            logging.error('Test terminated - EOF')
            # We're here because either the device went offline, or the test harness
            # crashed without outputting the CRASHED marker (crbug.com/175538).
            if not self.device.IsOnline():
                raise device_errors.DeviceUnreachableError(
                    'Device %s went offline.' % str(self.device))
            if full_test_name:
                results.AddResult(
                    base_test_result.BaseTestResult(
                        full_test_name,
                        base_test_result.ResultType.CRASH,
                        log=p.before.replace('\r', '')))
        except pexpect.TIMEOUT:
            logging.error('Test terminated after %d second timeout.',
                          self._timeout)
            if full_test_name:
                results.AddResult(
                    base_test_result.BaseTestResult(
                        full_test_name,
                        base_test_result.ResultType.TIMEOUT,
                        log=p.before.replace('\r', '')))
        finally:
            p.close()

        ret_code = self.test_package.GetGTestReturnCode(self.device)
        if ret_code:
            logging.critical(
                'gtest exit code: %d\npexpect.before: %s\npexpect.after: %s',
                ret_code, p.before, p.after)

        return results
Exemplo n.º 5
0
  def _ParseTestOutput(self, p):
    """Process the test output.

    Args:
      p: An instance of pexpect spawn class.

    Returns:
      A TestRunResults object.
    """
    results = base_test_result.TestRunResults()

    # Test case statuses.
    re_run = re.compile('\[ RUN      \] ?(.*)\r\n')
    re_fail = re.compile('\[  FAILED  \] ?(.*)\r\n')
    re_ok = re.compile('\[       OK \] ?(.*?) .*\r\n')

    # Test run statuses.
    re_passed = re.compile('\[  PASSED  \] ?(.*)\r\n')
    re_runner_fail = re.compile('\[ RUNNER_FAILED \] ?(.*)\r\n')
    # Signal handlers are installed before starting tests
    # to output the CRASHED marker when a crash happens.
    re_crash = re.compile('\[ CRASHED      \](.*)\r\n')

    log = ''
    try:
      while True:
        full_test_name = None
        found = p.expect([re_run, re_passed, re_runner_fail],
                         timeout=self._timeout)
        if found == 1:  # re_passed
          break
        elif found == 2:  # re_runner_fail
          break
        else:  # re_run
          full_test_name = p.match.group(1).replace('\r', '')
          found = p.expect([re_ok, re_fail, re_crash], timeout=self._timeout)
          log = p.before.replace('\r', '')
          if found == 0:  # re_ok
            if full_test_name == p.match.group(1).replace('\r', ''):
              results.AddResult(base_test_result.BaseTestResult(
                  full_test_name, base_test_result.ResultType.PASS,
                  log=log))
          elif found == 2:  # re_crash
            results.AddResult(base_test_result.BaseTestResult(
                full_test_name, base_test_result.ResultType.CRASH,
                log=log))
            break
          else:  # re_fail
            results.AddResult(base_test_result.BaseTestResult(
                full_test_name, base_test_result.ResultType.FAIL, log=log))
    except pexpect.EOF:
      logging.error('Test terminated - EOF')
      # We're here because either the device went offline, or the test harness
      # crashed without outputting the CRASHED marker (crbug.com/175538).
      if not self.device.IsOnline():
        raise device_errors.DeviceUnreachableError(
            'Device %s went offline.' % str(self.device))
      if full_test_name:
        results.AddResult(base_test_result.BaseTestResult(
            full_test_name, base_test_result.ResultType.CRASH,
            log=p.before.replace('\r', '')))
    except pexpect.TIMEOUT:
      logging.error('Test terminated after %d second timeout.',
                    self._timeout)
      if full_test_name:
        results.AddResult(base_test_result.BaseTestResult(
            full_test_name, base_test_result.ResultType.TIMEOUT,
            log=p.before.replace('\r', '')))
    finally:
      p.close()

    ret_code = self.test_package.GetGTestReturnCode(self.device)
    if ret_code:
      logging.critical(
          'gtest exit code: %d\npexpect.before: %s\npexpect.after: %s',
          ret_code, p.before, p.after)

    return results
Exemplo n.º 6
0
def _RunTestsFromQueue(runner, collection, out_results, watcher,
                       num_retries, tag_results_with_device=False):
  """Runs tests from the collection until empty using the given runner.

  Adds TestRunResults objects to the out_results list and may add tests to the
  out_retry list.

  Args:
    runner: A TestRunner object used to run the tests.
    collection: A TestCollection from which to get _Test objects to run.
    out_results: A list to add TestRunResults to.
    watcher: A watchdog_timer.WatchdogTimer object, used as a shared timeout.
    num_retries: Number of retries for a test.
    tag_results_with_device: If True, appends the name of the device on which
        the test was run to the test name. Used when replicating to identify
        which device ran each copy of the test, and to ensure each copy of the
        test is recorded separately.
  """

  def TagTestRunResults(test_run_results):
    """Tags all results with the last 4 digits of the device id.

    Used when replicating tests to distinguish the same tests run on different
    devices. We use a set to store test results, so the hash (generated from
    name and tag) must be unique to be considered different results.
    """
    new_test_run_results = base_test_result.TestRunResults()
    for test_result in test_run_results.GetAll():
      test_result.SetName('%s_%s' % (runner.device_serial[-4:],
                                     test_result.GetName()))
      new_test_run_results.AddResult(test_result)
    return new_test_run_results

  for test in collection:
    watcher.Reset()
    try:
      if not runner.device.IsOnline():
        # Device is unresponsive, stop handling tests on this device.
        msg = 'Device %s is unresponsive.' % runner.device_serial
        logging.warning(msg)
        raise device_errors.DeviceUnreachableError(msg)
      result, retry = runner.RunTest(test.test)
      if tag_results_with_device:
        result = TagTestRunResults(result)
      test.tries += 1
      if retry and test.tries <= num_retries:
        # Retry non-passing results, only record passing results.
        pass_results = base_test_result.TestRunResults()
        pass_results.AddResults(result.GetPass())
        out_results.append(pass_results)
        logging.warning('Will retry test %s, try #%s.', retry, test.tries)
        collection.add(_Test(test=retry, tries=test.tries))
      else:
        # All tests passed or retry limit reached. Either way, record results.
        out_results.append(result)
    except:
      # An unhandleable exception, ensure tests get run by another device and
      # reraise this exception on the main thread.
      collection.add(test)
      raise
    finally:
      # Retries count as separate tasks so always mark the popped test as done.
      collection.test_completed()
Exemplo n.º 7
0
def main():
    parser = argparse.ArgumentParser()

    apk_group = parser.add_mutually_exclusive_group(required=True)
    apk_group.add_argument('--apk',
                           dest='apk_name',
                           help='DEPRECATED The name of the apk containing the'
                           ' application (with the .apk extension).')
    apk_group.add_argument('apk_path',
                           nargs='?',
                           help='The path to the APK to install.')

    # TODO(jbudorick): Remove once no clients pass --apk_package
    parser.add_argument('--apk_package', help='DEPRECATED unused')
    parser.add_argument('--split',
                        action='append',
                        dest='splits',
                        help='A glob matching the apk splits. '
                        'Can be specified multiple times.')
    parser.add_argument('--keep_data',
                        action='store_true',
                        default=False,
                        help='Keep the package data when installing '
                        'the application.')
    parser.add_argument('--debug',
                        action='store_const',
                        const='Debug',
                        dest='build_type',
                        default=os.environ.get('BUILDTYPE', 'Debug'),
                        help='If set, run test suites under out/Debug. '
                        'Default is env var BUILDTYPE or Debug')
    parser.add_argument('--release',
                        action='store_const',
                        const='Release',
                        dest='build_type',
                        help='If set, run test suites under out/Release. '
                        'Default is env var BUILDTYPE or Debug.')
    parser.add_argument('-d',
                        '--device',
                        dest='device',
                        help='Target device for apk to install on.')
    parser.add_argument('-v',
                        '--verbose',
                        action='count',
                        help='Enable verbose logging.')

    args = parser.parse_args()

    run_tests_helper.SetLogLevel(args.verbose)
    constants.SetBuildType(args.build_type)

    apk = args.apk_path or args.apk_name
    if not apk.endswith('.apk'):
        apk += '.apk'
    if not os.path.exists(apk):
        apk = os.path.join(constants.GetOutDirectory(), 'apks', apk)
        if not os.path.exists(apk):
            parser.error('%s not found.' % apk)

    if args.splits:
        splits = []
        base_apk_package = apk_helper.ApkHelper(apk).GetPackageName()
        for split_glob in args.splits:
            apks = [f for f in glob.glob(split_glob) if f.endswith('.apk')]
            if not apks:
                logging.warning('No apks matched for %s.' % split_glob)
            for f in apks:
                helper = apk_helper.ApkHelper(f)
                if (helper.GetPackageName() == base_apk_package
                        and helper.GetSplitName()):
                    splits.append(f)

    devices = device_utils.DeviceUtils.HealthyDevices()

    if args.device:
        devices = [d for d in devices if d == args.device]
        if not devices:
            raise device_errors.DeviceUnreachableError(args.device)
    elif not devices:
        raise device_errors.NoDevicesError()

    def blacklisting_install(device):
        try:
            if args.splits:
                device.InstallSplitApk(apk, splits, reinstall=args.keep_data)
            else:
                device.Install(apk, reinstall=args.keep_data)
        except device_errors.CommandFailedError:
            logging.exception('Failed to install %s', args.apk_name)
            device_blacklist.ExtendBlacklist([str(device)])
            logging.warning('Blacklisting %s', str(device))
        except device_errors.CommandTimeoutError:
            logging.exception('Timed out while installing %s', args.apk_name)
            device_blacklist.ExtendBlacklist([str(device)])
            logging.warning('Blacklisting %s', str(device))

    device_utils.DeviceUtils.parallel(devices).pMap(blacklisting_install)
Exemplo n.º 8
0
def main():
    # Parse options.
    parser = optparse.OptionParser(description=__doc__,
                                   usage='screenshot.py [options] [filename]')
    parser.add_option('-d',
                      '--device',
                      metavar='ANDROID_DEVICE',
                      help='Serial '
                      'number of Android device to use.',
                      default=None)
    parser.add_option('--blacklist-file', help='Device blacklist JSON file.')
    parser.add_option('-f',
                      '--file',
                      help='Save result to file instead of '
                      'generating a timestamped file name.',
                      metavar='FILE')
    parser.add_option('-v',
                      '--verbose',
                      help='Verbose logging.',
                      action='store_true')
    video_options = optparse.OptionGroup(parser, 'Video capture')
    video_options.add_option('--video',
                             help='Enable video capturing. Requires '
                             'Android KitKat or later',
                             action='store_true')
    video_options.add_option('-b',
                             '--bitrate',
                             help='Bitrate in megabits/s, '
                             'from 0.1 to 100 mbps, %default mbps by default.',
                             default=4,
                             type='float')
    video_options.add_option('-r',
                             '--rotate',
                             help='Rotate video by 90 degrees.',
                             default=False,
                             action='store_true')
    video_options.add_option('-s',
                             '--size',
                             metavar='WIDTHxHEIGHT',
                             help='Frame size to use instead of the device '
                             'screen size.',
                             default=None)
    parser.add_option_group(video_options)

    (options, args) = parser.parse_args()

    if len(args) > 1:
        parser.error('Too many positional arguments.')
    host_file = args[0] if args else options.file

    if options.verbose:
        logging.getLogger().setLevel(logging.DEBUG)

    if options.blacklist_file:
        blacklist = device_blacklist.Blacklist(options.blacklist_file)
    else:
        blacklist = None

    devices = device_utils.DeviceUtils.HealthyDevices(blacklist)
    if options.device:
        device = next((d for d in devices if d == options.device), None)
        if not device:
            raise device_errors.DeviceUnreachableError(options.device)
    else:
        if len(devices) > 1:
            parser.error('Multiple devices are attached. '
                         'Please specify device serial number with --device.')
        elif len(devices) == 1:
            device = devices[0]
        else:
            raise device_errors.NoDevicesError()

    if options.video:
        _CaptureVideo(device, host_file, options)
    else:
        _CaptureScreenshot(device, host_file)
    return 0