Snap for 5434517 from b2010fc2ff94af33259503aa28daa6eb70ff4f2d to qt-release
Change-Id: I18b432b01913a7748ea39acb648319d60da7c5e7
diff --git a/client/site_tests/graphics_Sanity/control b/client/site_tests/graphics_Sanity/control
index ccb2b87..67ee566 100644
--- a/client/site_tests/graphics_Sanity/control
+++ b/client/site_tests/graphics_Sanity/control
@@ -8,7 +8,8 @@
CRITERIA = """
This test fails if application screen shots cannot capture the screen output.
"""
-ATTRIBUTES = ("suite:bvt-cq, suite:graphics, suite:graphics_per-day,"
+#TODO(pwang): crbug.com/948506, change suite:bvt-perbuild back to bvt-cq.
+ATTRIBUTES = ("suite:bvt-perbuild, suite:graphics, suite:graphics_per-day,"
"suite:graphics_system")
TIME='SHORT'
TEST_CATEGORY = 'Functional'
diff --git a/client/site_tests/touch_ScrollDirection/touch_ScrollDirection.py b/client/site_tests/touch_ScrollDirection/touch_ScrollDirection.py
index d38b7d5..69708ed 100644
--- a/client/site_tests/touch_ScrollDirection/touch_ScrollDirection.py
+++ b/client/site_tests/touch_ScrollDirection/touch_ScrollDirection.py
@@ -90,6 +90,9 @@
# Setup.
self._set_autotest_ext(cr.autotest_ext)
self._open_events_page(cr)
+ self._events.expand_page()
+ self._events.set_prevent_defaults(False)
+
self._emulate_mouse()
self._center_cursor()
diff --git a/server/cros/network/netperf_runner.py b/server/cros/network/netperf_runner.py
index 6b1158e..a63af25 100644
--- a/server/cros/network/netperf_runner.py
+++ b/server/cros/network/netperf_runner.py
@@ -525,7 +525,7 @@
def _restart_netserv(self):
logging.info('Starting netserver...')
self._kill_netserv()
- self._server_host.run('%s -p %d >/dev/null 2>&1' %
+ self._server_host.run('%s -p %d' %
(self._command_netserv, self.NETPERF_PORT))
startup_time = time.time()
self._client_proxy.firewall_open('tcp', self._server_proxy.wifi_ip)
diff --git a/site_utils/deployment/install.py b/site_utils/deployment/install.py
index fbba6d1..cece839 100644
--- a/site_utils/deployment/install.py
+++ b/site_utils/deployment/install.py
@@ -69,6 +69,7 @@
from autotest_lib.client.common_lib import time_utils
from autotest_lib.client.common_lib import utils
from autotest_lib.client.common_lib.cros import retry
+from autotest_lib.server import afe_utils
from autotest_lib.server import constants
from autotest_lib.server import frontend
from autotest_lib.server import hosts
@@ -505,14 +506,13 @@
@param host Host instance for the DUT being installed.
@param arguments Command line arguments with options.
"""
+ repair_image = _get_cros_repair_image_name(host)
+ logging.info('Using repair image %s', repair_image)
if arguments.dry_run:
return
if arguments.stageusb:
try:
- preparedut.download_image_to_servo_usb(
- host,
- host.get_cros_repair_image_name(),
- )
+ preparedut.download_image_to_servo_usb(host, repair_image)
except Exception as e:
logging.exception('Failed to stage image on USB: %s', e)
raise Exception('USB staging failed')
@@ -520,7 +520,7 @@
try:
if arguments.using_servo:
logging.debug('Install FW using servo.')
- preparedut.flash_firmware_using_servo(host)
+ preparedut.flash_firmware_using_servo(host, repair_image)
else:
logging.debug('Install FW by chromeos-firmwareupdate.')
preparedut.install_firmware(host, arguments.force_firmware)
@@ -831,6 +831,18 @@
return host_attributes
+def _get_cros_repair_image_name(host):
+ """Get the CrOS repair image name for given host.
+
+ @param host: hosts.CrosHost object. This object need not have an AFE
+ reference.
+ """
+ info = host.host_info_store.get()
+ if not info.board:
+ raise InstallFailedError('Unknown board for given host')
+ return afe_utils.get_stable_cros_image_name(info.board)
+
+
def install_duts(arguments):
"""Install a test image on DUTs, and deploy them.
diff --git a/site_utils/deployment/prepare/dut.py b/site_utils/deployment/prepare/dut.py
index 97af542..37dec6b 100644
--- a/site_utils/deployment/prepare/dut.py
+++ b/site_utils/deployment/prepare/dut.py
@@ -29,7 +29,7 @@
@contextlib.contextmanager
def create_host(hostname, board, model, servo_hostname, servo_port,
- servo_serial=None, uart_logs_dir=None):
+ servo_serial=None, logs_dir=None):
"""Yield a server.hosts.CrosHost object to use for DUT preparation.
This object contains just enough inventory data to be able to prepare the
@@ -43,7 +43,8 @@
@param servo_hostname: FQDN of the servo host controlling the DUT.
@param servo_port: Servo host port used for the controlling servo.
@param servo_serial: (Optional) Serial number of the controlling servo.
- @param uart_logs_dir: (Optional) Directory to save UART logs.
+ @param logs_dir: (Optional) Directory to save logs obtained from the
+ host.
@yield a server.hosts.Host object.
"""
@@ -72,7 +73,7 @@
**servo_host.get_servo_args_for_host(host))
_prepare_servo(servohost)
host.set_servo_host(servohost)
- host.servo.uart_logs_dir = uart_logs_dir
+ host.servo.uart_logs_dir = logs_dir
try:
yield host
finally:
@@ -88,14 +89,75 @@
host.servo.image_to_servo_usb(host.stage_image_for_servo(build))
-def flash_firmware_using_servo(host):
+def install_test_image(host):
+ """Install the test image for the given build to DUT.
+
+ This function assumes that the required image is already downloaded onto the
+ USB key connected to the DUT via servo.
+
+ @param host servers.host.Host object.
+ """
+ host.servo_install()
+
+
+def flash_firmware_using_servo(host, build):
"""Flash DUT firmware directly using servo.
Rather than running `chromeos-firmwareupdate` on DUT, we can flash DUT
firmware directly using servo (run command `flashrom`, etc. on servo). In
this way, we don't require DUT to be in dev mode and with dev_boot_usb
enabled."""
- host.firmware_install(build=host.get_cros_repair_image_name())
+ host.firmware_install(build)
+
+
+def install_firmware(host, force):
+ """Install dev-signed firmware after removing write-protect.
+
+ At start, it's assumed that hardware write-protect is disabled,
+ the DUT is in dev mode, and the servo's USB stick already has a
+ test image installed.
+
+ The firmware is installed by powering on and typing ctrl+U on
+ the keyboard in order to boot the test image from USB. Once
+ the DUT is booted, we run a series of commands to install the
+ read-only firmware from the test image. Then we clear debug
+ mode, and shut down.
+
+ @param host Host instance to use for servo and ssh operations.
+ @param force Boolean value determining if firmware install is forced.
+ """
+ servo = host.servo
+ # First power on. We sleep to allow the firmware plenty of time
+ # to display the dev-mode screen; some boards take their time to
+ # be ready for the ctrl+U after power on.
+ servo.get_power_state_controller().power_off()
+ servo.switch_usbkey('dut')
+ servo.get_power_state_controller().power_on()
+ time.sleep(10)
+ # Dev mode screen should be up now: type ctrl+U and wait for
+ # boot from USB to finish.
+ servo.ctrl_u()
+ if not host.wait_up(timeout=host.USB_BOOT_TIMEOUT):
+ raise Exception('DUT failed to boot in dev mode for '
+ 'firmware update')
+ # Disable software-controlled write-protect for both FPROMs, and
+ # install the RO firmware.
+ for fprom in ['host', 'ec']:
+ host.run('flashrom -p %s --wp-disable' % fprom,
+ ignore_status=True)
+
+ fw_update_log = '/mnt/stateful_partition/home/root/cros-fw-update.log'
+ pid = _start_firmware_update(host, force, fw_update_log)
+ _wait_firmware_update_process(host, pid)
+ _check_firmware_update_result(host, fw_update_log)
+
+ # Get us out of dev-mode and clear GBB flags. GBB flags are
+ # non-zero because boot from USB was enabled.
+ host.run('/usr/share/vboot/bin/set_gbb_flags.sh 0',
+ ignore_status=True)
+ host.run('crossystem disable_dev_request=1',
+ ignore_status=True)
+ host.halt()
def _start_firmware_update(host, force, result_file):
@@ -158,67 +220,6 @@
raise Exception("chromeos-firmwareupdate failed!")
-def install_firmware(host, force):
- """Install dev-signed firmware after removing write-protect.
-
- At start, it's assumed that hardware write-protect is disabled,
- the DUT is in dev mode, and the servo's USB stick already has a
- test image installed.
-
- The firmware is installed by powering on and typing ctrl+U on
- the keyboard in order to boot the test image from USB. Once
- the DUT is booted, we run a series of commands to install the
- read-only firmware from the test image. Then we clear debug
- mode, and shut down.
-
- @param host Host instance to use for servo and ssh operations.
- @param force Boolean value determining if firmware install is forced.
- """
- servo = host.servo
- # First power on. We sleep to allow the firmware plenty of time
- # to display the dev-mode screen; some boards take their time to
- # be ready for the ctrl+U after power on.
- servo.get_power_state_controller().power_off()
- servo.switch_usbkey('dut')
- servo.get_power_state_controller().power_on()
- time.sleep(10)
- # Dev mode screen should be up now: type ctrl+U and wait for
- # boot from USB to finish.
- servo.ctrl_u()
- if not host.wait_up(timeout=host.USB_BOOT_TIMEOUT):
- raise Exception('DUT failed to boot in dev mode for '
- 'firmware update')
- # Disable software-controlled write-protect for both FPROMs, and
- # install the RO firmware.
- for fprom in ['host', 'ec']:
- host.run('flashrom -p %s --wp-disable' % fprom,
- ignore_status=True)
-
- fw_update_log = '/mnt/stateful_partition/home/root/cros-fw-update.log'
- pid = _start_firmware_update(host, force, fw_update_log)
- _wait_firmware_update_process(host, pid)
- _check_firmware_update_result(host, fw_update_log)
-
- # Get us out of dev-mode and clear GBB flags. GBB flags are
- # non-zero because boot from USB was enabled.
- host.run('/usr/share/vboot/bin/set_gbb_flags.sh 0',
- ignore_status=True)
- host.run('crossystem disable_dev_request=1',
- ignore_status=True)
- host.halt()
-
-
-def install_test_image(host):
- """Install the test image for the given build to DUT.
-
- This function assumes that the required image is already downloaded onto the
- USB key connected to the DUT via servo.
-
- @param host servers.host.Host object.
- """
- host.servo_install()
-
-
def _prepare_servo(servohost):
"""Prepare servo connected to host for installation steps.
diff --git a/site_utils/deployment/prepare/main.py b/site_utils/deployment/prepare/main.py
old mode 100644
new mode 100755
index c35eb58..9a40a39
--- a/site_utils/deployment/prepare/main.py
+++ b/site_utils/deployment/prepare/main.py
@@ -1,45 +1,55 @@
-#!/usr/bin/env python
+#!/usr/bin/python -u
# Copyright 2019 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.
-"""Tool to (re)prepare a DUT for lab deployment.
-
-TODO(this docstring is a stub).
-"""
+"""Tool to (re)prepare a DUT for lab deployment."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
+import errno
import logging
+import logging.config
+import os
import common
+from autotest_lib.server import afe_utils
+from autotest_lib.server.hosts import file_store
from autotest_lib.site_utils.deployment.prepare import dut as preparedut
+
+class DutPreparationError(Exception):
+ """Generic error raised during DUT preparation."""
+
+
def main():
- """Tool to (re)prepare a DUT for lab deployment.
-
- TODO(this docstring is a stub).
- """
+ """Tool to (re)prepare a DUT for lab deployment."""
opts = _parse_args()
- # Setup tempfile to capture trash dropped by autotest?
- # Setup logging to avoid dumping everything to stdout?
- logging.basicConfig(level=logging.DEBUG)
+ _configure_logging('prepare_dut', os.path.join(opts.results_dir, _LOG_FILE))
- with preparedut.create_host(
- opts.hostname, opts.board, opts.model, opts.servo_hostname,
- opts.servo_port, opts.servo_serial, opts.uart_logs_dir) as host:
+ info = _read_store(opts.host_info_file)
+ repair_image = _get_cros_repair_image_name(info.board)
+ logging.info('Using repair image %s, obtained from AFE', repair_image)
+ with _create_host(opts.hostname, info, opts.results_dir) as host:
+ if opts.dry_run:
+ logging.info('DRY RUN: Would have run actions %s', opts.actions)
+ return
if 'stage-usb' in opts.actions:
- preparedut.download_image_to_servo_usb(host, opts.build)
+ preparedut.download_image_to_servo_usb(host, repair_image)
if 'install-firmware' in opts.actions:
preparedut.install_firmware(host, opts.force_firmware)
if 'install-test-image' in opts.actions:
preparedut.install_test_image(host)
+_LOG_FILE = 'prepare_dut.log'
+_DUT_LOGS_DIR = 'dut_logs'
+
+
def _parse_args():
parser = argparse.ArgumentParser(
description='Prepare / validate DUT for lab deployment.')
@@ -51,53 +61,132 @@
help='DUT preparation actions to execute.',
)
parser.add_argument(
+ '--dry-run',
+ action='store_true',
+ default=False,
+ help='Run in dry-run mode. No changes will be made to the DUT.',
+ )
+ parser.add_argument(
+ '--results-dir',
+ required=True,
+ help='Directory to drop logs and output artifacts in.',
+ )
+
+ parser.add_argument(
'--hostname',
required=True,
help='Hostname of the DUT to prepare.',
)
-
parser.add_argument(
- '--board',
+ '--host-info-file',
required=True,
- help='Board label of the DUT to prepare.',
- )
- parser.add_argument(
- '--model',
- required=True,
- help='Model label of the DUT to prepare.',
- )
- parser.add_argument(
- '--build',
- required=True,
- help='Chrome OS image version to use for installation.',
+ help=('Full path to HostInfo file.'
+ ' DUT inventory information is read from the HostInfo file.'),
)
parser.add_argument(
- '--servo-hostname',
- required=True,
- help='Hostname of the servo host connected to the DUT.',
- )
- parser.add_argument(
- '--servo-port',
- required=True,
- help='Servo host port (to be) used for the controlling servo.',
- )
- parser.add_argument(
- '--servo-serial',
- help='Serial number of the controlling servo.',
- )
- parser.add_argument(
'--force-firmware',
action='store_true',
help='Force firmware isntallation via chromeos-installfirmware.',
)
- parser.add_argument(
- '--uart-logs-dir',
- help='The directory to save UART logs.'
- )
return parser.parse_args()
+def _configure_logging(name, tee_file):
+ """Configure logging globally.
+
+ @param name: Name to prepend to log messages.
+ This should be the name of the program.
+ @param tee_file: File to tee logs to, in addition to stderr.
+ """
+ logging.config.dictConfig({
+ 'version': 1,
+ 'formatters': {
+ 'stderr': {
+ 'format': ('{name}: '
+ '%(asctime)s:%(levelname)s'
+ ':%(module)s:%(funcName)s:%(lineno)d'
+ ': %(message)s'
+ .format(name=name)),
+ },
+ 'tee_file': {
+ 'format': ('%(asctime)s:%(levelname)s'
+ ':%(module)s:%(funcName)s:%(lineno)d'
+ ': %(message)s'),
+ },
+ },
+ 'handlers': {
+ 'stderr': {
+ 'class': 'logging.StreamHandler',
+ 'formatter': 'stderr',
+ },
+ 'tee_file': {
+ 'class': 'logging.FileHandler',
+ 'formatter': 'tee_file',
+ 'filename': tee_file,
+ },
+ },
+ 'root': {
+ 'level': 'DEBUG',
+ 'handlers': ['stderr', 'tee_file'],
+ },
+ 'disable_existing_loggers': False,
+ })
+
+
+def _read_store(path):
+ """Read a HostInfo from a file at path."""
+ store = file_store.FileStore(path)
+ return store.get()
+
+
+def _create_host(hostname, info, results_dir):
+ """Yield a hosts.CrosHost object with the given inventory information.
+
+ @param hostname: Hostname of the DUT.
+ @param info: A HostInfo with the inventory information to use.
+ @param results_dir: Path to directory for logs / output artifacts.
+ @yield server.hosts.CrosHost object.
+ """
+ if not info.board:
+ raise DutPreparationError('No board in DUT labels')
+ if not info.model:
+ raise DutPreparationError('No model in DUT labels')
+
+ servo_args = {}
+ if 'servo_host' not in info.attributes:
+ raise DutPreparationError('No servo_host in DUT attributes')
+ if 'servo_port' not in info.attributes:
+ raise DutPreparationError('No servo_port in DUT attributes')
+
+ dut_logs_dir = os.path.join(results_dir, _DUT_LOGS_DIR)
+ try:
+ os.makedirs(dut_logs_dir)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+
+ return preparedut.create_host(
+ hostname,
+ info.board,
+ info.model,
+ info.attributes['servo_host'],
+ info.attributes['servo_port'],
+ info.attributes.get('servo_serial', ''),
+ dut_logs_dir,
+ )
+
+
+def _get_cros_repair_image_name(board):
+ """Get the CrOS repair image name for given host.
+
+ TODO(pprabhu): This is an evil function with dependence on the environment
+ (global_config information) and the AFE. Remove this dependence when stable
+ image mappings move off of the AFE.
+ """
+ return afe_utils.get_stable_cros_image_name(board)
+
+
if __name__ == '__main__':
main()
diff --git a/site_utils/run_suite.py b/site_utils/run_suite.py
index 35eeb39..35bbe5b 100755
--- a/site_utils/run_suite.py
+++ b/site_utils/run_suite.py
@@ -54,9 +54,19 @@
import common
from chromite.lib import buildbot_annotations as annotations
+from chromite.lib import gs
+from chromite.lib import osutils
from django.core import exceptions as django_exceptions
+try:
+ from suite_scheduler import config_reader
+ from suite_scheduler import skylab
+except ImportError:
+ # For unittest
+ config_reader = None
+ skylab = None
+
from autotest_lib.client.common_lib import control_data
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import global_config
@@ -90,6 +100,13 @@
_DEFAULT_AUTOTEST_INSTANCE = CONFIG.get_config_value(
'SERVER', 'hostname', type=str)
_URL_PATTERN = CONFIG.get_config_value('CROS', 'log_url_pattern', type=str)
+_ENABLE_RUN_SUITE_TRAMPOLINE = CONFIG.get_config_value(
+ 'CROS', 'enable_run_suite_trampoline', type=bool, default=False)
+
+_MIGRATION_CONFIG_FILE = 'migration_config.ini'
+_MIGRATION_CONFIG_BUCKET = 'suite-scheduler.google.com.a.appspot.com'
+_TRAMPOLINE_CONFIG = 'gs://%s/%s' % (_MIGRATION_CONFIG_BUCKET,
+ _MIGRATION_CONFIG_FILE)
# Minimum RPC timeout setting for calls expected to take long time, e.g.,
# create_suite_job. If default socket time (socket.getdefaulttimeout()) is
@@ -2037,6 +2054,40 @@
sys.exit(run_suite_common.RETURN_CODES.INFRA_FAILURE)
+def _check_if_use_skylab(options):
+ """Detect whether to run suite in skylab."""
+ if not _ENABLE_RUN_SUITE_TRAMPOLINE:
+ logging.info('trampoline to skylab is not enabled.')
+ return False
+
+ task_info = 'suite:%s, board:%s, model:%s, pool:%s' % (
+ options.name, options.board, options.model, options.pool)
+ ctx = gs.GSContext()
+ with osutils.TempDir(prefix='trampoline_') as tempdir:
+ temp_file = os.path.join(tempdir, _MIGRATION_CONFIG_FILE)
+ ctx.Copy(_TRAMPOLINE_CONFIG, temp_file)
+ _migration_config = config_reader.MigrationConfig(
+ config_reader.ConfigReader(temp_file))
+
+ logging.info('Checking whether to run in skylab: Task(%s)', task_info)
+ if skylab.should_run_in_skylab(_migration_config,
+ options.board,
+ options.model,
+ options.name,
+ options.pool):
+ logging.info('Task (%s) Should run in skylab', task_info)
+ return True
+
+ logging.info('Task (%s) Should run in autotest', task_info)
+ return False
+
+
+def _run_with_skylab(options):
+ """Run suite inside skylab."""
+ # TODO(xixuan): Implement running suite in skylab.
+ return _RETURN_RESULTS['ok']
+
+
def _run_with_autotest(options):
"""Run suite inside autotest."""
if options.pre_check and not _should_run(options):
@@ -2079,7 +2130,10 @@
result = run_suite_common.SuiteResult(
run_suite_common.RETURN_CODES.INVALID_OPTIONS)
else:
- result = _run_with_autotest(options)
+ if _check_if_use_skylab(options):
+ result = _run_with_skylab(options)
+ else:
+ result = _run_with_autotest(options)
logging.info('Will return from run_suite with status: %s',
run_suite_common.RETURN_CODES.get_string(result.return_code))
diff --git a/venv/skylab_suite/suite_runner.py b/venv/skylab_suite/suite_runner.py
index 3cea765..808ccee 100644
--- a/venv/skylab_suite/suite_runner.py
+++ b/venv/skylab_suite/suite_runner.py
@@ -222,7 +222,7 @@
# SWARMING_SERVER environment variable. See crbug.com/948774
def _is_dev():
"""Detect whether skylab tool should be invoked with -dev flag."""
- return 'chromium-swarm-dev' in os.environ['SWARMING_SERVER']
+ return 'chromium-swarm-dev' in os.environ['SWARMING_SERVER']
def _compute_tags(build, suite_id):
tags = [