• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5import logging, re, time
6
7from autotest_lib.server import test
8from autotest_lib.server.cros import stress
9from autotest_lib.server.cros.servo import servo
10from autotest_lib.client.common_lib import error
11
12_WAIT_DELAY = 5
13
14class 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