# Copyright 2022 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging
import pprint
import re
import time

from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import cr50_utils
from autotest_lib.server.cros.faft.cr50_test import Cr50Test


class firmware_GSCAPROV1Trigger(Cr50Test):
    """Verify GSC response after triggering AP RO V1 verification."""
    version = 1

    # This only verifies V1 output right now.
    TEST_AP_RO_VER = 1

    # DBG image has to be able to set the AP RO hash with the board id set.
    MIN_DBG_VER = '1.6.100'
    MIN_RELEASE_MAJOR = 5
    MIN_RELEASE_MINOR = 141

    APRO_PASS = 6
    APRO_FAIL = 2
    APRO_IN_PROGRESS = 7
    # Regex to search for the end of the AP RO output. Every run should end with
    # "AP RO PASS!" or "AP RO FAIL! evt - status". Collect all output up until
    # that point.
    APRO_OUTPUT_RE = r'.*(AP RO ([\S]*)![^\n]|do_ap_ro_check: unsupported)'

    # Cr50 tries to recalculate the hash with 8 of the common factory flags.
    FACTORY_FLAG_COUNT = 8
    TIMEOUT_SINGLE_RUN = 60
    TIMEOUT_ALL_FLAGS = FACTORY_FLAG_COUNT * TIMEOUT_SINGLE_RUN
    # If the flags are wrong, verification should fail quickly.
    TIMEOUT_FLAG_FAILURE = 10
    # Delay the gsctool command that starts verification, so the test can start
    # looking for the AP RO verify command output before the gsctool command
    # runs.
    START_DELAY = 5

    DIGEST_RE = r' digest ([0-9a-f]{64})'
    CALCULATED_DIGEST_RE = 'Calculated' + DIGEST_RE
    STORED_DIGEST_RE = 'Stored' + DIGEST_RE

    # The FAFT GBB flags are innocuous. Check that the DUT is using those or
    # doesn't have any flags set.
    SUPPORTED_FLAGS = [0, 0x140]
    TEST_RO_VPD_KEY = 'faft_apro_test_key'

    # 0x42b9 is the last value in the cr50 factory flag list. Use it to verify
    # cr50 can regenerate the hash with all factory flags in a reasonable time.
    LAST_FACTORY_FLAG_VAL = 0x42b9
    FLAG_0 = 0

    FLAGS_NONE = None
    FLAG_42B9 = '0x%x' % LAST_FACTORY_FLAG_VAL
    FLAG_0 = '0x%x' % FLAG_0
    FLAG_NA = 'na'

    # GBB status bits
    GBBS_INJECT_FLAGS = 1
    GBBS_FLAGS_IN_HASH = 2
    GBBD_INVALID = 'na (10)'
    GBBD_SAVED = 'ok (%d)'
    # If the flags are 0, then cr50 won't try to inject them.
    STATUS_0 = GBBS_FLAGS_IN_HASH
    # If the gbb flags are in the hash and they were non-zero when the hash
    # was generated, then cr50 should try to inject them when calculating
    # the hash.
    STATUS_LAST_FLAG = (GBBS_FLAGS_IN_HASH | GBBS_INJECT_FLAGS)
    # The flags aren't in the hash, so they're not injected. Cr50 should save
    # the status as 0.
    STATUS_OUTSIDE_HASH = 0
    GBBD_SAVED_0 = GBBD_SAVED % STATUS_0
    GBBD_SAVED_LAST_FLAG = GBBD_SAVED % STATUS_LAST_FLAG
    GBBD_SAVED_FLAGS_NOT_IN_HASH = GBBD_SAVED % STATUS_OUTSIDE_HASH
    # These messages should never happen. Fail if they show up in any AP RO
    # verificaton output.
    ERR_MESSAGES = ['Could not find GBB area', 'WATCHDOG']

    def initialize(self, host, cmdline_args, full_args={}):
        """Initialize servo"""
        self.ran_test = False
        super(firmware_GSCAPROV1Trigger,
              self).initialize(host,
                               cmdline_args,
                               full_args,
                               restore_cr50_image=True)
        if not self.gsc.ap_ro_version_is_supported(self.TEST_AP_RO_VER):
            raise error.TestNAError('GSC does not support AP RO v%s' %
                                    self.TEST_AP_RO_VER)

        self._original_timeout = float(self.servo.get('cr50_uart_timeout'))
        rw_ver = self.get_saved_cr50_original_version()[1]
        _, major, minor = rw_ver.split('.')
        if (int(major) < self.MIN_RELEASE_MAJOR or
            int(minor) < self.MIN_RELEASE_MINOR):
            raise error.TestNAError('Test does not support cr50 (%r). Update '
                                    'to 0.%s.%s' % (rw_ver,
                                                    self.MIN_RELEASE_MAJOR,
                                                    self.MIN_RELEASE_MINOR))

        dbg_ver = cr50_utils.InstallImage(self.host,
                                          self.get_saved_dbg_image_path(),
                                          '/tmp/cr50.bin')[1][1]
        if cr50_utils.GetNewestVersion(dbg_ver,
                                       self.MIN_DBG_VER) == self.MIN_DBG_VER:
            raise error.TestNAError('Update DBG image to 6.100 or newer.')

        self._start_gbb_flags = self.faft_client.bios.get_gbb_flags()
        logging.info('GBB flags: %x', self._start_gbb_flags)
        # Refuse to run with unsupported gbb flags, because this test sets the
        # flags to 0 and it could prevent the device from booting if it's
        # currently relying on the FORCE_DEV_MODE flag.
        if self._start_gbb_flags not in self.SUPPORTED_FLAGS:
            raise error.TestNaError('Unsupported DUT GBB flags 0x%x. Set the '
                                    'flags to one of %r to run the test.' %
                                    (self._start_gbb_flags,
                                     self.SUPPORTED_FLAGS))

    def run_ro_vpd_cmd(self, cmd):
        """Run RO_VPD command

        @param cmd: the RO vpd command to run
        """
        return self.host.run('vpd -i RO_VPD ' + cmd)

    def delete_test_ro_vpd_key(self):
        """Remove the test key from the RO_VPD"""
        self.run_ro_vpd_cmd('-d ' + self.TEST_RO_VPD_KEY)

    def set_test_ro_vpd_key(self, val):
        """Remove the test key from the RO_VPD"""
        self.run_ro_vpd_cmd('-s %s=%s' % (self.TEST_RO_VPD_KEY, val))

    def restore_ro(self):
        """Restore the original test RO_VPD test key value."""
        self.set_test_ro_vpd_key('original_val')
        self._ro_desc = 'ok'

    def modify_ro(self):
        """Change a RO_VPD value to modify RO."""
        self.set_test_ro_vpd_key('modified_val')
        self._ro_desc = 'modified'

    def update_to_dbg_and_clear_hash(self):
        """Clear the Hash."""
        # Make sure the AP is up before trying to update.
        self.recover_dut()
        self.clear_gbb_flags()
        self._retry_gsc_update_with_ccd_and_ap(self._dbg_image_path, 3, False)
        self.gsc.send_command('ap_ro_info erase')
        time.sleep(3)
        if self.gsc.get_ap_ro_info()['hash']:
            raise error.TestError('Could not erase hash')
        self._try_to_bring_dut_up()

    def after_run_once(self):
        """Reboot cr50 to recover the dut."""
        try:
            self.recover_dut()
        finally:
            super(firmware_GSCAPROV1Trigger, self).after_run_once()

    def set_hash(self, regions):
        """Set the Hash.

        @param regions: a space separated string with the names of the regions
                        to include in the hash. ex "FMAP GBB"
        """
        self.recover_dut()
        result = self.host.run('ap_ro_hash.py -v True %s' % regions)
        logging.info(result)
        time.sleep(3)
        ap_ro_info = self.gsc.get_ap_ro_info()
        self._hash_desc = '%s flags' % self._flag_desc
        ap_ro_info = self.gsc.get_ap_ro_info()
        if ap_ro_info['supported'] and not ap_ro_info['hash']:
            raise error.TestError('Could not set hash %r' % result)

    def rollback_to_release_image(self):
        """Update to the release image."""
        self._retry_gsc_update_with_ccd_and_ap(
                self.get_saved_cr50_original_path(), 3, rollback=True)
        self._try_to_bring_dut_up()

    def set_gbb_flags(self, flags):
        """Set the GBB flags.

        @params flags: integer value to set the gbb flags to.
        """
        self.host.run('/usr/bin/futility gbb --set --flash --flags=0x%x' %
                      flags)
        logging.info('Set GBB: %x', self.faft_client.bios.get_gbb_flags())

    def set_factory_gbb_flags(self):
        """Set the GBB flags to one of the cr50 factory flags."""
        self.set_gbb_flags(self.LAST_FACTORY_FLAG_VAL)
        self._flag_desc = '%x' % self.LAST_FACTORY_FLAG_VAL

    def clear_gbb_flags(self):
        """Set the GBB flags to 0."""
        self.set_gbb_flags(0)
        self._flag_desc = 'cleared'

    def cleanup(self):
        """Clear the hash, remove the test ro vpd key, and restore the flags."""
        try:
            if not self.ran_test:
                return
            logging.info('Cleanup')
            self.recover_dut()
            self.clear_gbb_flags()
            self.update_to_dbg_and_clear_hash()
            self.rollback_to_release_image()
            self.delete_test_ro_vpd_key()
            self.faft_client.bios.set_gbb_flags(self._start_gbb_flags)
        finally:
            super(firmware_GSCAPROV1Trigger, self).cleanup()

    def recover_dut(self):
        """Reboot gsc to recover the dut."""
        logging.info('Recover DUT')
        ap_ro_info = self.gsc.get_ap_ro_info()
        logging.info(ap_ro_info)
        if ap_ro_info['result'] != self.APRO_FAIL:
            self._try_to_bring_dut_up()
            return
        time.sleep(3)
        self.gsc.send_command('ccd testlab open')
        time.sleep(3)
        self.gsc.reboot()
        time.sleep(self.faft_config.delay_reboot_to_ping)
        self.gsc.get_ap_ro_info()
        self._try_to_bring_dut_up()
        self.gsc.send_command('ccd testlab open')

    def verification_in_progress(self):
        """Returns True if AP RO verification is running."""
        return self.gsc.get_ap_ro_info()['result']  == self.APRO_IN_PROGRESS

    def get_apro_output(self, timeout):
        """Get the AP RO console output.

        @param timeout: time in seconds to wait for AP RO verification to
                        finish.
        """
        self.servo.set_nocheck('cr50_uart_timeout', timeout + self.START_DELAY)
        start_time = time.time()
        try:
            # AP RO verification will start in the background. Wait for cr50 to
            # finish verification collect all of the AP RO output.
            cmd = 'noop_wait_apro ' + self._desc
            rv = self.gsc.send_command_get_output(cmd, [self.APRO_OUTPUT_RE])
        finally:
            self.servo.set_nocheck('cr50_uart_timeout', self._original_timeout)
        logging.info('AP RO verification ran in %ds', time.time() - start_time)
        return rv[0][0]

    def _start_apro_verify(self):
        """Start AP RO verification with a delay.

        Delay starting AP RO verification, so the test can get the full
        AP RO console output.
        """
        if not self.host.ping_wait_up(self.faft_config.delay_reboot_to_ping):
            raise error.TestError('AP is %s. Dut is not sshable. ' %
                                  self.cr50.get_ccdstate('AP'))
        apro_start_cmd = utils.sh_escape('sleep %d ; gsctool -aB start' %
                                         self.START_DELAY)
        full_ssh_cmd = '%s "%s"' % (self.host.ssh_command(options='-tt'),
                                    apro_start_cmd)
        # Start running the Cr50 Open process in the background.
        self._apro_start = utils.BgJob(full_ssh_cmd,
                                         nickname='apro_start',
                                         stdout_tee=utils.TEE_TO_LOGS,
                                         stderr_tee=utils.TEE_TO_LOGS)

    def _close_apro_start(self):
        """Terminate the process and check the results."""
        exit_status = utils.nuke_subprocess(self._apro_start.sp)
        delattr(self, '_apro_start')
        if exit_status:
            logging.info('exit status: %d', exit_status)

    def trigger_verification(self,
                             exp_result,
                             exp_calculations,
                             timeout,
                             exp_gbb,
                             exp_flags,
                             end_if_unsupported=True):
        """Trigger verification.

        Trigger verification. Verify the AP RO behavior by checking the result
        matches the expected result. Check that cr50 calculated the expected
        number of hashes within timeout seconds. Check the gbb value from
        ap_ro_info matches exp_gbb and all of the expected strings show up
        in the output.

        @param exp_result: expected value for the ap_ro_info result field after
                           verification runs.
        @param exp_calculations: expected number of hashes cr50 will generate
                                 during verification.
        @param timeout: maximum time in seconds that the AP RO verification run
                        can take.
        @param exp_gbb: string that should be found in the ap_ro_info gbb field.
        @param exp_flags: None or the flag string if the gbbd is saved
        @param end_if_unsupported: raise testNA if the device doesn't support
                                   verification.
        """
        self._desc = ('%s: current flags(%s) ro(%s) saved hash(%s) - '
                      'expected result(%d)' %
                      (self._prefix, self._flag_desc, self._ro_desc,
                       self._hash_desc, exp_result))
        # CCD has to be open to trigger verification.
        self.fast_ccd_open(True)
        logging.info('Run: %s', self._desc)

        self.recover_dut()
        try:
            self._start_apro_verify()
            contents = self.get_apro_output(timeout)
        finally:
            self._close_apro_start()
        logging.info('finished %r:%s', self._desc, contents)

        try:
            if self.verification_in_progress():
                raise error.TestFail('%s: Verification did not finish in %ds' %
                                     (self._desc, timeout))

            for msg in self.ERR_MESSAGES:
                if msg in contents:
                    raise error.TestFail('%s: %r showed up in contents %s' %
                                         (self._desc, msg, contents))
        finally:
            ap_ro_info = self.gsc.get_ap_ro_info()
            # Make sure to recover the dut.
            self.recover_dut()

        # cr50 only prints calculated and stored hashes after AP RO verificaiton
        # fails. These sets will be empty if verification passed every time.
        calculated = set(re.findall(self.CALCULATED_DIGEST_RE, contents))
        stored = set(re.findall(self.STORED_DIGEST_RE, contents))
        logging.info('Stored: %r', stored)
        logging.info('Calculated (%d): %s', len(calculated),
                     pprint.pformat(calculated))
        logging.info('Results: %s', pprint.pformat(ap_ro_info))

        if not ap_ro_info['supported']:
            reason = ap_ro_info['reason']
            if 'not programmed' not in reason:
                if end_if_unsupported:
                    raise error.TestNAError(reason)
                raise error.TestFail('%s: verification unsupported: %s' %
                                     (self._desc, reason))

        if len(calculated) != exp_calculations:
            raise error.TestFail('%s: Calculated %d digests instead of %d' %
                                 (self._desc, len(calculated),
                                  exp_calculations))
        if exp_flags != ap_ro_info['flags']:
            raise error.TestFail(
                    '%s: %r not found in flags %r -- stored: %r calc: %r' %
                    (self._desc, exp_flags, ap_ro_info['flags'], stored,
                     calculated))
        if exp_gbb not in ap_ro_info['gbbd']:
            raise error.TestFail(
                    '%s: %r not found in gbb %r -- stored: %r calc: %r' %
                    (self._desc, exp_gbb, ap_ro_info['gbbd'], stored,
                     calculated))
        if exp_result != ap_ro_info['result']:
            raise error.TestFail(
                    '%s: %r not found in status %r -- stored: %r calc: %r' %
                    (self._desc, exp_result, ap_ro_info['result'], stored,
                     calculated))

    def run_once(self):
        """Save hash and trigger verification"""
        self.ran_test = True
        # The DBG image can set the hash when the board id is saved. The release
        # image can't. Set the hash with the DBG image, so the test doesn't need
        # to erase the board id. This test verifies triggering AP RO
        # verification. It's not about saving the hash. Whenever the test
        # updates the hash, it'll update to the dbg image, set the hash, and
        # then rollback to the released image.
        self.update_to_dbg_and_clear_hash()

        # Generate a hash with the GBB flags set to 0.
        # Set the GBB flags to 0.
        self.clear_gbb_flags()
        # The test creates a RO_VPD key and modifies it to modify RO. It's a
        # bogus key. It doesn't change any device behavior. It's just a way
        # to easily modify RO.
        self.restore_ro()
        self.set_hash('WP_RO')
        self.rollback_to_release_image()
        self.fast_ccd_open(True)

        logging.info('Verifying standard behavior')
        logging.info('the hash was generated with 0 gbb flags')
        self._prefix = 'standard'
        # Set the flags to a non-zero value. Make sure it fails almost
        # immediately because the flags are wrong.
        self.set_factory_gbb_flags()
        # This is a pretty basic test. If the board says verification is
        # unsupported, fail with TestNA.
        self.trigger_verification(self.APRO_FAIL,
                                  0,
                                  self.TIMEOUT_FLAG_FAILURE,
                                  self.GBBD_INVALID,
                                  self.FLAGS_NONE,
                                  end_if_unsupported=True)
        # Modify RO. Cr50 should still fail immediately because the flags are
        # wrong.
        self.modify_ro()
        self.trigger_verification(self.APRO_FAIL, 0,
                                  self.TIMEOUT_FLAG_FAILURE,
                                  self.GBBD_INVALID,
                                  self.FLAGS_NONE)
        self.clear_gbb_flags()
        # Cr50 should try all factory flags and fail with a hash mismatch.
        self.trigger_verification(self.APRO_FAIL, self.FACTORY_FLAG_COUNT,
                                  self.TIMEOUT_ALL_FLAGS,
                                  self.GBBD_INVALID,
                                  self.FLAGS_NONE)
        # Restore RO. Check AP RO verification starts passing.
        self.restore_ro()
        # Verification should pass during the first flag check since the hash
        # was generated with gbb flags set to 0.
        self.trigger_verification(self.APRO_PASS, 0,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_SAVED_0,
                                  self.FLAG_0)
        # Trigger verification multiple times. Make sure it doesn't fail or
        # change.
        self.trigger_verification(self.APRO_PASS, 0,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_SAVED_0,
                                  self.FLAG_0)
        self.trigger_verification(self.APRO_PASS, 0,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_SAVED_0,
                                  self.FLAG_0)
        # With the saved flags AP RO verification should only try one flag. It
        # should fail more quickly.
        self.modify_ro()
        self.trigger_verification(self.APRO_FAIL, 1,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_SAVED_0,
                                  self.FLAG_0)

        # TODO(b/327795084): reenable after flakiness is investigated.
        return
        # Generate a hash with non-zero flags.
        self.update_to_dbg_and_clear_hash()
        self.restore_ro()
        self.set_factory_gbb_flags()
        self.set_hash('WP_RO')
        # Clear the gbb flags, so the test can open ccd.
        self.clear_gbb_flags()
        self.rollback_to_release_image()
        self.fast_ccd_open(True)
        self.set_factory_gbb_flags()

        logging.info('Verifying the gbb workaround')
        logging.info('cr50 can handle hashes generated with non-zero flags')
        self._prefix = 'non-zero factory flags'
        # The gbb flags are non-zero. Cr50 should fail immediately since they're
        # non-zero.
        self.trigger_verification(self.APRO_FAIL, 0,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_INVALID,
                                  self.FLAGS_NONE)

        # The flags are wrong and RO is wrong. Cr50 verifies the flags first, so
        # it should still fail immediately and not generate any hashes.
        self.modify_ro()
        self.trigger_verification(self.APRO_FAIL, 0,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_INVALID,
                                  self.FLAGS_NONE)
        # The flags are ok. RO is wrong. Cr50 should try all factory flags and
        # fail with a hash mismatch.
        self.clear_gbb_flags()
        self.trigger_verification(self.APRO_FAIL, self.FACTORY_FLAG_COUNT,
                                  self.TIMEOUT_ALL_FLAGS,
                                  self.GBBD_INVALID,
                                  self.FLAGS_NONE)
        # The test saved the hash with the last factory flag. Cr50 should
        # calculate hashes with all of the factory flags and pass on the last
        # one.
        self.restore_ro()
        # Cr50 should match the gbb flag and then save it.
        self.trigger_verification(self.APRO_PASS, self.FACTORY_FLAG_COUNT - 1,
                                  self.TIMEOUT_ALL_FLAGS,
                                  self.GBBD_SAVED_LAST_FLAG,
                                  self.FLAG_42B9)
        # The next verification cr50 should load the matched flag and only try
        # that.
        self.trigger_verification(self.APRO_PASS, 0,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_SAVED_LAST_FLAG,
                                  self.FLAG_42B9)
        # RO verificaiton will fail since the RO is changed, but cr50 should
        # only try the flag it matched originally.
        self.modify_ro()
        self.trigger_verification(self.APRO_FAIL, 1,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_SAVED_LAST_FLAG,
                                  self.FLAG_42B9)
        # RO and the flags are wrong, but cr50 shouldn't try to generate a hash.
        # It should fail before that since the flags are wrong.
        self.set_factory_gbb_flags()
        # Cr50 checks the current flags, before it tries to use the saved gbbd.
        # Cr50 will fail with non-zero flags before it loads the gbbd, so
        # LOAD_42B9 shouldn't show up in the result. It should only have the
        # invalid gbb flags messages.
        self.trigger_verification(self.APRO_FAIL, 0,
                                  self.TIMEOUT_FLAG_FAILURE,
                                  self.GBBD_SAVED_LAST_FLAG,
                                  self.FLAG_42B9)

        # After the state is restored to a good state, cr50 should pass again.
        self.clear_gbb_flags()
        self.restore_ro()
        self.trigger_verification(self.APRO_PASS, 0,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_SAVED_LAST_FLAG,
                                  self.FLAG_42B9)
        self.gsc.reboot()
        self._try_to_bring_dut_up()
        # Make sure it works the same after cr50 reboots.
        self.trigger_verification(self.APRO_PASS, 0,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_SAVED_LAST_FLAG,
                                  self.FLAG_42B9)

        # Set a hash with FMAP in the hash and the GBB outside of the hash.
        # Cr50 should not care about the GBB flags in this case.
        self.update_to_dbg_and_clear_hash()
        self.restore_ro()
        self.set_factory_gbb_flags()
        self.set_hash('FMAP RO_VPD')

        self.clear_gbb_flags()
        self.rollback_to_release_image()
        self.fast_ccd_open(True)
        self.set_factory_gbb_flags()

        logging.info('Verifying setup with GBB outside of hash')
        self._prefix = 'gbb outside of hash'

        # GBB flags are non-zero, but they're outside of the hash, so it
        # shouldn't matter.
        self.trigger_verification(self.APRO_PASS, 0,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_SAVED_FLAGS_NOT_IN_HASH,
                                  self.FLAG_NA)
        # GBB flags are now zero, but they're outside of the hash, so it
        # shouldn't matter.
        self.clear_gbb_flags()
        self.trigger_verification(self.APRO_PASS, 0,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_SAVED_FLAGS_NOT_IN_HASH,
                                  self.FLAG_NA)
        # Modify the RO_VPD. It's in the hash, so verification should fail.
        self.modify_ro()
        self.trigger_verification(self.APRO_FAIL, 1,
                                  self.TIMEOUT_SINGLE_RUN,
                                  self.GBBD_SAVED_FLAGS_NOT_IN_HASH,
                                  self.FLAG_NA)

        # Cr50 will fail verification if the FMAP is outside of the hash since
        # it can't trust the GBB location.
        self.update_to_dbg_and_clear_hash()
        self.restore_ro()
        self.clear_gbb_flags()
        self.set_hash('GBB')
        self.rollback_to_release_image()
        self.fast_ccd_open(True)

        logging.info('Verifying setup with FMAP outside of hash')
        self._prefix = 'fmap not in hash'

        # There's no way to pass since FMAP isn't in the hash. The factory
        # process is standard. FMAP should be in the hash.
        self.trigger_verification(self.APRO_FAIL, 0,
                                  self.TIMEOUT_FLAG_FAILURE,
                                  self.GBBD_INVALID,
                                  self.FLAGS_NONE)
