You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
3.5 KiB
108 lines
3.5 KiB
# Copyright 2016 The Chromium OS Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
#
|
|
# This file contains things that are shared by arc.py and arc_util.py.
|
|
|
|
import logging
|
|
import subprocess
|
|
import time
|
|
|
|
from autotest_lib.client.bin import utils
|
|
from autotest_lib.client.common_lib import error
|
|
|
|
|
|
# Ask Chrome to start ARC instance and the script will block until ARC's boot
|
|
# completed event.
|
|
ARC_MODE_ENABLED = "enabled"
|
|
# Similar to "enabled", except that it will not block.
|
|
ARC_MODE_ENABLED_ASYNC = "enabled_async"
|
|
# Ask Chrome to not start ARC instance. This is the default.
|
|
ARC_MODE_DISABLED = "disabled"
|
|
# All available ARC options.
|
|
ARC_MODES = [ARC_MODE_ENABLED, ARC_MODE_ENABLED_ASYNC, ARC_MODE_DISABLED]
|
|
|
|
_BOOT_CHECK_INTERVAL_SECONDS = 2
|
|
_WAIT_FOR_ANDROID_BOOT_SECONDS = 120
|
|
|
|
_VAR_LOGCAT_PATH = '/var/log/logcat'
|
|
_VAR_LOGCAT_BOOT_PATH = '/var/log/logcat-boot'
|
|
|
|
|
|
class Logcat(object):
|
|
"""Saves the output of logcat to a file."""
|
|
|
|
def __init__(self, path=_VAR_LOGCAT_PATH):
|
|
with open(path, 'w') as f:
|
|
self._proc = subprocess.Popen(
|
|
['android-sh', '-c', 'logcat'],
|
|
stdout=f,
|
|
stderr=subprocess.STDOUT,
|
|
close_fds=True)
|
|
|
|
def __enter__(self):
|
|
"""Support for context manager."""
|
|
return self
|
|
|
|
def __exit__(self, *args):
|
|
"""Support for context manager.
|
|
|
|
Calls close().
|
|
"""
|
|
self.close()
|
|
|
|
def close(self):
|
|
"""Stop the logcat process gracefully."""
|
|
if not self._proc:
|
|
return
|
|
self._proc.terminate()
|
|
|
|
class TimeoutException(Exception):
|
|
"""Termination timeout timed out."""
|
|
|
|
try:
|
|
utils.poll_for_condition(
|
|
condition=lambda: self._proc.poll() is not None,
|
|
exception=TimeoutException,
|
|
timeout=10,
|
|
sleep_interval=0.1,
|
|
desc='Waiting for logcat to terminate')
|
|
except TimeoutException:
|
|
logging.info('Killing logcat due to timeout')
|
|
self._proc.kill()
|
|
self._proc.wait()
|
|
finally:
|
|
self._proc = None
|
|
|
|
|
|
def wait_for_android_boot(timeout=None):
|
|
"""Sleep until Android has completed booting or timeout occurs."""
|
|
if timeout is None:
|
|
timeout = _WAIT_FOR_ANDROID_BOOT_SECONDS
|
|
|
|
def _is_container_started():
|
|
return utils.system('android-sh -c true', ignore_status=True) == 0
|
|
|
|
def _is_android_booted():
|
|
output = utils.system_output(
|
|
'android-sh -c "getprop sys.boot_completed"', ignore_status=True)
|
|
return output.strip() == '1'
|
|
|
|
logging.info('Waiting for Android to boot completely.')
|
|
|
|
start_time = time.time()
|
|
utils.poll_for_condition(condition=_is_container_started,
|
|
desc='Container has started',
|
|
timeout=timeout,
|
|
exception=error.TestFail('Android did not boot!'),
|
|
sleep_interval=_BOOT_CHECK_INTERVAL_SECONDS)
|
|
with Logcat(_VAR_LOGCAT_BOOT_PATH):
|
|
boot_timeout = timeout - (time.time() - start_time)
|
|
utils.poll_for_condition(
|
|
condition=_is_android_booted,
|
|
desc='Android has booted',
|
|
timeout=boot_timeout,
|
|
exception=error.TestFail('Android did not boot!'),
|
|
sleep_interval=_BOOT_CHECK_INTERVAL_SECONDS)
|
|
logging.info('Android has booted completely.')
|