Home | History | Annotate | Download | only in platform_ExternalUSBBootStress
      1 # Copyright (c) 2012 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 
      5 import logging, re, time
      6 
      7 from autotest_lib.server import test
      8 from autotest_lib.server.cros import stress
      9 from autotest_lib.server.cros.servo import servo
     10 from autotest_lib.client.common_lib import error
     11 
     12 _WAIT_DELAY = 5
     13 
     14 class platform_ExternalUSBBootStress(test.test):
     15     """Uses servo to repeatedly connect/remove USB devices during boot."""
     16     version = 1
     17 
     18     def run_once(self, host, reboots):
     19         reboots = int(reboots)
     20         self.client = host
     21         # The servo hubs come up as diffs in connected components.  These
     22         # should be ignored for this test.  It is a list so when servo next
     23         # is available it may have a differnet hub which can be appended.
     24         servo_hardware_list = ['Standard Microsystems Corp.']
     25 
     26 
     27         def strip_lsusb_output(lsusb_output):
     28             items = lsusb_output.split('\n')
     29             named_list = []
     30             unnamed_device_count = 0
     31             for item in items:
     32                 columns = item.split(' ')
     33                 if len(columns) == 6 or len(' '.join(columns[6:]).strip()) == 0:
     34                     logging.info('Unnamed device located, adding generic name.')
     35                     name = 'Unnamed device %d' % unnamed_device_count
     36                     unnamed_device_count += 1
     37                 else:
     38                     name = ' '.join(columns[6:]).strip()
     39                 if name not in servo_hardware_list:
     40                     named_list.append(name)
     41             return named_list
     42 
     43 
     44         def set_hub_power(on=True, check_host_detection=False):
     45             reset = 'off'
     46             if not on:
     47                 reset = 'on'
     48             host.servo.set('dut_hub1_rst1', reset)
     49             if check_host_detection:
     50                 time.sleep(_WAIT_DELAY)
     51                 return strip_lsusb_output(host.run('lsusb').stdout.strip())
     52 
     53 
     54         def stress_hotplug():
     55             # Devices need some time to come up and to be recognized.  However
     56             # this is a stress test so we want to move reasonably fast.
     57             time.sleep(2)
     58             removed = set_hub_power(False)
     59             time.sleep(1)
     60             connected = set_hub_power()
     61 
     62 
     63         host.servo.switch_usbkey('dut')
     64         host.servo.set('usb_mux_sel3', 'dut_sees_usbkey')
     65 
     66         # There are some mice that need the data and power connection to both
     67         # be removed, otherwise they won't come back up.  This means that the
     68         # external devices should only use the usb connections labeled:
     69         # USB_KEY and DUT_HUB1_USB.
     70         connected = set_hub_power(check_host_detection=True)
     71         off_list = set_hub_power(on=False, check_host_detection=True)
     72         diff_list = set(connected).difference(set(off_list))
     73         if len(diff_list) == 0:
     74             raise error.TestError('No connected devices were detected.  Make '
     75                                   'sure the devices are connected to USB_KEY '
     76                                   'and DUT_HUB1_USB on the servo board.')
     77         logging.info('Connected devices list: %s' % diff_list)
     78         set_hub_power(True)
     79 
     80         lsb_release = host.run('cat /etc/lsb-release').stdout.split('\n')
     81         unsupported_gbb_boards = ['x86-mario', 'x86-alex', 'x86-zgb']
     82         skip_gbb = False
     83         for line in lsb_release:
     84             m = re.match(r'^CHROMEOS_RELEASE_BOARD=(.+)$', line)
     85             if m and m.group(1) in unsupported_gbb_boards:
     86                 skip_gbb = True
     87                 break
     88 
     89         logging.info('Rebooting the device %d time(s)' % reboots)
     90         for i in xrange(reboots):
     91             # We want fast boot past the dev screen
     92             if not skip_gbb:
     93                 host.run('/usr/share/vboot/bin/set_gbb_flags.sh 0x01')
     94             stressor = stress.ControlledStressor(stress_hotplug)
     95             logging.info('Reboot iteration %d of %d' % (i + 1, reboots))
     96             if skip_gbb:
     97                 # For devices that do not support gbb we have servo
     98                 # accelerate booting through dev mode.
     99                 host.servo.get_power_state_controller().reset()
    100                 host.servo.power_short_press()
    101                 time.sleep(servo.Servo.BOOT_DELAY)
    102                 host.servo.ctrl_d()
    103                 stressor.start()
    104                 host.wait_up(timeout=120)
    105             else:
    106                 stressor.start()
    107                 self.client.reboot()
    108             logging.info('Reboot complete, shutting down stressor.')
    109             stressor.stop()
    110             connected_now = set_hub_power(check_host_detection=True)
    111             diff_now = set(connected_now).difference(set(off_list))
    112             if diff_list != diff_now:
    113                 raise error.TestFail('The list of connected items does not '
    114                                       'match the master list.\nMaster: %s\n'
    115                                       'Current: %s' %
    116                                       (diff_list, diff_now))
    117             logging.info('Connected devices for iteration %d: %s' %
    118                          (i, diff_now))
    119