def FinishProvisioning(device, options):
  # The lockscreen can't be disabled on user builds, so send a keyevent
  # to unlock it.
  if device.IsUserBuild():
    device.SendKeyEvent(keyevent.KEYCODE_MENU)

  if options.min_battery_level is not None:
    try:
      battery = battery_utils.BatteryUtils(device)
      battery.ChargeDeviceToLevel(options.min_battery_level)
    except device_errors.CommandFailedError:
      logging.exception('Unable to charge device to specified level.')

  if options.max_battery_temp is not None:
    try:
      battery = battery_utils.BatteryUtils(device)
      battery.LetBatteryCoolToTemperature(options.max_battery_temp)
    except device_errors.CommandFailedError:
      logging.exception('Unable to let battery cool to specified temperature.')

  def _set_and_verify_date():
    if device.build_version_sdk >= version_codes.MARSHMALLOW:
      date_format = '%m%d%H%M%Y.%S'
      set_date_command = ['date']
    else:
      date_format = '%Y%m%d.%H%M%S'
      set_date_command = ['date', '-s']
    strgmtime = time.strftime(date_format, time.gmtime())
    set_date_command.append(strgmtime)
    device.RunShellCommand(set_date_command, as_root=True, check_return=True)

    device_time = device.RunShellCommand(
        ['date', '+"%Y%m%d.%H%M%S"'], as_root=True,
        single_line=True).replace('"', '')
    device_time = datetime.datetime.strptime(device_time, "%Y%m%d.%H%M%S")
    correct_time = datetime.datetime.strptime(strgmtime, date_format)
    tdelta = (correct_time - device_time).seconds
    if tdelta <= 1:
      logging.info('Date/time successfully set on %s', device)
      return True
    else:
      logging.error('Date mismatch. Device: %s Correct: %s',
                    device_time.isoformat(), correct_time.isoformat())
      return False

  # Sometimes the date is not set correctly on the devices. Retry on failure.
  if device.IsUserBuild():
    # TODO(bpastene): Figure out how to set the date & time on user builds.
    pass
  else:
    if not timeout_retry.WaitFor(
        _set_and_verify_date, wait_period=1, max_tries=2):
      raise device_errors.CommandFailedError(
          'Failed to set date & time.', device_serial=str(device))

  props = device.RunShellCommand('getprop', check_return=True)
  for prop in props:
    logging.info('  %s', prop)
  if options.auto_reconnect:
    _PushAndLaunchAdbReboot(device, options.target)
Esempio n. 2
0
  def WaitForFastbootMode(self, timeout=None, retries=None):
    """Wait for device to boot into fastboot mode.

    This waits for the device serial to show up in fastboot devices output.
    """
    timeout_retry.WaitFor(self.IsFastbootMode,
                          wait_period=self._FASTBOOT_WAIT_TIME)
Esempio n. 3
0
    def LetBatteryCoolToTemperature(self, target_temp, wait_period=180):
        """Lets device sit to give battery time to cool down
    Args:
      temp: maximum temperature to allow in tenths of degrees c.
      wait_period: time in seconds to wait between checking.
    """
        def cool_device():
            temp = self.GetBatteryInfo().get('temperature')
            if temp is None:
                logger.warning('Unable to find current battery temperature.')
                temp = 0
            else:
                logger.info('Current battery temperature: %s', temp)
            if int(temp) <= target_temp:
                return True
            else:
                if 'Nexus 5' in self._cache['profile']['name']:
                    self._DischargeDevice(1)
                return False

        self._DiscoverDeviceProfile()
        self.EnableBatteryUpdates()
        logger.info('Waiting for the device to cool down to %s (0.1 C)',
                    target_temp)
        timeout_retry.WaitFor(cool_device, wait_period=wait_period)
