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