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