# Copyright (c) 2012 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, re, time from autotest_lib.server import test from autotest_lib.server.cros import stress from autotest_lib.server.cros.servo import servo from autotest_lib.client.common_lib import error _WAIT_DELAY = 5 class platform_ExternalUSBBootStress(test.test): """Uses servo to repeatedly connect/remove USB devices during boot.""" version = 1 def run_once(self, host, reboots): reboots = int(reboots) self.client = host # The servo hubs come up as diffs in connected components. These # should be ignored for this test. It is a list so when servo next # is available it may have a differnet hub which can be appended. servo_hardware_list = ['Standard Microsystems Corp.'] def strip_lsusb_output(lsusb_output): items = lsusb_output.split('\n') named_list = [] unnamed_device_count = 0 for item in items: columns = item.split(' ') if len(columns) == 6 or len(' '.join(columns[6:]).strip()) == 0: logging.info('Unnamed device located, adding generic name.') name = 'Unnamed device %d' % unnamed_device_count unnamed_device_count += 1 else: name = ' '.join(columns[6:]).strip() if name not in servo_hardware_list: named_list.append(name) return named_list def set_hub_power(on=True, check_host_detection=False): reset = 'off' if not on: reset = 'on' host.servo.set('dut_hub1_rst1', reset) if check_host_detection: time.sleep(_WAIT_DELAY) return strip_lsusb_output(host.run('lsusb').stdout.strip()) def stress_hotplug(): # Devices need some time to come up and to be recognized. However # this is a stress test so we want to move reasonably fast. time.sleep(2) removed = set_hub_power(False) time.sleep(1) connected = set_hub_power() host.servo.switch_usbkey('dut') host.servo.set('usb_mux_sel3', 'dut_sees_usbkey') # There are some mice that need the data and power connection to both # be removed, otherwise they won't come back up. This means that the # external devices should only use the usb connections labeled: # USB_KEY and DUT_HUB1_USB. connected = set_hub_power(check_host_detection=True) off_list = set_hub_power(on=False, check_host_detection=True) diff_list = set(connected).difference(set(off_list)) if len(diff_list) == 0: raise error.TestError('No connected devices were detected. Make ' 'sure the devices are connected to USB_KEY ' 'and DUT_HUB1_USB on the servo board.') logging.info('Connected devices list: %s' % diff_list) set_hub_power(True) lsb_release = host.run('cat /etc/lsb-release').stdout.split('\n') unsupported_gbb_boards = ['x86-mario', 'x86-alex', 'x86-zgb'] skip_gbb = False for line in lsb_release: m = re.match(r'^CHROMEOS_RELEASE_BOARD=(.+)$', line) if m and m.group(1) in unsupported_gbb_boards: skip_gbb = True break logging.info('Rebooting the device %d time(s)' % reboots) for i in xrange(reboots): # We want fast boot past the dev screen if not skip_gbb: host.run('/usr/share/vboot/bin/set_gbb_flags.sh 0x01') stressor = stress.ControlledStressor(stress_hotplug) logging.info('Reboot iteration %d of %d' % (i + 1, reboots)) if skip_gbb: # For devices that do not support gbb we have servo # accelerate booting through dev mode. host.servo.get_power_state_controller().reset() host.servo.power_short_press() time.sleep(servo.Servo.BOOT_DELAY) host.servo.ctrl_d() stressor.start() host.wait_up(timeout=120) else: stressor.start() self.client.reboot() logging.info('Reboot complete, shutting down stressor.') stressor.stop() connected_now = set_hub_power(check_host_detection=True) diff_now = set(connected_now).difference(set(off_list)) if diff_list != diff_now: raise error.TestFail('The list of connected items does not ' 'match the master list.\nMaster: %s\n' 'Current: %s' % (diff_list, diff_now)) logging.info('Connected devices for iteration %d: %s' % (i, diff_now))