Esempio n. 4
0
    def _HardwareSetCharging(self, enabled, timeout=None, retries=None):
        """Enables or disables charging on the device.

    Args:
      enabled: A boolean indicating whether charging should be enabled or
        disabled.
      timeout: timeout in seconds
      retries: number of retries

    Raises:
      device_errors.CommandFailedError: If method of disabling charging cannot
        be determined.
    """
        self._DiscoverDeviceProfile()
        if not self._cache['profile']['enable_command']:
            raise device_errors.CommandFailedError(
                'Unable to find charging commands.')

        command = (self._cache['profile']['enable_command']
                   if enabled else self._cache['profile']['disable_command'])

        def verify_charging():
            return self.GetCharging() == enabled

        self._device.RunShellCommand(command,
                                     shell=True,
                                     check_return=True,
                                     as_root=True,
                                     large_output=True)
        timeout_retry.WaitFor(verify_charging, wait_period=1)
Esempio n. 5
0
  def _DischargeDevice(self, percent, wait_period=120):
    """Disables charging and waits for device to discharge given amount

    Args:
      percent: level of charge to discharge.

    Raises:
      ValueError: If percent is not between 1 and 99.
    """
    battery_level = int(self.GetBatteryInfo().get('level'))
    if not 0 < percent < 100:
      raise ValueError('Discharge amount(%s) must be between 1 and 99'
                       % percent)
    if battery_level is None:
      logger.warning('Unable to find current battery level. Cannot discharge.')
      return
    # Do not discharge if it would make battery level too low.
    if percent >= battery_level - 10:
      logger.warning('Battery is too low or discharge amount requested is too '
                     'high. Cannot discharge phone %s percent.', percent)
      return

    self._HardwareSetCharging(False)

    def device_discharged():
      self._HardwareSetCharging(True)
      current_level = int(self.GetBatteryInfo().get('level'))
      logger.info('current battery level: %s', current_level)
      if battery_level - current_level >= percent:
        return True
      self._HardwareSetCharging(False)
      return False

    timeout_retry.WaitFor(device_discharged, wait_period=wait_period)
Esempio n. 6
0
def main():
    logging.basicConfig(level=logging.INFO)
    parser = argparse.ArgumentParser(
        description='Fetches Crashpad dumps from a given device, '
        'walks and symbolizes the stacks.')
    parser.add_argument('--device', required=True, help='Device serial number')
    parser.add_argument('--adb-path',
                        required=True,
                        help='Path to the "adb" command')
    parser.add_argument(
        '--build-path',
        required=True,
        help='Build output directory, equivalent to CHROMIUM_OUTPUT_DIR')
    parser.add_argument(
        '--chrome-cache-path',
        required=True,
        help='Directory on the device where Chrome stores cached files,'
        ' crashpad stores dumps in a subdirectory of it')
    args = parser.parse_args()

    stackwalk_path = os.path.join(args.build_path, 'minidump_stackwalk')
    if not os.path.exists(stackwalk_path):
        logging.error('Missing minidump_stackwalk executable')
        return 1

    devil_chromium.Initialize(adb_path=args.adb_path)
    device = device_utils.DeviceUtils(args.device)

    device_crashpad_path = posixpath.join(args.chrome_cache_path, 'Crashpad',
                                          'pending')

    def CrashpadDumpExists():
        return _ChooseLatestCrashpadDump(device, device_crashpad_path)

    crashpad_file = timeout_retry.WaitFor(CrashpadDumpExists,
                                          wait_period=1,
                                          max_tries=9)
    if not crashpad_file:
        logging.error('Could not locate a crashpad dump')
        return 1

    dump_dir = tempfile.mkdtemp()
    symbols_dir = None
    try:
        device.PullFile(device_path=posixpath.join(device_crashpad_path,
                                                   crashpad_file),
                        host_path=dump_dir)
        dump_full_path = os.path.join(dump_dir, crashpad_file)
        library_names = _ExtractLibraryNamesFromDump(args.build_path,
                                                     dump_full_path)
        symbols_dir = _CreateSymbolsDir(args.build_path, library_names)
        stackwalk_cmd = [stackwalk_path, dump_full_path, symbols_dir]
        subprocess.call(stackwalk_cmd)
    finally:
        shutil.rmtree(dump_dir, ignore_errors=True)
        if symbols_dir:
            shutil.rmtree(symbols_dir, ignore_errors=True)
    return 0
