1# Lint as: python2, python3 2# Copyright 2018 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6 7 8import difflib 9import logging 10 11from autotest_lib.client.common_lib import error 12from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 13 14 15class servo_ConsoleStress(FirmwareTest): 16 """Verify the given console by running the same command many times. 17 18 Use the given command to verify the specified console. This command should 19 have output that doesn't change. This test will fail if the command output 20 changes at all or the control fails to run. 21 """ 22 version = 1 23 24 # Give the EC some time to enter/resume from hibernate 25 EC_SETTLE_TIME = 10 26 27 def _get_servo_cmd_output(self, cmd): 28 """Get the output from the specified servo control""" 29 return self.servo.get(cmd).strip() 30 31 32 def _get_console_cmd_output(self, cmd): 33 """Run the command on the console specified by the test args.""" 34 return self._test_console_obj.send_command_get_output(cmd, 35 ['%s.*>' % cmd])[0].strip() 36 37 def cleanup(self): 38 """Restore the chan settings""" 39 if hasattr(self, '_test_console_obj'): 40 self._test_console_obj.send_command('chan restore') 41 super(servo_ConsoleStress, self).cleanup() 42 43 44 def run_once(self, attempts, cmd_type, cmd): 45 """Make sure cmd output doesn't change during any of the runs.""" 46 if cmd_type == 'servo': 47 self._get_test_cmd_output = self._get_servo_cmd_output 48 elif cmd_type in ['ec', 'cr50']: 49 self._test_console_obj = getattr(self, cmd_type) 50 # Set chan to 0, so only console task output will print. This will 51 # prevent other task output from corrupting the command output. 52 self._test_console_obj.send_command('chan save') 53 self._test_console_obj.send_command('chan 0') 54 self._get_test_cmd_output = self._get_console_cmd_output 55 else: 56 raise error.TestError('Invalid cmd type %r' % cmd_type) 57 58 start = self._get_test_cmd_output(cmd) 59 if not start: 60 raise error.TestError('Could not get %s %s output' % (cmd_type, 61 cmd)) 62 logging.info('start output: %r', start) 63 64 # Run the command for the given number of tries. If the output changes 65 # or the command fails to run raise an error. 66 for i in range(attempts): 67 try: 68 output = self._get_test_cmd_output(cmd) 69 except Exception as e: 70 raise error.TestFail('failed to get %s %r during run %d' % 71 (cmd_type, cmd, i)) 72 73 # The command will be run hundreds of times. Print the run number 74 # command output once every hundred runs, so you can tell the test 75 # is progressing but don't spam too much output. 76 if (i % 100) == 0: 77 logging.info('run %d %r', i, start) 78 79 if start != output: 80 logging.info('MISMATCH:\n %s', '\n'.join(difflib.unified_diff( 81 start.splitlines(), output.splitlines()))) 82 raise error.TestFail('%s %r output changed after %d runs' % 83 (cmd_type, cmd, i)) 84