# Copyright 2018 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 logging
import os
import time

from autotest_lib.server import test
from autotest_lib.server.cros import filesystem_util
from autotest_lib.client.common_lib import error, utils


class FingerprintTest(test.test):
    """Base class that sets up helpers for fingerprint tests."""
    version = 1

    # Location of firmware from the build on the DUT
    _FINGERPRINT_BUILD_FW_DIR = '/opt/google/biod/fw'

    _DISABLE_FP_UPDATER_FILE = '.disable_fp_updater'

    _UPSTART_DIR = '/etc/init'
    _BIOD_UPSTART_JOB_FILE = 'biod.conf'
    _STATEFUL_PARTITION_DIR = '/mnt/stateful_partition'

    _GENIMAGES_SCRIPT_NAME = 'gen_test_images.sh'
    _GENIMAGES_OUTPUT_DIR_NAME = 'images'

    _TEST_IMAGE_FORMAT_MAP = {
        'TEST_IMAGE_ORIGINAL': '%s.bin',
        'TEST_IMAGE_DEV': '%s.dev',
        'TEST_IMAGE_CORRUPT_FIRST_BYTE': '%s_corrupt_first_byte.bin',
        'TEST_IMAGE_CORRUPT_LAST_BYTE': '%s_corrupt_last_byte.bin',
        'TEST_IMAGE_DEV_RB_ZERO': '%s.dev.rb0',
        'TEST_IMAGE_DEV_RB_ONE': '%s.dev.rb1',
        'TEST_IMAGE_DEV_RB_NINE': '%s.dev.rb9'
    }

    _ROLLBACK_ZERO_BLOCK_ID = '0'
    _ROLLBACK_INITIAL_BLOCK_ID = '1'
    _ROLLBACK_INITIAL_MIN_VERSION = '0'
    _ROLLBACK_INITIAL_RW_VERSION = '0'

    _SERVER_GENERATED_FW_DIR_NAME = 'generated_fw'

    _DUT_TMP_PATH_BASE = '/tmp/fp_test'

    # Name of key in "futility show" output corresponds to the signing key ID
    _FUTILITY_KEY_ID_KEY_NAME = 'ID'

    # Types of firmware
    _FIRMWARE_TYPE_RO = 'RO'
    _FIRMWARE_TYPE_RW = 'RW'

    # Types of signing keys
    _KEY_TYPE_DEV = 'dev'
    _KEY_TYPE_PRE_MP = 'premp'
    _KEY_TYPE_MP = 'mp'

    # EC board names for FPMCUs
    _FP_BOARD_NAME_BLOONCHIPPER = 'bloonchipper'
    _FP_BOARD_NAME_DARTMONKEY = 'dartmonkey'
    _FP_BOARD_NAME_NOCTURNE = 'nocturne_fp'
    _FP_BOARD_NAME_NAMI = 'nami_fp'

    # Map from signing key ID to type of signing key
    _KEY_ID_MAP_ = {
        # bloonchipper
        '61382804da86b4156d666cc9a976088f8b647d44': _KEY_TYPE_DEV,
        '07b1af57220c196e363e68d73a5966047c77011e': _KEY_TYPE_PRE_MP,
        '1c590ef36399f6a2b2ef87079c135b69ef89eb60': _KEY_TYPE_MP,

        # dartmonkey
        '257a0aa3ac9e81aa4bc3aabdb6d3d079117c5799': _KEY_TYPE_MP,

        # nocturne
        '8a8fc039a9463271995392f079b83ce33832d07d': _KEY_TYPE_DEV,
        '6f38c866182bd9bf7a4462c06ac04fa6a0074351': _KEY_TYPE_MP,
        'f6f7d96c48bd154dbae7e3fe3a3b4c6268a10934': _KEY_TYPE_PRE_MP,

        # nami
        '754aea623d69975a22998f7b97315dd53115d723': _KEY_TYPE_PRE_MP,
        '35486c0090ca390408f1fbbf2a182966084fe2f8': _KEY_TYPE_MP

    }

    # RO versions that are flashed in the factory
    # (for eternity for a given board)
    _GOLDEN_RO_FIRMWARE_VERSION_MAP = {
            _FP_BOARD_NAME_BLOONCHIPPER: {
                    'hatch': 'bloonchipper_v2.0.4277-9f652bb3',
                    'zork': 'bloonchipper_v2.0.5938-197506c1',
            },
            _FP_BOARD_NAME_DARTMONKEY: 'dartmonkey_v2.0.2887-311310808',
            _FP_BOARD_NAME_NOCTURNE: 'nocturne_fp_v2.2.64-58cf5974e',
            _FP_BOARD_NAME_NAMI: 'nami_fp_v2.2.144-7a08e07eb',
    }

    _FIRMWARE_VERSION_SHA256SUM = 'sha256sum'
    _FIRMWARE_VERSION_RO_VERSION = 'ro_version'
    _FIRMWARE_VERSION_RW_VERSION = 'rw_version'
    _FIRMWARE_VERSION_KEY_ID = 'key_id'

    # Map of attributes for a given board's various firmware file releases
    #
    # Two purposes:
    #   1) Documents the exact versions and keys used for a given firmware file.
    #   2) Used to verify that files that end up in the build (and therefore
    #      what we release) is exactly what we expect.
    _FIRMWARE_VERSION_MAP = {
        _FP_BOARD_NAME_BLOONCHIPPER: {
            'bloonchipper_v2.0.4277-9f652bb3.bin': {
                _FIRMWARE_VERSION_SHA256SUM: '7d9b788a908bee5c83e27450258b2bbf110d7253d49faa4804562ae27e42cb3b',
                _FIRMWARE_VERSION_RO_VERSION: 'bloonchipper_v2.0.4277-9f652bb3',
                _FIRMWARE_VERSION_RW_VERSION: 'bloonchipper_v2.0.4277-9f652bb3',
                _FIRMWARE_VERSION_KEY_ID: '1c590ef36399f6a2b2ef87079c135b69ef89eb60',
            },
            'bloonchipper_v2.0.5938-197506c1.bin': {
                _FIRMWARE_VERSION_SHA256SUM: 'dc62e4b05eaf4fa8ab5546dcf18abdb30c8e64e9bf0fbf377ebc85155c7c3a47',
                _FIRMWARE_VERSION_RO_VERSION: 'bloonchipper_v2.0.5938-197506c1',
                _FIRMWARE_VERSION_RW_VERSION: 'bloonchipper_v2.0.5938-197506c1',
                _FIRMWARE_VERSION_KEY_ID: '1c590ef36399f6a2b2ef87079c135b69ef89eb60',
            },
        },
        _FP_BOARD_NAME_NOCTURNE: {
            'nocturne_fp_v2.2.64-58cf5974e-RO_v2.0.4017-9c45fb4b3-RW.bin': {
                _FIRMWARE_VERSION_SHA256SUM: '16c405eeaff75dcbc76dbc9f368f66e3fabc47e2ebcf13bd2b64b8b133bbff97',
                _FIRMWARE_VERSION_RO_VERSION: 'nocturne_fp_v2.2.64-58cf5974e',
                _FIRMWARE_VERSION_RW_VERSION: 'nocturne_fp_v2.0.4017-9c45fb4b3',
                _FIRMWARE_VERSION_KEY_ID: '6f38c866182bd9bf7a4462c06ac04fa6a0074351',
            },
        },
        _FP_BOARD_NAME_NAMI: {
            'nami_fp_v2.2.144-7a08e07eb-RO_v2.0.4017-9c45fb4b3-RW.bin': {
                _FIRMWARE_VERSION_SHA256SUM: '7965ea4c4371ee6d21dc462b9ed7c99078d17f4b772bec51441ca9af7d8f3a80',
                _FIRMWARE_VERSION_RO_VERSION: 'nami_fp_v2.2.144-7a08e07eb',
                _FIRMWARE_VERSION_RW_VERSION: 'nami_fp_v2.0.4017-9c45fb4b3',
                _FIRMWARE_VERSION_KEY_ID: '35486c0090ca390408f1fbbf2a182966084fe2f8',
            },
        },
        _FP_BOARD_NAME_DARTMONKEY: {
            'dartmonkey_v2.0.2887-311310808-RO_v2.0.4017-9c45fb4b3-RW.bin': {
                _FIRMWARE_VERSION_SHA256SUM: 'b84914c70e93c28e2221f48be338dbf0ad0cfb12b7877baaf6b47f7bfd2aa958',
                _FIRMWARE_VERSION_RO_VERSION: 'dartmonkey_v2.0.2887-311310808',
                _FIRMWARE_VERSION_RW_VERSION: 'dartmonkey_v2.0.4017-9c45fb4b3',
                _FIRMWARE_VERSION_KEY_ID: '257a0aa3ac9e81aa4bc3aabdb6d3d079117c5799',
            }
        }
    }

    _BIOD_UPSTART_JOB_NAME = 'biod'
    # TODO(crbug.com/925545)
    _TIMBERSLIDE_UPSTART_JOB_NAME = \
        'timberslide LOG_PATH=/sys/kernel/debug/cros_fp/console_log'

    _INIT_ENTROPY_CMD = 'bio_wash --factory_init'

    _CROS_FP_ARG = '--name=cros_fp'
    _CROS_CONFIG_FINGERPRINT_PATH = '/fingerprint'
    _ECTOOL_RO_VERSION = 'RO version'
    _ECTOOL_RW_VERSION = 'RW version'
    _ECTOOL_FIRMWARE_COPY = 'Firmware copy'
    _ECTOOL_ROLLBACK_BLOCK_ID = 'Rollback block id'
    _ECTOOL_ROLLBACK_MIN_VERSION = 'Rollback min version'
    _ECTOOL_ROLLBACK_RW_VERSION = 'RW rollback version'

    @staticmethod
    def _parse_colon_delimited_output(ectool_output):
        """
        Converts ectool's (or any other tool with similar output) colon
        delimited output into python dict. Ignores any lines that do not have
        colons.

        Example:
        RO version:    nocturne_fp_v2.2.64-58cf5974e
        RW version:    nocturne_fp_v2.2.110-b936c0a3c

        becomes:
        {
          'RO version': 'nocturne_fp_v2.2.64-58cf5974e',
          'RW version': 'nocturne_fp_v2.2.110-b936c0a3c'
        }
        """
        ret = {}
        try:
            for line in ectool_output.strip().split('\n'):
                splits = line.split(':', 1)
                if len(splits) != 2:
                    continue
                key = splits[0].strip()
                val = splits[1].strip()
                ret[key] = val
        except:
            raise error.TestFail('Unable to parse ectool output: %s'
                                 % ectool_output)
        return ret

    def initialize(self, host):
        """Perform minimal initialization, to avoid AttributeError in cleanup"""
        self.host = host
        self.servo = host.servo

        self._validate_compatible_servo_version()

        self.servo.initialize_dut()

        self.fp_board = self.get_fp_board()
        self._build_fw_file = self.get_build_fw_file()

    def setup_test(self, test_dir, use_dev_signed_fw=False,
                   enable_hardware_write_protect=True,
                   enable_software_write_protect=True,
                   force_firmware_flashing=False, init_entropy=True):
        """Perform more complete initialization, including copying test files"""
        logging.info('HW write protect enabled: %s',
                     self.is_hardware_write_protect_enabled())

        # TODO(crbug.com/925545): stop timberslide so /var/log/cros_fp.log
        # continues to update after flashing.
        self._timberslide_running = self.host.upstart_status(
            self._TIMBERSLIDE_UPSTART_JOB_NAME)
        if self._timberslide_running:
            logging.info('Stopping %s', self._TIMBERSLIDE_UPSTART_JOB_NAME)
            self.host.upstart_stop(self._TIMBERSLIDE_UPSTART_JOB_NAME)

        self._biod_running = self.host.upstart_status(
            self._BIOD_UPSTART_JOB_NAME)
        if self._biod_running:
            logging.info('Stopping %s', self._BIOD_UPSTART_JOB_NAME)
            self.host.upstart_stop(self._BIOD_UPSTART_JOB_NAME)

        # On some platforms an AP reboot is needed after flashing firmware to
        # rebind the driver.
        self._dut_needs_reboot = self.get_host_board() == 'zork'

        if filesystem_util.is_rootfs_writable(self.host):
            if self._dut_needs_reboot:
                logging.warning('rootfs is writable')
            else:
                raise error.TestFail('rootfs is writable')

        if not self.biod_upstart_job_enabled():
            raise error.TestFail(
                    'Biod upstart job is disabled at the beginning of test')
        if not self.fp_updater_is_enabled():
            raise error.TestFail(
                    'Fingerprint firmware updater is disabled at the beginning of test'
            )

        # Disable biod and updater so that they won't interfere after reboot.
        if self._dut_needs_reboot:
            self.disable_biod_upstart_job()
            self.disable_fp_updater()

        # create tmp working directory on device (automatically cleaned up)
        self._dut_working_dir = self.host.get_tmp_dir(
            parent=self._DUT_TMP_PATH_BASE)
        logging.info('Created dut_working_dir: %s', self._dut_working_dir)
        self.copy_files_to_dut(test_dir, self._dut_working_dir)

        self.validate_build_fw_file()

        gen_script = os.path.abspath(os.path.join(self.autodir,
                                                  'server', 'cros', 'faft',
                                                  self._GENIMAGES_SCRIPT_NAME))
        self._dut_firmware_test_images_dir = \
            self._generate_test_firmware_images(gen_script,
                                                self._build_fw_file,
                                                self._dut_working_dir)
        logging.info('dut_firmware_test_images_dir: %s',
                     self._dut_firmware_test_images_dir)

        self._initialize_test_firmware_image_attrs(
            self._dut_firmware_test_images_dir)

        self._initialize_running_fw_version(use_dev_signed_fw,
                                            force_firmware_flashing)

        if init_entropy:
            self._initialize_fw_entropy()

        self._initialize_hw_and_sw_write_protect(enable_hardware_write_protect,
                                                 enable_software_write_protect)

    def cleanup(self):
        """Restores original state."""
        # Once the tests complete we need to make sure we're running the
        # original firmware (not dev version) and potentially reset rollback.
        self._initialize_running_fw_version(use_dev_signed_fw=False,
                                            force_firmware_flashing=False)
        self._initialize_fw_entropy()
        # Re-enable biod and updater after flashing and initializing entropy so
        # that they don't interfere if there was a reboot.
        if hasattr(self, '_dut_needs_reboot') and self._dut_needs_reboot:
            if not self.biod_upstart_job_enabled():
                self.enable_biod_upstart_job()
            if not self.fp_updater_is_enabled():
                self.enable_fp_updater()
        self._initialize_hw_and_sw_write_protect(
            enable_hardware_write_protect=True,
            enable_software_write_protect=True)
        if hasattr(self, '_biod_running') and self._biod_running:
            logging.info('Restarting biod')
            self.host.upstart_restart(self._BIOD_UPSTART_JOB_NAME)
        # TODO(crbug.com/925545)
        if hasattr(self, '_timberslide_running') and self._timberslide_running:
            logging.info('Restarting timberslide')
            self.host.upstart_restart(self._TIMBERSLIDE_UPSTART_JOB_NAME)

        super(FingerprintTest, self).cleanup()

    def after_run_once(self):
        """Logs which iteration just ran."""
        logging.info('successfully ran iteration %d', self.iteration)

    def _validate_compatible_servo_version(self):
        """Asserts if a compatible servo version is not attached."""
        servo_version = self.servo.get_servo_version()
        logging.info('servo version: %s', servo_version)

    def _generate_test_firmware_images(self, gen_script, build_fw_file,
                                       dut_working_dir):
        """
        Copies the fingerprint firmware from the DUT to the server running
        the tests, which runs a script to generate various test versions of
        the firmware.

        @return full path to location of test images on DUT
        """
        # create subdirectory under existing tmp dir
        server_tmp_dir = os.path.join(self.tmpdir,
                                      self._SERVER_GENERATED_FW_DIR_NAME)
        os.mkdir(server_tmp_dir)
        logging.info('server_tmp_dir: %s', server_tmp_dir)

        # Copy firmware from device to server
        self.get_files_from_dut(build_fw_file, server_tmp_dir)

        # Run the test image generation script on server
        pushd = os.getcwd()
        os.chdir(server_tmp_dir)
        cmd = ' '.join([gen_script,
                        self.get_fp_board(),
                        os.path.basename(build_fw_file)])
        result = self.run_server_cmd(cmd)
        if result.exit_status != 0:
            raise error.TestFail('Failed to run test image generation script')

        os.chdir(pushd)

        # Copy resulting files to DUT tmp dir
        server_generated_images_dir = \
            os.path.join(server_tmp_dir, self._GENIMAGES_OUTPUT_DIR_NAME)
        self.copy_files_to_dut(server_generated_images_dir, dut_working_dir)

        return os.path.join(dut_working_dir, self._GENIMAGES_OUTPUT_DIR_NAME)

    def _initialize_test_firmware_image_attrs(self, dut_fw_test_images_dir):
        """Sets attributes with full path to test images on DUT.

        Example: self.TEST_IMAGE_DEV = /some/path/images/nocturne_fp.dev
        """
        for key, val in self._TEST_IMAGE_FORMAT_MAP.iteritems():
            full_path = os.path.join(dut_fw_test_images_dir,
                                     val % self.get_fp_board())
            setattr(self, key, full_path)

    def _initialize_running_fw_version(self, use_dev_signed_fw,
                                       force_firmware_flashing):
        """
        Ensures that the running firmware version matches build version
        and factory rollback settings; flashes to correct version if either
        fails to match is requested to force flashing.

        RO firmware: original version released at factory
        RW firmware: firmware from current build
        """
        build_rw_firmware_version = \
            self.get_build_rw_firmware_version(use_dev_signed_fw)
        golden_ro_firmware_version = \
            self.get_golden_ro_firmware_version(use_dev_signed_fw)
        logging.info('Build RW firmware version: %s', build_rw_firmware_version)
        logging.info('Golden RO firmware version: %s',
                     golden_ro_firmware_version)

        running_rw_firmware = self.ensure_running_rw_firmware()

        fw_versions_match = self.running_fw_version_matches_given_version(
            build_rw_firmware_version, golden_ro_firmware_version)

        if not running_rw_firmware or not fw_versions_match \
            or not self.is_rollback_set_to_initial_val() \
            or force_firmware_flashing:
            fw_file = self._build_fw_file
            if use_dev_signed_fw:
                fw_file = self.TEST_IMAGE_DEV
            self.flash_rw_ro_firmware(fw_file)
            if not self.running_fw_version_matches_given_version(
                build_rw_firmware_version, golden_ro_firmware_version):
                raise error.TestFail(
                    'Running firmware version does not match expected version')

    def _initialize_fw_entropy(self):
        """Sets the entropy (key) in FPMCU flash (if not set)."""
        result = self.run_cmd(self._INIT_ENTROPY_CMD)
        if result.exit_status != 0:
            raise error.TestFail('Unable to initialize entropy')

    def _initialize_hw_and_sw_write_protect(self, enable_hardware_write_protect,
                                            enable_software_write_protect):
        """Enables/disables hardware/software write protect."""
        # sw: 0, hw: 0 => initial_hw(0) -> sw(0) -> hw(0)
        # sw: 0, hw: 1 => initial_hw(0) -> sw(0) -> hw(1)
        # sw: 1, hw: 0 => initial_hw(1) -> sw(1) -> hw(0)
        # sw: 1, hw: 1 => initial_hw(1) -> sw(1) -> hw(1)
        hardware_write_protect_initial_enabled = True
        if not enable_software_write_protect:
            hardware_write_protect_initial_enabled = False

        self.set_hardware_write_protect(hardware_write_protect_initial_enabled)

        self.set_software_write_protect(enable_software_write_protect)
        self.set_hardware_write_protect(enable_hardware_write_protect)

    def get_fp_board(self):
        """Returns name of fingerprint EC.

        nocturne and nami are special cases and have "_fp" appended. Newer
        FPMCUs have unique names.
        See go/cros-fingerprint-firmware-branching-and-signing.
        """
        # Use cros_config to get fingerprint board.
        result = self._run_cros_config_cmd('board')
        if result.exit_status != 0:
            raise error.TestFail(
                'Unable to get fingerprint board with cros_config')
        return result.stdout.rstrip()

    def get_host_board(self):
        """Returns name of the host board."""
        return self.host.get_board().split(':')[-1]

    def get_build_fw_file(self):
        """Returns full path to build FW file on DUT."""
        ls_cmd = 'ls %s/%s*.bin' % (
            self._FINGERPRINT_BUILD_FW_DIR, self.fp_board)
        result = self.run_cmd(ls_cmd)
        if result.exit_status != 0:
            raise error.TestFail(
                'Unable to find firmware file on device:'
                ' command failed (rc=%s): %s'
                % (result.exit_status, result.stderr.strip() or ls_cmd))
        ret = result.stdout.rstrip()
        logging.info('Build firmware file: %s', ret)
        return ret

    def check_equal(self, a, b):
        """Raises exception if "a" does not equal "b"."""
        if a != b:
            raise error.TestFail('"%s" does not match expected "%s" for board '
                                 '%s' % (a, b, self.get_fp_board()))

    def validate_build_fw_file(self,
                               allowed_types=(_KEY_TYPE_PRE_MP, _KEY_TYPE_MP)):
        """
        Checks that all attributes in the given firmware file match their
        expected values.

        @param allowed_types: If key type is something else, raise TestFail.
                              Default: pre-MP or MP.
        @type allowed_types: tuple | list
        """
        build_fw_file = self._build_fw_file
        # check hash
        actual_hash = self._calculate_sha256sum(build_fw_file)
        expected_hash = self._get_expected_firmware_hash(build_fw_file)
        self.check_equal(actual_hash, expected_hash)

        # check signing key_id
        actual_key_id = self._read_firmware_key_id(build_fw_file)
        expected_key_id = self._get_expected_firmware_key_id(build_fw_file)
        self.check_equal(actual_key_id, expected_key_id)

        # check that the signing key for firmware in the build
        # is "pre mass production" (pre-mp) or "mass production" (MP)
        key_type = self._get_key_type(actual_key_id)
        if key_type not in allowed_types:
            raise error.TestFail(
                'Firmware key type must be %s for board %s; got %s (%s)' %
                (' or '.join(allowed_types), self.fp_board, key_type,
                 actual_key_id))

        # check ro_version
        actual_ro_version = self._read_firmware_ro_version(build_fw_file)
        expected_ro_version = \
            self._get_expected_firmware_ro_version(build_fw_file)
        self.check_equal(actual_ro_version, expected_ro_version)

        # check rw_version
        actual_rw_version = self._read_firmware_rw_version(build_fw_file)
        expected_rw_version = \
            self._get_expected_firmware_rw_version(build_fw_file)
        self.check_equal(actual_rw_version, expected_rw_version)

        logging.info("Validated build firmware metadata.")

    def _get_key_type(self, key_id):
        """Returns the key "type" for a given "key id"."""
        key_type = self._KEY_ID_MAP_.get(key_id)
        if key_type is None:
            raise error.TestFail('Unable to get key type for key id: %s'
                                 % key_id)
        return key_type

    def _get_expected_firmware_info(self, build_fw_file, info_type):
        """
        Returns expected firmware info for a given firmware file name.
        """
        build_fw_file_name = os.path.basename(build_fw_file)

        board = self.get_fp_board()
        board_expected_fw_info = self._FIRMWARE_VERSION_MAP.get(board)
        if board_expected_fw_info is None:
            raise error.TestFail('Unable to get firmware info for board: %s'
                                 % board)

        expected_fw_info = board_expected_fw_info.get(build_fw_file_name)
        if expected_fw_info is None:
            raise error.TestFail('Unable to get firmware info for file: %s'
                                 % build_fw_file_name)

        ret = expected_fw_info.get(info_type)
        if ret is None:
            raise error.TestFail('Unable to get firmware info type: %s'
                                 % info_type)

        return ret

    def _get_expected_firmware_hash(self, build_fw_file):
        """Returns expected hash of firmware file."""
        return self._get_expected_firmware_info(
            build_fw_file, self._FIRMWARE_VERSION_SHA256SUM)

    def _get_expected_firmware_key_id(self, build_fw_file):
        """Returns expected "key id" for firmware file."""
        return self._get_expected_firmware_info(
            build_fw_file, self._FIRMWARE_VERSION_KEY_ID)

    def _get_expected_firmware_ro_version(self, build_fw_file):
        """Returns expected RO version for firmware file."""
        return self._get_expected_firmware_info(
            build_fw_file, self._FIRMWARE_VERSION_RO_VERSION)

    def _get_expected_firmware_rw_version(self, build_fw_file):
        """Returns expected RW version for firmware file."""
        return self._get_expected_firmware_info(
            build_fw_file, self._FIRMWARE_VERSION_RW_VERSION)

    def _read_firmware_key_id(self, file_name):
        """Returns "key id" as read from the given file."""
        result = self._run_futility_show_cmd(file_name)
        parsed = self._parse_colon_delimited_output(result)
        key_id = parsed.get(self._FUTILITY_KEY_ID_KEY_NAME)
        if key_id is None:
            raise error.TestFail('Failed to get key ID for file: %s'
                                 % file_name)
        return key_id

    def _read_firmware_ro_version(self, file_name):
        """Returns RO firmware version as read from the given file."""
        return self._run_dump_fmap_cmd(file_name, 'RO_FRID')

    def _read_firmware_rw_version(self, file_name):
        """Returns RW firmware version as read from the given file."""
        return self._run_dump_fmap_cmd(file_name, 'RW_FWID')

    def _calculate_sha256sum(self, file_name):
        """Returns SHA256 hash of the given file contents."""
        result = self._run_sha256sum_cmd(file_name)
        return result.stdout.split()[0]

    def _get_running_firmware_info(self, key):
        """
        Returns requested firmware info (RW version, RO version, or firmware
        type).
        """
        result = self._run_ectool_cmd('version')
        parsed = self._parse_colon_delimited_output(result.stdout)
        if result.exit_status != 0:
            raise error.TestFail('Failed to get running firmware info')
        info = parsed.get(key)
        if info is None:
            raise error.TestFail(
                'Failed to get running firmware info: %s' % key)
        return info

    def get_running_rw_firmware_version(self):
        """Returns running RW firmware version."""
        return self._get_running_firmware_info(self._ECTOOL_RW_VERSION)

    def get_running_ro_firmware_version(self):
        """Returns running RO firmware version."""
        return self._get_running_firmware_info(self._ECTOOL_RO_VERSION)

    def get_running_firmware_type(self):
        """Returns type of firmware we are running (RW or RO)."""
        return self._get_running_firmware_info(self._ECTOOL_FIRMWARE_COPY)

    def _get_rollback_info(self, info_type):
        """Returns requested type of rollback info."""
        result = self._run_ectool_cmd('rollbackinfo')
        parsed = self._parse_colon_delimited_output(result.stdout)
        if result.exit_status != 0:
            raise error.TestFail('Failed to get rollback info')
        info = parsed.get(info_type)
        if info is None:
            raise error.TestFail('Failed to get rollback info: %s' % info_type)
        return info

    def get_rollback_id(self):
        """Returns rollback ID."""
        return self._get_rollback_info(self._ECTOOL_ROLLBACK_BLOCK_ID)

    def get_rollback_min_version(self):
        """Returns rollback min version."""
        return self._get_rollback_info(self._ECTOOL_ROLLBACK_MIN_VERSION)

    def get_rollback_rw_version(self):
        """Returns RW rollback version."""
        return self._get_rollback_info(self._ECTOOL_ROLLBACK_RW_VERSION)

    def _construct_dev_version(self, orig_version):
        """
        Given a "regular" version string from a signed build, returns the
        special "dev" version that we use when creating the test images.
        """
        fw_version = orig_version
        if len(fw_version) + len('.dev') > 31:
            fw_version = fw_version[:27]
        fw_version = fw_version + '.dev'
        return fw_version

    def get_golden_ro_firmware_version(self, use_dev_signed_fw):
        """Returns RO firmware version used in factory."""
        board = self.get_fp_board()
        golden_version = self._GOLDEN_RO_FIRMWARE_VERSION_MAP.get(board)
        if isinstance(golden_version, dict):
            golden_version = golden_version.get(self.get_host_board())
        if golden_version is None:
            raise error.TestFail('Unable to get golden RO version for board: %s'
                                 % board)
        if use_dev_signed_fw:
            golden_version = self._construct_dev_version(golden_version)
        return golden_version

    def get_build_rw_firmware_version(self, use_dev_signed_fw):
        """Returns RW firmware version from build."""
        fw_version = self._read_firmware_rw_version(self._build_fw_file)
        if use_dev_signed_fw:
            fw_version = self._construct_dev_version(fw_version)
        return fw_version

    def ensure_running_rw_firmware(self):
        """
        Check whether the device is running RW firmware. If not, try rebooting
        to RW.

        @return true if successfully verified running RW firmware, false
        otherwise.
        """
        try:
            if self.get_running_firmware_type() != self._FIRMWARE_TYPE_RW:
                self._reboot_ec()
                if self.get_running_firmware_type() != self._FIRMWARE_TYPE_RW:
                    # RW may be corrupted.
                    return False
        except:
            # We may not always be able to read the firmware version.
            # For example, if the firmware is erased due to RDP1, running any
            # commands (such as getting the version) won't work.
            return False
        return True

    def running_fw_version_matches_given_version(self, rw_version, ro_version):
        """
        Returns True if the running RO and RW firmware versions match the
        provided versions.
        """
        try:
            running_rw_firmware_version = self.get_running_rw_firmware_version()
            running_ro_firmware_version = self.get_running_ro_firmware_version()

            logging.info('RW firmware, running: %s, expected: %s',
                         running_rw_firmware_version, rw_version)
            logging.info('RO firmware, running: %s, expected: %s',
                         running_ro_firmware_version, ro_version)

            return (running_rw_firmware_version == rw_version and
                    running_ro_firmware_version == ro_version)
        except:
            # We may not always be able to read the firmware version.
            # For example, if the firmware is erased due to RDP1, running any
            # commands (such as getting the version) won't work.
            return False

    def is_rollback_set_to_initial_val(self):
        """
        Returns True if rollbackinfo matches the initial value that it
        should have coming from the factory.
        """
        return (self.get_rollback_id() ==
                self._ROLLBACK_INITIAL_BLOCK_ID
                and
                self.get_rollback_min_version() ==
                self._ROLLBACK_INITIAL_MIN_VERSION
                and
                self.get_rollback_rw_version() ==
                self._ROLLBACK_INITIAL_RW_VERSION)

    def is_rollback_unset(self):
        """
        Returns True if rollbackinfo matches the uninitialized value that it
        should have after flashing the entire flash.
        """
        return (self.get_rollback_id() == self._ROLLBACK_ZERO_BLOCK_ID
                and self.get_rollback_min_version() ==
                self._ROLLBACK_INITIAL_MIN_VERSION
                and self.get_rollback_rw_version() ==
                self._ROLLBACK_INITIAL_RW_VERSION)

    def biod_upstart_job_enabled(self):
        """Returns whether biod's upstart job file is at original location."""
        return self.host.is_file_exists(
                os.path.join(self._UPSTART_DIR, self._BIOD_UPSTART_JOB_FILE))

    def disable_biod_upstart_job(self):
        """
        Disable biod's upstart job so that biod will not run after a reboot.
        """
        logging.info('Disabling biod\'s upstart job')
        filesystem_util.make_rootfs_writable(self.host)
        cmd = 'mv %s %s' % (os.path.join(
                self._UPSTART_DIR,
                self._BIOD_UPSTART_JOB_FILE), self._STATEFUL_PARTITION_DIR)
        result = self.run_cmd(cmd)
        if result.exit_status != 0:
            raise error.TestFail('Unable to disable biod upstart job: %s' %
                                 result.stderr.strip())

    def enable_biod_upstart_job(self):
        """
        Enable biod's upstart job so that biod will run after a reboot.
        """
        logging.info('Enabling biod\'s upstart job')
        filesystem_util.make_rootfs_writable(self.host)
        cmd = 'mv %s %s' % (os.path.join(
                self._STATEFUL_PARTITION_DIR,
                self._BIOD_UPSTART_JOB_FILE), self._UPSTART_DIR)
        result = self.run_cmd(cmd)
        if result.exit_status != 0:
            raise error.TestFail('Unable to enable biod upstart job: %s' %
                                 result.stderr.strip())

    def fp_updater_is_enabled(self):
        """Returns whether the fingerprint firmware updater is disabled."""
        return not self.host.is_file_exists(
                os.path.join(self._FINGERPRINT_BUILD_FW_DIR,
                             self._DISABLE_FP_UPDATER_FILE))

    def disable_fp_updater(self):
        """Disable the fingerprint firmware updater."""
        filesystem_util.make_rootfs_writable(self.host)
        touch_cmd = 'touch %s' % os.path.join(self._FINGERPRINT_BUILD_FW_DIR,
                                              self._DISABLE_FP_UPDATER_FILE)
        logging.info('Disabling fp firmware updater')
        result = self.run_cmd(touch_cmd)
        if result.exit_status != 0:
            raise error.TestFail(
                    'Unable to write file to disable fp updater:'
                    ' command failed (rc=%s): %s' %
                    (result.exit_status, result.stderr.strip() or touch_cmd))
        self.run_cmd('sync')

    def enable_fp_updater(self):
        """
        Enable the fingerprint firmware updater. Must be called only after
        disable_fp_updater().
        """
        filesystem_util.make_rootfs_writable(self.host)
        rm_cmd = 'rm %s' % os.path.join(self._FINGERPRINT_BUILD_FW_DIR,
                                        self._DISABLE_FP_UPDATER_FILE)
        logging.info('Enabling fp firmware updater')
        result = self.run_cmd(rm_cmd)
        if result.exit_status != 0:
            raise error.TestFail(
                    'Unable to rm .disable_fp_updater:'
                    ' command failed (rc=%s): %s' %
                    (result.exit_status, result.stderr.strip() or rm_cmd))
        self.run_cmd('sync')

    def flash_rw_ro_firmware(self, fw_path):
        """Flashes *all* firmware (both RO and RW)."""
        self.set_hardware_write_protect(False)
        flash_cmd = 'flash_fp_mcu' + ' ' + fw_path
        logging.info('Running flash cmd: %s', flash_cmd)
        flash_result = self.run_cmd(flash_cmd)
        self.set_hardware_write_protect(True)

        # Zork cannot rebind cros-ec-uart after flashing, so an AP reboot is
        # needed to talk to FPMCU. See b/170213489.
        # We have to do this even if flashing failed.
        if hasattr(self, '_dut_needs_reboot') and self._dut_needs_reboot:
            self.host.reboot()
            if self.fp_updater_is_enabled():
                raise error.TestFail(
                        'Fp updater was not disabled when firmware is flashed')
            # If we just re-enable fp updater, it can still update (race
            # condition), so do it later in cleanup.

        if flash_result.exit_status != 0:
            raise error.TestFail('Flashing RW/RO firmware failed')

    def is_hardware_write_protect_enabled(self):
        """Returns state of hardware write protect."""
        fw_wp_state = self.servo.get('fw_wp_state')
        return fw_wp_state == 'on' or fw_wp_state == 'force_on'

    def set_hardware_write_protect(self, enable):
        """Enables or disables hardware write protect."""
        self.servo.set('fw_wp_state', 'force_on' if enable else 'force_off')

    def set_software_write_protect(self, enable):
        """Enables or disables software write protect."""
        arg  = 'enable' if enable else 'disable'
        self._run_ectool_cmd('flashprotect ' + arg)
        # TODO(b/116396469): The flashprotect command returns an error even on
        # success.
        # if result.exit_status != 0:
        #    raise error.TestFail('Failed to modify software write protect')

        # TODO(b/116396469): "flashprotect enable" command is slow, so wait for
        # it to complete before attempting to reboot.
        time.sleep(2)
        self._reboot_ec()

    def _reboot_ec(self):
        """Reboots the fingerprint MCU (FPMCU)."""
        self._run_ectool_cmd('reboot_ec')
        # TODO(b/116396469): The reboot_ec command returns an error even on
        # success.
        # if result.exit_status != 0:
        #    raise error.TestFail('Failed to reboot ec')
        time.sleep(2)

    def get_files_from_dut(self, src, dst):
        """Copes files from DUT to server."""
        logging.info('Copying files from (%s) to (%s).', src, dst)
        self.host.get_file(src, dst, delete_dest=True)

    def copy_files_to_dut(self, src_dir, dst_dir):
        """Copies files from server to DUT."""
        logging.info('Copying files from (%s) to (%s).', src_dir, dst_dir)
        self.host.send_file(src_dir, dst_dir, delete_dest=True)
        # Sync the filesystem in case we need to reboot the AP soon.
        self.run_cmd('sync')

    def run_server_cmd(self, command, timeout=60):
        """Runs command on server; return result with output and exit code."""
        logging.info('Server execute: %s', command)
        result = utils.run(command, timeout=timeout, ignore_status=True)
        logging.info('exit_code: %d', result.exit_status)
        logging.info('stdout:\n%s', result.stdout)
        logging.info('stderr:\n%s', result.stderr)
        return result

    def run_cmd(self, command, timeout=300):
        """Runs command on the DUT; return result with output and exit code."""
        logging.debug('DUT Execute: %s', command)
        result = self.host.run(command, timeout=timeout, ignore_status=True)
        logging.info('exit_code: %d', result.exit_status)
        logging.info('stdout:\n%s', result.stdout)
        logging.info('stderr:\n%s', result.stderr)
        return result

    def _run_ectool_cmd(self, command):
        """Runs ectool on DUT; return result with output and exit code."""
        cmd = 'ectool ' + self._CROS_FP_ARG + ' ' + command
        result = self.run_cmd(cmd)
        return result

    def _run_cros_config_cmd(self, command):
        """Runs cros_config on DUT; return result with output and exit code."""
        cmd = 'cros_config ' + self._CROS_CONFIG_FINGERPRINT_PATH + ' ' \
              + command
        result = self.run_cmd(cmd)
        return result

    def _run_dump_fmap_cmd(self, fw_file, section):
        """
        Runs "dump_fmap" on DUT for given file.
        Returns value of given section.
        """
        # Write result to stderr while redirecting stderr to stdout
        # and dropping stdout. This is done because dump_map only writes the
        # value read from a section to a file (will not just print it to
        # stdout).
        cmd = 'dump_fmap -x ' + fw_file + ' ' + section +\
              ':/dev/stderr /dev/stderr >& /dev/stdout > /dev/null'
        result = self.run_cmd(cmd)
        if result.exit_status != 0:
            raise error.TestFail('Failed to read section: %s' % section)
        return result.stdout.rstrip('\0')

    def _run_futility_show_cmd(self, fw_file):
        """
        Runs "futility show" on DUT for given file.
        Returns stdout on success.
        """
        futility_cmd = 'futility show ' + fw_file
        result = self.run_cmd(futility_cmd)
        if result.exit_status != 0:
            raise error.TestFail('Unable to run futility on device')
        return result.stdout

    def _run_sha256sum_cmd(self, file_name):
        """
        Runs "sha256sum" on DUT for given file.
        Returns stdout on success.
        """
        sha_cmd = 'sha256sum ' + file_name
        result = self.run_cmd(sha_cmd)
        if result.exit_status != 0:
            raise error.TestFail('Unable to calculate sha256sum on device')
        return result

    def run_test(self, test_name, *args):
        """Runs test on DUT."""
        logging.info('Running %s', test_name)
        # Redirecting stderr to stdout since some commands intentionally fail
        # and it's easier to read when everything ordered in the same output
        test_cmd = ' '.join([os.path.join(self._dut_working_dir, test_name)] +
                            list(args) + ['2>&1'])
        # Change the working dir so we can write files from within the test
        # (otherwise defaults to $HOME (/root), which is not usually writable)
        # Note that dut_working_dir is automatically cleaned up so tests don't
        # need to worry about files from previous invocations or other tests.
        test_cmd = '(cd ' + self._dut_working_dir + ' && ' + test_cmd + ')'
        logging.info('Test command: %s', test_cmd)
        result = self.run_cmd(test_cmd)
        if result.exit_status != 0:
            raise error.TestFail(test_name + ' failed')