Esempio n. 7
0
  def WaitForFastbootMode(self, timeout=None, retries=None):
    """Wait for presentation.device to boot into fastboot mode.

    This waits for the presentation.device serial to show up in fastboot devices output.
    """
    def fastboot_mode():
      return self._serial in self.fastboot.Devices()

    timeout_retry.WaitFor(fastboot_mode, wait_period=self._FASTBOOT_WAIT_TIME)
  def testStartServer(self):
    # Manually kill off any instances of adb.
    adb_pids = _hostAdbPids()
    for p in adb_pids:
      os.kill(p, signal.SIGKILL)

    self.assertIsNotNone(
        timeout_retry.WaitFor(
            lambda: not _hostAdbPids(), wait_period=0.1, max_tries=10))

    # start the adb server
    start_server_status, _ = cmd_helper.GetCmdStatusAndOutput(
        [adb_wrapper.AdbWrapper.GetAdbPath(), 'start-server'])

    # verify that the server is now online
    self.assertEquals(0, start_server_status)
    self.assertIsNotNone(
        timeout_retry.WaitFor(
            lambda: bool(_hostAdbPids()), wait_period=0.1, max_tries=10))
Esempio n. 9
0
def RestartServer():
    """Restarts the adb server.

  Raises:
    CommandFailedError if we fail to kill or restart the server.
  """
    def adb_killed():
        return not AdbWrapper.IsServerOnline()

    def adb_started():
        return AdbWrapper.IsServerOnline()

    AdbWrapper.KillServer()
    if not timeout_retry.WaitFor(adb_killed, wait_period=1, max_tries=5):
        # TODO(crbug.com/442319): Switch this to raise an exception if we
        # figure out why sometimes not all adb servers on bots get killed.
        logger.warning('Failed to kill adb server')
    AdbWrapper.StartServer()
    if not timeout_retry.WaitFor(adb_started, wait_period=1, max_tries=5):
        raise device_errors.CommandFailedError('Failed to start adb server')
def SetDate(device):
    def _set_and_verify_date():
        if device.build_version_sdk >= version_codes.MARSHMALLOW:
            date_format = '%m%d%H%M%Y.%S'
            set_date_command = ['date', '-u']
            get_date_command = ['date', '-u']
        else:
            date_format = '%Y%m%d.%H%M%S'
            set_date_command = ['date', '-s']
            get_date_command = ['date']

        # TODO(jbudorick): This is wrong on pre-M devices -- get/set are
        # dealing in local time, but we're setting based on GMT.
        strgmtime = time.strftime(date_format, time.gmtime())
        set_date_command.append(strgmtime)
        device.RunShellCommand(set_date_command,
                               as_root=True,
                               check_return=True)

        get_date_command.append('+"%Y%m%d.%H%M%S"')
        device_time = device.RunShellCommand(get_date_command,
                                             check_return=True,
                                             as_root=True,
                                             single_line=True).replace(
                                                 '"', '')
        device_time = datetime.datetime.strptime(device_time, "%Y%m%d.%H%M%S")
        correct_time = datetime.datetime.strptime(strgmtime, date_format)
        tdelta = (correct_time - device_time).seconds
        if tdelta <= 1:
            logger.info('Date/time successfully set on %s', device)
            return True
        else:
            logger.error('Date mismatch. Device: %s Correct: %s',
                         device_time.isoformat(), correct_time.isoformat())
            return False

    # Sometimes the date is not set correctly on the devices. Retry on failure.
    if device.IsUserBuild():
        # TODO(bpastene): Figure out how to set the date & time on user builds.
        pass
    else:
        if not timeout_retry.WaitFor(
                _set_and_verify_date, wait_period=1, max_tries=2):
            raise device_errors.CommandFailedError(
                'Failed to set date & time.', device_serial=str(device))
        device.EnableRoot()
        # The following intent can take a bit to complete when ran shortly after
        # device boot-up.
        device.BroadcastIntent(
            intent.Intent(action='android.intent.action.TIME_SET'),
            timeout=180)
