• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2017 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging
6
7from autotest_lib.client.common_lib import error
8from autotest_lib.server.cros.faft.cr50_test import Cr50Test
9
10
11class firmware_Cr50Testlab(Cr50Test):
12    """Verify cr50 testlab enable/disable."""
13    version = 1
14    ACCESS_DENIED = 'Access Denied'
15    INVALID_PARAM = 'Parameter 1 invalid'
16    BASIC_ERROR = 'Usage: ccd '
17
18    def initialize(self, host, cmdline_args, full_args):
19        """Initialize servo. Check that it can access cr50"""
20        super(firmware_Cr50Testlab, self).initialize(host, cmdline_args,
21                full_args)
22
23        if not hasattr(self, 'cr50'):
24            raise error.TestNAError('Test can only be run on devices with '
25                                    'access to the Cr50 console')
26        if self.servo.main_device_is_ccd():
27            raise error.TestNAError('Use a flex cable instead of CCD cable.')
28
29        # Get the current reset count, so we can check that there haven't been
30        # any cr50 resets at any point during the test.
31        self.start_reset_count = self.servo.get('cr50_reset_count')
32
33
34    def try_testlab(self, mode, err=''):
35        """Try to modify ccd testlab mode.
36
37        Args:
38            mode: The testlab command: 'on', 'off', or 'open'
39            err: An empty string if the command should succeed or the error
40                 message.
41
42        Raises:
43            TestFail if setting the ccd testlab mode doesn't match err
44        """
45        logging.info('Setting ccd testlab %s', mode)
46        rv = self.cr50.send_command_get_output('ccd testlab %s' % mode,
47                ['ccd.*>'])[0]
48        logging.info(rv)
49        if err not in rv or (not err and self.BASIC_ERROR in rv):
50            raise error.TestFail('Unexpected result setting "%s": %r' % (mode,
51                    rv))
52        if err:
53            return
54
55        if mode == 'open':
56            if mode != self.cr50.get_ccd_level():
57                raise error.TestFail('ccd testlab open did not open the device')
58        else:
59            self.cr50.run_pp(self.cr50.PP_SHORT)
60            if (mode == 'on') != self.cr50.testlab_is_on():
61                raise error.TestFail('Testlab mode could not be turned %s' %
62                        mode)
63            logging.info('Set ccd testlab %s', mode)
64
65
66    def check_reset_count(self):
67        """Verify there haven't been any cr50 reboots"""
68        reset_count = self.servo.get('cr50_reset_count')
69        if self.start_reset_count != reset_count:
70            raise error.TestFail('Unexpected cr50 reboot')
71
72
73    def reset_ccd(self):
74        """Enable ccd testlab mode and set the privilege level to open"""
75        logging.info('Resetting CCD state')
76        # If testlab mode is enabled, use that to open ccd. It is a lot faster.
77        if self.cr50.testlab_is_on():
78            self.try_testlab('open')
79        else:
80            self.enter_mode_after_checking_tpm_state('dev')
81            self.ccd_open_from_ap()
82        self.try_testlab('on')
83        self.check_reset_count()
84
85
86    def run_once(self):
87        """Try to set testlab mode from different privilege levels."""
88        # Dummy isn't a valid mode. Make sure it fails
89        self.reset_ccd()
90        self.try_testlab('dummy', err=self.INVALID_PARAM)
91
92        # If ccd is locked, ccd testlab dummy should fail with access denied not
93        # invalid param.
94        self.reset_ccd()
95        self.cr50.set_ccd_level('lock')
96        self.try_testlab('dummy', err=self.ACCESS_DENIED)
97
98        # CCD can be opened without physical presence if testlab mode is enabled
99        self.reset_ccd()
100        self.try_testlab('on')
101        self.try_testlab('open')
102        self.check_reset_count()
103
104        # You shouldn't be able to use testlab open if it is disabled
105        self.reset_ccd()
106        self.try_testlab('off')
107        self.try_testlab('open', err=self.ACCESS_DENIED)
108        self.check_reset_count()
109
110        # You can't turn on testlab mode while ccd is locked
111        self.reset_ccd()
112        self.cr50.set_ccd_level('lock')
113        self.try_testlab('on', err=self.ACCESS_DENIED)
114        self.check_reset_count()
115
116        # You can't turn off testlab mode while ccd is locked
117        self.reset_ccd()
118        self.cr50.set_ccd_level('lock')
119        self.try_testlab('off', err=self.ACCESS_DENIED)
120        self.check_reset_count()
121
122        # If testlab mode is enabled, you can open the device without physical
123        # presence by using 'ccd testlab open'.
124        self.reset_ccd()
125        self.try_testlab('on')
126        self.cr50.set_ccd_level('lock')
127        self.try_testlab('open')
128        self.check_reset_count()
129
130        # If testlab mode is disabled, testlab open should fail with access
131        # denied.
132        self.reset_ccd()
133        self.try_testlab('off')
134        self.cr50.set_ccd_level('lock')
135        self.try_testlab('open', err=self.ACCESS_DENIED)
136        self.check_reset_count()
137        logging.info('ccd testlab is accessbile')
138