| # Copyright (c) 2013 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. |
| |
| # WARNING(crbug.com/743265): This test is currently broken because the ability |
| # to run client tests in the background from a server-side test has been |
| # deleted. |
| |
| import logging, time |
| |
| from autotest_lib.server import autotest, test |
| from autotest_lib.client.common_lib import error |
| |
| _SUSPEND_TIME = 60 |
| _SUSPEND_TIMEOUT = 30 |
| |
| class power_USBHotplugInSuspend(test.test): |
| version = 1 |
| |
| def _switch_usbkey_power(self, on): |
| """ |
| Turn on/off the power to the USB key. |
| |
| @param on True to turn on, false otherwise. |
| """ |
| if on: |
| self._host.servo.set('prtctl4_pwren', 'on') |
| else: |
| self._host.servo.set('prtctl4_pwren', 'off') |
| time.sleep(self._host.servo.USB_POWEROFF_DELAY) |
| |
| def _get_usb_devices(self): |
| """ |
| Get the USB device attached to the client. |
| |
| Parses output from lsusb and returns the set of device IDs. |
| """ |
| try: |
| lines = self._host.run('lsusb').stdout.strip().split('\n') |
| except: |
| raise error.TestError('Failed to get list of USB devices.') |
| devices = set(line.split()[5] for line in lines) |
| logging.info('USB Devices: %s' % (",".join(devices))) |
| return devices |
| |
| def _suspend_client(self): |
| """ |
| Start the client test power_KernelSuspend to suspend the client and |
| do not wait for it to finish. |
| """ |
| client_at = autotest.Autotest(self._host) |
| # TODO(scottz): Add server side support to sys_power: crosbug.com/38115 |
| client_at.run_test('power_KernelSuspend', background=True, |
| seconds=_SUSPEND_TIME) |
| |
| def _suspend_and_hotplug(self, insert): |
| """ |
| Suspend the client and add/remove the USB key. This assumes that a |
| USB key is plugged into the servo and is facing the DUT. |
| |
| @param insert True to test insertion during suspend, False to test |
| removal. |
| """ |
| # Initialize the USB key and get the set of USB devices before |
| # suspending. |
| self._switch_usbkey_power(not insert) |
| before_suspend = self._get_usb_devices() |
| |
| # Suspend the client and wait for it to go down before powering on/off |
| # the usb key. |
| self._suspend_client() |
| if not self._host.ping_wait_down(_SUSPEND_TIMEOUT): |
| raise error.TestError('Client failed to suspend.') |
| self._switch_usbkey_power(insert) |
| |
| # Wait for the client to come back up (suspend time + some slack time). |
| # TODO(beeps): Combine the two timeouts in wait_up after |
| # crbug.com/221785 is resolved. |
| time.sleep(_SUSPEND_TIME) |
| if not self._host.wait_up(self._host.RESUME_TIMEOUT): |
| raise error.TestError('Client failed to resume.') |
| |
| # Get the set of devices plugged in and make sure the change was |
| # detected. |
| after_suspend = self._get_usb_devices() |
| diff = after_suspend ^ before_suspend |
| if not diff: |
| raise error.TestFail('No USB changes detected after resuming.') |
| |
| # Finally, make sure hotplug still works after resuming by switching |
| # the USB key's power once more. |
| self._switch_usbkey_power(not insert) |
| after_hotplug = self._get_usb_devices() |
| diff = after_hotplug ^ after_suspend |
| if not diff: |
| raise error.TestFail('No USB changes detected after hotplugging.') |
| |
| def cleanup(self): |
| """ |
| Reset the USB key to its initial state. |
| """ |
| self._host.servo.switch_usbkey(self._init_usbkey_direction) |
| self._switch_usbkey_power(self._init_usbkey_power == 'on') |
| super(power_USBHotplugInSuspend, self).cleanup() |
| |
| def run_once(self, host): |
| """ |
| Tests adding and removing a USB device while the client is suspended. |
| """ |
| self._host = host |
| self._init_usbkey_power = self._host.servo.get('prtctl4_pwren') |
| self._init_usbkey_direction = self._host.servo.get_usbkey_direction() |
| |
| # Make sure the USB key is facing the DUT and is actually present. |
| self._host.servo.switch_usbkey('dut') |
| self._switch_usbkey_power(False) |
| before_insert = self._get_usb_devices() |
| self._switch_usbkey_power(True) |
| after_insert = self._get_usb_devices() |
| diff = after_insert - before_insert |
| logging.info('Inserted USB device(s): %s' % (",".join(diff))) |
| if not diff: |
| raise error.TestError('No new USB devices detected. Is a USB key ' |
| 'plugged into the servo?') |
| |
| logging.info('Testing insertion during suspend.') |
| self._suspend_and_hotplug(True) |
| logging.info('Testing removal during suspend.') |
| self._suspend_and_hotplug(False) |