Esempio n. 11
0
  def Start(self, timeout=None):
    """Start recording video."""
    def screenrecord_started():
      return bool(self._device.GetPids('screenrecord'))

    if screenrecord_started():
      raise Exception("Can't run multiple concurrent video captures.")

    self._started.clear()
    self._recorder_thread = reraiser_thread.ReraiserThread(self._Record)
    self._recorder_thread.start()
    timeout_retry.WaitFor(
        screenrecord_started, wait_period=1, max_tries=timeout)
    self._started.wait(timeout)
  def WaitForUiNode(self, timeout=None, retries=None, **kwargs):
    """Wait for a node matching a given criteria to appear on the screen.

    Args:
      timeout: A number of seconds to wait for the matching node to appear.
      retries: Number of times to retry in case of adb command errors.
      For other args, to specify the search criteria, see _UiNode._Find.
    Returns:
      The UI node instance found.
    Raises:
      device_errors.CommandTimeoutError if the node is not found before the
      timeout.
    """
    def node_found():
      return self.GetUiNode(**kwargs)

    return timeout_retry.WaitFor(node_found)
Esempio n. 13
0
            def crasher():
                def ready_to_crash():
                    try:
                        return trigger_text == self.device.ReadFile(
                            trigger_file.name, retries=0).strip()
                    except device_errors.CommandFailedError:
                        return False

                timeout_retry.WaitFor(ready_to_crash,
                                      wait_period=2,
                                      max_tries=10)
                if not ready_to_crash():
                    return False
                self.device.adb.Shell('echo c > /proc/sysrq-trigger',
                                      expect_status=None,
                                      timeout=60,
                                      retries=0)
                return True
Esempio n. 14
0
    def EnableBatteryUpdates(self, timeout=None, retries=None):
        """Restarts device charging so that dumpsys no longer collects power data.

    Args:
      timeout: timeout in seconds
      retries: number of retries

    Raises:
      device_errors.DeviceVersionError: If device is not L or higher.
    """
        def battery_updates_enabled():
            return (self.GetCharging() or
                    not bool('UPDATES STOPPED' in self._device.RunShellCommand(
                        ['dumpsys', 'battery'], check_return=True)))

        self._device.RunShellCommand(['dumpsys', 'battery', 'reset'],
                                     check_return=True)
        timeout_retry.WaitFor(battery_updates_enabled, wait_period=1)
Esempio n. 15
0
    def _ClearPowerData(self):
        """Resets battery data and makes device appear like it is not
    charging so that it will collect power data since last charge.

    Returns:
      True if power data cleared.
      False if power data clearing is not supported (pre-L)

    Raises:
      device_errors.DeviceVersionError: If power clearing is supported,
        but fails.
    """
        if self._device.build_version_sdk < version_codes.LOLLIPOP:
            logger.warning(
                'Dumpsys power data only available on 5.0 and above. '
                'Cannot clear power data.')
            return False

        self._device.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '1'],
                                     check_return=True)
        self._device.RunShellCommand(['dumpsys', 'battery', 'set', 'ac', '1'],
                                     check_return=True)

        def test_if_clear():
            self._device.RunShellCommand(
                ['dumpsys', 'batterystats', '--reset'], check_return=True)
            battery_data = self._device.RunShellCommand(
                ['dumpsys', 'batterystats', '--charged', '-c'],
                check_return=True,
                large_output=True)
            for line in battery_data:
                l = line.split(',')
                if (len(l) > _PWI_POWER_CONSUMPTION_INDEX
                        and l[_ROW_TYPE_INDEX] == 'pwi'
                        and float(l[_PWI_POWER_CONSUMPTION_INDEX]) != 0.0):
                    return False
            return True

        try:
            timeout_retry.WaitFor(test_if_clear, wait_period=1)
            return True
        finally:
            self._device.RunShellCommand(['dumpsys', 'battery', 'reset'],
                                         check_return=True)
