普通文本  |  165行  |  5.91 KB

# Copyright (c) 2011 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 time

from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error, smogcheck_tpm, \
    smogcheck_ttci, smogcheck_util
from autotest_lib.client.cros import service_stopper


class hardware_TPMTakeOwnership(test.test):
    version = 1


    def initialize(self):
        smogcheck_util.enableI2C()
        self.ttci_obj = None
        self.tpm_obj = None
        self.attr_dict = dict()  # Attributes to output
        self.perf_dict = dict()  # Performance measures to output
        self._services = service_stopper.ServiceStopper(['cryptohomed',
                                                         'chapsd', 'tcsd'])
        self._services.stop_services()


    def _prepareTpmController(self):
        """Prepare a TpmController instance for use.

        Returns:
          an operational TpmControler instance, ready to use.

        Raises:
          TestFail: if error creating a new TpmController instance.
        """
        try:
            self.tpm_obj = smogcheck_tpm.TpmController()
        except smogcheck_tpm.SmogcheckError as e:
            raise error.TestFail('Error creating a TpmController: %s', e)


    def _prepareTtciController(self):
        """Prepare TtciController instances for use.

        Returns:
          an operational TtciController instance, ready to use.

        Raises:
          TestFail: if error creating a new TtciController instance.
        """
        try:
            self.ttci_obj = smogcheck_ttci.TtciController()
        except smogcheck_ttci.TtciError as e:
            raise error.TestFail('Error creating a TtciController: %s' % e)


    def _sleep(self, amount):
        """Sleeps for 'amount' of time and logs a message.

        Args:
          amount: an integer or float in seconds.
        """
        time.sleep(amount)
        if amount >= 1:
            logging.debug('Slept for %0.2f second', amount)
        elif amount >= 0.001:
            logging.debug('Slept for %0.2f millisecond', (amount * 1000))
        else:
            logging.debug('Slept for %0.2f microsecond', (amount * 1000000))


    def run_once(self, loop=-1, max_acceptable_delay=-1):
        self._prepareTtciController()
        self._prepareTpmController()

        timestamps = dict()
        time_list = []
        try:
            # Verify TPM is operational before triggering hardware Reset
            self.tpm_obj.runTpmSelfTest()

            # Activate hardware Reset signal
            if self.ttci_obj.TTCI_Set_Reset_Control(turn_on=True):
                raise error.TestFail('TTCI_Set_Reset_Control() error: %s' %
                                     self.ttci_obj.err)
            logging.info('TPM hardware Reset signal activated')

            # Wait for 100 milisec
            self._sleep(0.1)

            # Deactivate hardware Reset signal
            if self.ttci_obj.TTCI_Set_Reset_Control(turn_on=False):
                raise error.TestFail('TTCI_Set_Reset_Control() error: %s' %
                                     self.ttci_obj.err)
            logging.info('TPM hardware Reset signal DEactivated')

            # Run TPM_Starup
            smogcheck_util.runInSubprocess(['tpmc', 'startup'])

            # Run TPM_SelfTestFull
            smogcheck_util.runInSubprocess(['tpmc', 'test'])

            # Run TPM_AssertPhysicalPresence
            smogcheck_util.runInSubprocess(['tpmc', 'ppon'])

            # Run TPM_OwnerClear
            smogcheck_util.runInSubprocess(['tpmc', 'clear'])

            for i in range(loop):
                smogcheck_util.runInSubprocess(['start', 'tcsd'])
                # Wait 3 sec for tcsd to start
                self._sleep(3)

                # Run TPM_TakeOwnership and record elapsed time
                timestamps[i] = self.tpm_obj.takeTpmOwnership()

                smogcheck_util.runInSubprocess(['stop', 'tcsd'])
                # Wait for 1 sec for tcsd to stop
                self._sleep(1)

                # Run TPM_OwnerClear
                smogcheck_util.runInSubprocess(['tpmc', 'clear'])

            # Output timing measurements
            for k, v in timestamps.iteritems():
                sec, ms = divmod(v/1000, 1000)
                key = 'iteration_%d_delay_in_sec' % k
                delay_float = float(v)/1000000
                self.perf_dict[key] = delay_float
                time_list.append(delay_float)
            self.perf_dict['num_total_iterations'] = len(timestamps)
            # TODO(tgao): modify generate_test_report to support attr_dict
            #self.attr_dict['timing_measurement_for'] = 'TPM_TakeOwnership'
            time_list.sort()
            time_list.reverse()
            count = 0
            for i in time_list:
                if i <= max_acceptable_delay:
                    break
                logging.debug('Actual value (%0.2f) exceeds max (%0.2f)',
                              i, max_acceptable_delay)
                count += 1
            self.perf_dict['num_iterations_exceeding_max_delay'] = count
            self.perf_dict['max_acceptable_delay_in_sec'] = max_acceptable_delay
            self.perf_dict['min_delay_in_sec_actual'] = time_list[-1]
            # Set this attribute last. If it exceeds user-specified limit in
            # test suite control file, output report would still be complete
            self.perf_dict['max_delay_in_sec_actual'] = time_list[0]

        except smogcheck_tpm.SmogcheckError as e:
            raise error.TestFail('Error: %r' % e)
        finally:
            # Output attibutes and performance keyval pairs
            self.write_iteration_keyval(self.attr_dict, self.perf_dict)

            # Close TPM context
            if self.tpm_obj.closeContext():
                raise error.TestFail('Error closing tspi context')


    def cleanup(self):
        self._services.restore_services()