1c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker# Use of this source code is governed by a BSD-style license that can be 3c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker# found in the LICENSE file. 4c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 5c2369d85a68be588aa5e03ab63359671915c6331Andrew Brestickerimport logging, time 6c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 7c2369d85a68be588aa5e03ab63359671915c6331Andrew Brestickerfrom autotest_lib.server import autotest, test 8c2369d85a68be588aa5e03ab63359671915c6331Andrew Brestickerfrom autotest_lib.client.common_lib import error 9c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 10c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker_SUSPEND_TIME = 60 11c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker_SUSPEND_TIMEOUT = 30 12c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 13c2369d85a68be588aa5e03ab63359671915c6331Andrew Brestickerclass power_USBHotplugInSuspend(test.test): 14c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker version = 1 15c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 16c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker def _switch_usbkey_power(self, on): 17c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 18c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker Turn on/off the power to the USB key. 19c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 20c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker @param on True to turn on, false otherwise. 21c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 22c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker if on: 23c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._host.servo.set('prtctl4_pwren', 'on') 24c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker else: 25c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._host.servo.set('prtctl4_pwren', 'off') 26c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker time.sleep(self._host.servo.USB_POWEROFF_DELAY) 27c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 28c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker def _get_usb_devices(self): 29c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 30c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker Get the USB device attached to the client. 31c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 32c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker Parses output from lsusb and returns the set of device IDs. 33c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 34c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker try: 35c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker lines = self._host.run('lsusb').stdout.strip().split('\n') 36c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker except: 37c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker raise error.TestError('Failed to get list of USB devices.') 38c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker devices = set(line.split()[5] for line in lines) 39c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker logging.info('USB Devices: %s' % (",".join(devices))) 40c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker return devices 41c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 42c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker def _suspend_client(self): 43c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 44c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker Start the client test power_KernelSuspend to suspend the client and 45c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker do not wait for it to finish. 46c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 47c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker client_at = autotest.Autotest(self._host) 48c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker # TODO(scottz): Add server side support to sys_power: crosbug.com/38115 49c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker client_at.run_test('power_KernelSuspend', background=True, 50c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker seconds=_SUSPEND_TIME) 51c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 52c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker def _suspend_and_hotplug(self, insert): 53c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 54c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker Suspend the client and add/remove the USB key. This assumes that a 55c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker USB key is plugged into the servo and is facing the DUT. 56c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 57c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker @param insert True to test insertion during suspend, False to test 58c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker removal. 59c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 60c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker # Initialize the USB key and get the set of USB devices before 61c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker # suspending. 62c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._switch_usbkey_power(not insert) 63c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker before_suspend = self._get_usb_devices() 64c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 65c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker # Suspend the client and wait for it to go down before powering on/off 66c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker # the usb key. 67c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._suspend_client() 68c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker if not self._host.ping_wait_down(_SUSPEND_TIMEOUT): 69c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker raise error.TestError('Client failed to suspend.') 70c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._switch_usbkey_power(insert) 71c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 72c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker # Wait for the client to come back up (suspend time + some slack time). 7333dbf14308816fb87d421562c8dce0c73c9208e3Andrew Bresticker # TODO(beeps): Combine the two timeouts in wait_up after 7433dbf14308816fb87d421562c8dce0c73c9208e3Andrew Bresticker # crbug.com/221785 is resolved. 7533dbf14308816fb87d421562c8dce0c73c9208e3Andrew Bresticker time.sleep(_SUSPEND_TIME) 7633dbf14308816fb87d421562c8dce0c73c9208e3Andrew Bresticker if not self._host.wait_up(self._host.RESUME_TIMEOUT): 77c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker raise error.TestError('Client failed to resume.') 78c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 79c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker # Get the set of devices plugged in and make sure the change was 80c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker # detected. 81c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker after_suspend = self._get_usb_devices() 82c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker diff = after_suspend ^ before_suspend 83c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker if not diff: 84c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker raise error.TestFail('No USB changes detected after resuming.') 85c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 86c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker # Finally, make sure hotplug still works after resuming by switching 87c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker # the USB key's power once more. 88c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._switch_usbkey_power(not insert) 89c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker after_hotplug = self._get_usb_devices() 90c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker diff = after_hotplug ^ after_suspend 91c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker if not diff: 92c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker raise error.TestFail('No USB changes detected after hotplugging.') 93c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 94c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker def cleanup(self): 95c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 96c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker Reset the USB key to its initial state. 97c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 98c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._host.servo.switch_usbkey(self._init_usbkey_direction) 99c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._switch_usbkey_power(self._init_usbkey_power == 'on') 100c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker super(power_USBHotplugInSuspend, self).cleanup() 101c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 102c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker def run_once(self, host): 103c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 104c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker Tests adding and removing a USB device while the client is suspended. 105c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker """ 106c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._host = host 107c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._init_usbkey_power = self._host.servo.get('prtctl4_pwren') 108c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._init_usbkey_direction = self._host.servo.get_usbkey_direction() 109c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 110c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker # Make sure the USB key is facing the DUT and is actually present. 111c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._host.servo.switch_usbkey('dut') 112c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._switch_usbkey_power(False) 113c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker before_insert = self._get_usb_devices() 114c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._switch_usbkey_power(True) 115c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker after_insert = self._get_usb_devices() 116c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker diff = after_insert - before_insert 117c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker logging.info('Inserted USB device(s): %s' % (",".join(diff))) 118c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker if not diff: 119c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker raise error.TestError('No new USB devices detected. Is a USB key ' 120c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 'plugged into the servo?') 121c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker 122c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker logging.info('Testing insertion during suspend.') 123c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._suspend_and_hotplug(True) 124c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker logging.info('Testing removal during suspend.') 125c2369d85a68be588aa5e03ab63359671915c6331Andrew Bresticker self._suspend_and_hotplug(False) 126