Esempio n. 16
0
    def LetCpuCoolToTemperature(self, target_temp, wait_period=30):
        """Lets device sit to give CPU time to cool down.

      Implements a similar mechanism to
      battery_utils.LetBatteryCoolToTemperature

      Args:
        temp: A float containing the maximum temperature to allow
          in degrees c.
        wait_period: An integer indicating time in seconds to wait
          between checking.
    """
        target_temp = int(target_temp * self._device_info['temp_multiplier'])

        def cool_cpu():
            # Get the temperatures
            cpu_temp_paths = self._device_info['cpu_temps']
            temps = []
            for temp_path in cpu_temp_paths.values():
                temp_return = self._device.ReadFile(temp_path)
                # Output is an array of strings, only need the first line.
                temps.append(int(temp_return))

            if not temps:
                logger.warning('Unable to read temperature files provided.')
                return True

            logger.info('Current CPU temperatures: %s', str(temps)[1:-1])

            return all(t <= target_temp for t in temps)

        logger.info('Waiting for the CPU to cool down to %s',
                    target_temp / self._device_info['temp_multiplier'])

        # Set the governor to powersave to aid the cooling down of the CPU
        self._perf_control.SetScalingGovernor('powersave')

        # Retry 3 times, each time waiting 30 seconds.
        # This negates most (if not all) of the noise in recorded results without
        # taking too long
        timeout_retry.WaitFor(cool_cpu, wait_period=wait_period, max_tries=3)

        # Set the performance mode
        self._perf_control.SetHighPerfMode()
Esempio n. 17
0
    def read(self):
        """Get the object, creating it if necessary."""
        if self._initialized.is_set():
            return self._val
        with self._lock:
            if not self._initialized.is_set():
                # We initialize the value on a separate thread to protect
                # from holding self._lock indefinitely in the event that
                # self._initializer hangs.
                initializer_thread = reraiser_thread.ReraiserThread(
                    self._initializer)
                initializer_thread.start()
                timeout_retry.WaitFor(lambda: initializer_thread.join(1) or
                                      not initializer_thread.isAlive(),
                                      wait_period=0)
                self._val = initializer_thread.GetReturnValue()
                self._initialized.set()

        return self._val
Esempio n. 18
0
    def ChargeDeviceToLevel(self, level, wait_period=60):
        """Enables charging and waits for device to be charged to given level.

    Args:
      level: level of charge to wait for.
      wait_period: time in seconds to wait between checking.
    """
        self.SetCharging(True)

        def device_charged():
            battery_level = self.GetBatteryInfo().get('level')
            if battery_level is None:
                logging.warning('Unable to find current battery level.')
                battery_level = 100
            else:
                logging.info('current battery level: %s', battery_level)
                battery_level = int(battery_level)
            return battery_level >= level

        timeout_retry.WaitFor(device_charged, wait_period=wait_period)
Esempio n. 19
0
    def DisableBatteryUpdates(self, timeout=None, retries=None):
        """Resets battery data and makes device appear like it is not
    charging so that it will collect power data since last charge.

    Args:
      timeout: timeout in seconds
      retries: number of retries

    Raises:
      device_errors.CommandFailedError: When resetting batterystats fails to
        reset power values.
      device_errors.DeviceVersionError: If device is not L or higher.
    """
        def battery_updates_disabled():
            return self.GetCharging() is False

        self._ClearPowerData()
        self._device.RunShellCommand(['dumpsys', 'battery', 'set', 'ac', '0'],
                                     check_return=True)
        self._device.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '0'],
                                     check_return=True)
        timeout_retry.WaitFor(battery_updates_disabled, wait_period=1)
