blob: e3e81af7e402983b6599169773bba768bb427551 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2023 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Evaluate if a DUT is bootable"""
import logging
import os
import sys
from bisect_kit import bisector_cli
from bisect_kit import cli
from bisect_kit import common
from bisect_kit import core
from bisect_kit import cros_lab_util
from bisect_kit import cros_util
from bisect_kit import errors
logger = logging.getLogger(__name__)
def create_argument_parser():
parents = [cli.create_session_optional_parser()]
parser = cli.ArgumentParser(description=__doc__, parents=parents)
parser.add_argument(
'--rich-result',
action='store_true',
help='Instead of mere exit code, output detailed information in json',
)
parser.add_argument(
'dut',
nargs='?',
type=cli.argtype_notempty,
metavar='DUT',
default=os.environ.get('DUT', ''),
)
return parser
def is_dut_bootable(dut: str) -> bool:
"""Check if a DUT is bootable
Args:
dut: dut host name
Returns:
True if the DUT is bootable, False otherwise
"""
try:
cros_util.reboot(dut)
return True
except (errors.SshConnectionError, errors.ExternalError):
return False
def step_main(args: tuple[str] | None) -> core.StepResult:
parser = create_argument_parser()
opts = parser.parse_args(args)
common.config_logging(opts)
if cros_lab_util.is_satlab_dut(opts.dut):
cros_lab_util.write_satlab_ssh_config(opts.dut)
if not cros_util.is_dut(opts.dut):
raise errors.BrokenDutException(
'%r is not a valid DUT address' % opts.dut
)
if not cros_util.is_good_dut(opts.dut):
logger.fatal('%r is not a good DUT', opts.dut)
if not cros_lab_util.repair(opts.dut, opts.chromeos_root):
raise errors.BrokenDutException('%r is not a good DUT' % opts.dut)
if is_dut_bootable(opts.dut):
return core.StepResult('old', 'DUT is bootable')
return core.StepResult('new', 'DUT is not bootable')
def action() -> bisector_cli.EvalAction:
return bisector_cli.EvalAction.WITH_DUT
def main(args: tuple[str] | None = None) -> int:
return bisector_cli.step_main_wrapper(step_main, args)
if __name__ == '__main__':
sys.exit(main())