1# Lint as: python2, python3 2# Copyright (c) 2013 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# WARNING(crbug.com/743265): This test is currently broken because the ability 7# to run client tests in the background from a server-side test has been 8# deleted. 9 10import logging, time 11 12from autotest_lib.server import autotest, test 13from autotest_lib.client.common_lib import error 14 15_SUSPEND_TIME = 60 16_SUSPEND_TIMEOUT = 30 17 18class power_USBHotplugInSuspend(test.test): 19 20 version = 1 21 22 # Constant to wait in seconds after turning on or off the usb port power. 23 USB_POWEROFF_DELAY_S = 2 24 25 26 def _switch_usbkey_power(self, on): 27 """ 28 Turn on/off the power to the USB key. 29 30 @param on True to turn on, false otherwise. 31 """ 32 if on: 33 self._host.servo.set('image_usbkey_pwr', 'on') 34 else: 35 self._host.servo.set('image_usbkey_pwr', 'off') 36 time.sleep(self.USB_POWEROFF_DELAY_S) 37 38 def _get_usb_devices(self): 39 """ 40 Get the USB devices attached to the client. 41 42 Parses output from lsusb and returns the set of device IDs. 43 """ 44 try: 45 lines = self._host.run('lsusb').stdout.strip().split('\n') 46 except: 47 raise error.TestError('Failed to get list of USB devices.') 48 devices = set(line.split()[5] for line in lines) 49 logging.info('USB Devices: %s' % (",".join(devices))) 50 return devices 51 52 def _suspend_client(self): 53 """ 54 Start the client test power_KernelSuspend to suspend the client and 55 do not wait for it to finish. 56 """ 57 self._host.suspend_bg(suspend_time=_SUSPEND_TIME) 58 59 def _suspend_and_hotplug(self, insert): 60 """ 61 Suspend the client and add/remove the USB key. This assumes that a 62 USB key is plugged into the servo and is facing the DUT. 63 64 @param insert True to test insertion during suspend, False to test 65 removal. 66 """ 67 # Initialize the USB key and get the set of USB devices before 68 # suspending. 69 self._switch_usbkey_power(not insert) 70 before_suspend = self._get_usb_devices() 71 72 # Suspend the client and wait for it to go down before powering on/off 73 # the usb key. 74 self._suspend_client() 75 if not self._host.ping_wait_down(_SUSPEND_TIMEOUT): 76 raise error.TestError('Client failed to suspend.') 77 self._switch_usbkey_power(insert) 78 79 # Wait for the client to come back up (suspend time + some slack time). 80 # TODO(beeps): Combine the two timeouts in wait_up after 81 # crbug.com/221785 is resolved. 82 time.sleep(_SUSPEND_TIME) 83 if not self._host.wait_up(self._host.RESUME_TIMEOUT): 84 raise error.TestError('Client failed to resume.') 85 86 # Get the set of devices plugged in and make sure the change was 87 # detected. 88 after_suspend = self._get_usb_devices() 89 diff = after_suspend ^ before_suspend 90 if not diff: 91 raise error.TestFail('No USB changes detected after resuming.') 92 93 # Finally, make sure hotplug still works after resuming by switching 94 # the USB key's power once more. 95 self._switch_usbkey_power(not insert) 96 after_hotplug = self._get_usb_devices() 97 diff = after_hotplug ^ after_suspend 98 if not diff: 99 raise error.TestFail('No USB changes detected after hotplugging.') 100 101 def cleanup(self): 102 """ 103 Reset the USB key to its initial state. 104 """ 105 self._host.servo.switch_usbkey(self._init_usbkey_direction) 106 self._switch_usbkey_power(self._init_usbkey_power == 'on') 107 super(power_USBHotplugInSuspend, self).cleanup() 108 109 def run_once(self, host): 110 """ 111 Tests adding and removing a USB device while the client is suspended. 112 """ 113 self._host = host 114 self._init_usbkey_power = self._host.servo.get('image_usbkey_pwr') 115 self._init_usbkey_direction = self._host.servo.get_usbkey_state() 116 117 # Make sure the USB key is facing the DUT and is actually present. 118 self._host.servo.switch_usbkey('dut') 119 self._switch_usbkey_power(False) 120 before_insert = self._get_usb_devices() 121 self._switch_usbkey_power(True) 122 after_insert = self._get_usb_devices() 123 diff = after_insert - before_insert 124 logging.info('Inserted USB device(s): %s' % (",".join(diff))) 125 if not diff: 126 raise error.TestError('No new USB devices detected. Is a USB key ' 127 'plugged into the servo?') 128 129 logging.info('Testing insertion during suspend.') 130 self._suspend_and_hotplug(True) 131 logging.info('Testing removal during suspend.') 132 self._suspend_and_hotplug(False) 133