Esempio n. 20
0
  def ChargeDeviceToLevel(self, level, wait_period=60):
    """Enables charging and waits for device to be charged to given level.

    Args:
      level: level of charge to wait for.
      wait_period: time in seconds to wait between checking.
    Raises:
      device_errors.DeviceChargingError: If error while charging is detected.
    """
    self.SetCharging(True)
    charge_status = {
        'charge_failure_count': 0,
        'last_charge_value': 0
    }
    def device_charged():
      battery_level = self.GetBatteryInfo().get('level')
      if battery_level is None:
        logger.warning('Unable to find current battery level.')
        battery_level = 100
      else:
        logger.info('current battery level: %s', battery_level)
        battery_level = int(battery_level)

      # Use > so that it will not reset if charge is going down.
      if battery_level > charge_status['last_charge_value']:
        charge_status['last_charge_value'] = battery_level
        charge_status['charge_failure_count'] = 0
      else:
        charge_status['charge_failure_count'] += 1

      if (not battery_level >= level
          and charge_status['charge_failure_count'] >= _MAX_CHARGE_ERROR):
        raise device_errors.DeviceChargingError(
            'Device not charging properly. Current level:%s Previous level:%s'
             % (battery_level, charge_status['last_charge_value']))
      return battery_level >= level

    timeout_retry.WaitFor(device_charged, wait_period=wait_period)
Esempio n. 21
0
def FinishProvisioning(device, options):
  # The lockscreen can't be disabled on user builds, so send a keyevent
  # to unlock it.
  if device.IsUserBuild():
    device.SendKeyEvent(keyevent.KEYCODE_MENU)

  if options.min_battery_level is not None:
    battery = battery_utils.BatteryUtils(device)
    try:
      battery.ChargeDeviceToLevel(options.min_battery_level)
    except device_errors.DeviceChargingError:
      device.Reboot()
      battery.ChargeDeviceToLevel(options.min_battery_level)

  if options.max_battery_temp is not None:
    try:
      battery = battery_utils.BatteryUtils(device)
      battery.LetBatteryCoolToTemperature(options.max_battery_temp)
    except device_errors.CommandFailedError:
      logging.exception('Unable to let battery cool to specified temperature.')

  def _set_and_verify_date():
    if device.build_version_sdk >= version_codes.MARSHMALLOW:
      date_format = '%m%d%H%M%Y.%S'
      set_date_command = ['date', '-u']
      get_date_command = ['date', '-u']
    else:
      date_format = '%Y%m%d.%H%M%S'
      set_date_command = ['date', '-s']
      get_date_command = ['date']

    # TODO(jbudorick): This is wrong on pre-M devices -- get/set are
    # dealing in local time, but we're setting based on GMT.
    strgmtime = time.strftime(date_format, time.gmtime())
    set_date_command.append(strgmtime)
    device.RunShellCommand(set_date_command, as_root=True, check_return=True)

    get_date_command.append('+"%Y%m%d.%H%M%S"')
    device_time = device.RunShellCommand(
        get_date_command, as_root=True, single_line=True).replace('"', '')
    device_time = datetime.datetime.strptime(device_time, "%Y%m%d.%H%M%S")
    correct_time = datetime.datetime.strptime(strgmtime, date_format)
    tdelta = (correct_time - device_time).seconds
    if tdelta <= 1:
      logging.info('Date/time successfully set on %s', device)
      return True
    else:
      logging.error('Date mismatch. Device: %s Correct: %s',
                    device_time.isoformat(), correct_time.isoformat())
      return False

  if options.disable_selinux:
    device.RunShellCommand("su -c setenforce 0", as_root=True)
  if options.force_battery_status:
    device.RunShellCommand("dumpsys battery set status 5", as_root=True)
    device.RunShellCommand("dumpsys battery set level 100", as_root=True)

  if options.disable_predictive_keyboard:
    DisablePredictiveKeyboard(device)

  # Sometimes the date is not set correctly on the devices. Retry on failure.
  if device.IsUserBuild():
    # TODO(bpastene): Figure out how to set the date & time on user builds.
    pass
  else:
    # FIXME: Some samsung devices can not set the date and time. so we skip this.
    if False and not timeout_retry.WaitFor(_set_and_verify_date, wait_period=1,
                                 max_tries=2):
      raise device_errors.CommandFailedError(
          'Failed to set date & time.', device_serial=str(device))

  props = device.RunShellCommand('getprop', check_return=True)
  for prop in props:
    logging.info('  %s', prop)
  if options.auto_reconnect:
    _PushAndLaunchAdbReboot(device, options.target)
    correct_time = datetime.datetime.strptime(strgmtime, date_format)
    tdelta = (correct_time - device_time).seconds
    if tdelta <= 1:
      logger.info('Date/time successfully set on %s', presentation.device)
      return True
    else:
      logger.error('Date mismatch. Device: %s Correct: %s',
                   device_time.isoformat(), correct_time.isoformat())
      return False

  # Sometimes the date is not set correctly on the devices. Retry on failure.
  if presentation.device.IsUserBuild():
    # TODO(bpastene): Figure out how to set the date & time on user builds.
    pass
  else:
    if not timeout_retry.WaitFor(
        _set_and_verify_date, wait_period=1, max_tries=2):
      raise device_errors.CommandFailedError(
          'Failed to set date & time.', device_serial=str(presentation.device))
    presentation.device.EnableRoot()
    presentation.device.BroadcastIntent(
        intent.Intent(action='android.intent.action.TIME_SET'))


