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.
140 lines
5.3 KiB
140 lines
5.3 KiB
# 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.
|
|
|
|
import common
|
|
import logging
|
|
from autotest_lib.client.common_lib import hosts
|
|
from autotest_lib.server.hosts import cros_constants
|
|
from autotest_lib.server.hosts import repair_utils
|
|
from autotest_lib.client.common_lib import utils
|
|
|
|
from chromite.lib import timeout_util
|
|
|
|
try:
|
|
from chromite.lib import metrics
|
|
except ImportError:
|
|
metrics = utils.metrics_mock
|
|
|
|
# There are some labstations we don't want they receive auto-update,
|
|
# e.g. labstations that used for image qualification purpose
|
|
UPDATE_EXEMPTED_POOL = {'servo_verification', 'labstation_tryjob'}
|
|
|
|
|
|
class _LabstationUpdateVerifier(hosts.Verifier):
|
|
"""
|
|
Verifier to trigger a labstation update, if necessary.
|
|
|
|
The operation doesn't wait for the update to complete and is
|
|
considered a success whether or not the servo is currently
|
|
up-to-date.
|
|
"""
|
|
|
|
@timeout_util.TimeoutDecorator(cros_constants.LONG_VERIFY_TIMEOUT_SEC)
|
|
def verify(self, host):
|
|
"""First, only run this verifier if the host is in the physical lab.
|
|
Secondly, skip if the test is being run by test_that, because subnet
|
|
restrictions can cause the update to fail.
|
|
"""
|
|
if host.is_in_lab() and host.job and host.job.in_lab:
|
|
host.update_cros_version_label()
|
|
info = host.host_info_store.get()
|
|
if bool(UPDATE_EXEMPTED_POOL & info.pools):
|
|
logging.info("Skip update because the labstation is in"
|
|
" one of following exempted pool: %s", info.pools)
|
|
return
|
|
|
|
stable_version = info.stable_versions.get('cros')
|
|
if stable_version:
|
|
host.update_image(stable_version=stable_version)
|
|
else:
|
|
raise hosts.AutoservVerifyError('Failed to check/update'
|
|
' labstation due to no stable'
|
|
'_version found in host_info'
|
|
'_store.')
|
|
|
|
@property
|
|
def description(self):
|
|
return 'Labstation image is updated to current stable-version'
|
|
|
|
|
|
class _LabstationRebootVerifier(hosts.Verifier):
|
|
"""Check if reboot is need for the labstation and perform a reboot if it's
|
|
not currently using by any tests.
|
|
"""
|
|
|
|
@timeout_util.TimeoutDecorator(cros_constants.VERIFY_TIMEOUT_SEC)
|
|
def verify(self, host):
|
|
if host.is_reboot_requested():
|
|
host.try_reboot()
|
|
|
|
@property
|
|
def description(self):
|
|
return 'Reboot labstation if requested and the labstation is not in use'
|
|
|
|
|
|
class _LabstationLangidVerifier(hosts.Verifier):
|
|
"""Check if labstation has issue with read serial from servo devices.
|
|
|
|
TODO(b:162518926): remove when bug will be resolved.
|
|
"""
|
|
|
|
@timeout_util.TimeoutDecorator(cros_constants.VERIFY_TIMEOUT_SEC)
|
|
def verify(self, host):
|
|
try:
|
|
cmd = (
|
|
"python2 -c 'import usb;"
|
|
" print([[d.open().getString(d.iSerialNumber, 128)"
|
|
" for d in bus.devices if d.idVendor == 0x18d1"
|
|
" and (d.idProduct == 0x501b" #servo_v4
|
|
" or d.idProduct == 0x501a" #servo_micro
|
|
" or d.idProduct == 0x5014)" #ccd_cr50
|
|
" and d.iSerialNumber == 3]" # 3 - slot for serial
|
|
" for bus in usb.busses()])'")
|
|
result = host.run(cmd, ignore_status=True, timeout=30)
|
|
if result.exit_status == 0:
|
|
return
|
|
if 'The device has no langid' in result.stderr.strip():
|
|
self._mark_host_for_reboot(host)
|
|
except Exception as e:
|
|
logging.debug('(Not critical) %s', e)
|
|
if 'Timeout encountered' in str(e):
|
|
# Time out mean we cannot get servo attributes in time because
|
|
# one of the servos has langid.
|
|
self._mark_host_for_reboot(host)
|
|
|
|
def _mark_host_for_reboot(self, host):
|
|
"""Mark Labstation as has issue with langid."""
|
|
logging.info('Detected langid issue.')
|
|
data = {'host': host.hostname, 'board': host.get_board() or ''}
|
|
metrics.Counter('chromeos/autotest/labstation/langid_issue').increment(
|
|
fields=data)
|
|
# labstation reboot will fix the issue but we does not want to
|
|
# reboot the labstation to often. Just create request to reboot
|
|
# it for the next time.
|
|
logging.info('Created request for reboot.')
|
|
cmd = ('touch %slangid%s' %
|
|
(host.TEMP_FILE_DIR, host.REBOOT_FILE_POSTFIX))
|
|
host.run(cmd, ignore_status=True, timeout=30)
|
|
|
|
@property
|
|
def description(self):
|
|
return 'Check if labsattion has langid issue'
|
|
|
|
|
|
def create_labstation_repair_strategy():
|
|
"""
|
|
Return a `RepairStrategy` for a `LabstationHost`.
|
|
"""
|
|
verify_dag = [
|
|
(repair_utils.SshVerifier, 'ssh', []),
|
|
(_LabstationUpdateVerifier, 'update', ['ssh']),
|
|
(_LabstationLangidVerifier, 'langid', ['ssh']),
|
|
(_LabstationRebootVerifier, 'reboot', ['ssh']),
|
|
]
|
|
|
|
repair_actions = [
|
|
(repair_utils.RPMCycleRepair, 'rpm', [], ['ssh', 'reboot']),
|
|
]
|
|
return hosts.RepairStrategy(verify_dag, repair_actions, 'labstation')
|