def LogDeviceProperties(presentation.device):
  props = presentation.device.RunShellCommand(['getprop'], check_return=True)
  for prop in props:
    logger.info('  %s', prop)


def CheckExternalStorage(presentation.device):
  """Checks that storage is writable and if not makes it writable.
Esempio n. 23
0
 def _FindDeviceWithTimeout(self):
     """Find which device to use with timeout."""
     timeout_retry.WaitFor(self._FindDevice, wait_period=1)
Esempio n. 24
0
def main():
    parser = CommandParser()
    args, extra_cmd_args = parser.parse_known_args(sys.argv[1:])

    logging.basicConfig(level=logging.INFO)
    if args.target:
        test_cmd = [os.path.join('bin', 'run_%s' % args.target), '-v']
        test_cmd += extra_cmd_args
    elif args.script:
        test_cmd = [args.script]
        test_cmd += extra_cmd_args
    else:
        test_cmd = extra_cmd_args

    test_env = dict(os.environ)
    logdog_cmd = []

    with tempfile_ext.NamedTemporaryDirectory(
            prefix='tmp_android_logdog_wrapper') as temp_directory:
        if not os.path.exists(args.logdog_bin_cmd):
            logging.error(
                'Logdog binary %s unavailable. Unable to create logdog client',
                args.logdog_bin_cmd)
        else:
            streamserver_uri = 'unix:%s' % os.path.join(
                temp_directory, 'butler.sock')
            prefix = os.path.join('android', 'swarming', 'logcats',
                                  os.environ.get('SWARMING_TASK_ID'))

            logdog_cmd = [
                args.logdog_bin_cmd, '-project', PROJECT, '-output', OUTPUT,
                '-prefix', prefix, '--service-account-json',
                SERVICE_ACCOUNT_JSON, '-coordinator-host', COORDINATOR_HOST,
                'serve', '-streamserver-uri', streamserver_uri
            ]
            test_env.update({
                'LOGDOG_STREAM_PROJECT': PROJECT,
                'LOGDOG_STREAM_PREFIX': prefix,
                'LOGDOG_STREAM_SERVER_PATH': streamserver_uri,
                'LOGDOG_COORDINATOR_HOST': COORDINATOR_HOST,
            })

        logdog_proc = None
        if logdog_cmd:
            logdog_proc = subprocess.Popen(logdog_cmd)

        with NoLeakingProcesses(logdog_proc):
            with NoLeakingProcesses(subprocess.Popen(
                    test_cmd, env=test_env)) as test_proc:
                with signal_handler.SignalHandler(
                        signal.SIGTERM, CreateStopTestsMethod(test_proc)):
                    result = test_proc.wait()
                    if logdog_proc:

                        def logdog_stopped():
                            return logdog_proc.poll() is not None

                        logdog_proc.terminate()
                        timeout_retry.WaitFor(
                            logdog_stopped,
                            wait_period=1,
                            max_tries=LOGDOG_TERMINATION_TIMEOUT)

                        # If logdog_proc hasn't finished by this point, allow
                        # NoLeakingProcesses to kill it.

    return result