15cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
25cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra# Use of this source code is governed by a BSD-style license that can be
35cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra# found in the LICENSE file.
45cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
55cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatraimport logging, os
65cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
75cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatrafrom autotest_lib.client.common_lib import error, autotemp, site_utils
85cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatrafrom autotest_lib.server import autotest, hosts
95cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatrafrom autotest_lib.server import test, utils
105cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
115cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatrabored_now = """
125cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[  _____             ____  _               _  ]
135cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[ |_   _|__   ___   / ___|| | _____      _| | ]
145cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[  | |/ _ \ / _ \  \___ \| |/ _ \ \ /\ / /| | ]
155cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[  | | (_) | (_) |  ___) | | (_) \ V  V / |_| ]
165cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[  |_|\___/ \___/  |____/|_|\___/ \_/\_/  (_) ]
175cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[                                             ]
185cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[ The device didn't wake up - either the HID device isn't working or  ]
195cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[ the chromebook just didn't wake up: Either way, wake the chromebook ]
205cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[ so we can finish the test, or we'll be sitting here for a while...  ]
215cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra"""
225cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
235cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatrapress_button_banner = """
245cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[     _   _   _             _   _              ]
255cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[    / \ | |_| |_ ___ _ __ | |_(_) ___  _ __   ]
265cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[   / _ \| __| __/ _ \ '_ \| __| |/ _ \| '_ \  ]
275cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[  / ___ \ |_| ||  __/ | | | |_| | (_) | | | | ]
285cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[ /_/   \_\__|\__\___|_| |_|\__|_|\___/|_| |_| ]
295cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[                                              ]
305cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[ Press the power, sleep or other suitable button on your USB HID Device ]
315cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[ NOTE: NOT on the Chromebook itself - on the USB Keyboard/Remote/etc    ]
325cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra[ Then press Return or Enter here so we can proceed with the test        ]
335cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra"""
345cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
355cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
365cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatraclass platform_USBHIDWake(test.test):
375cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra    version = 1
385cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
395cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra    def suspend(self):
405cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        self._client.run("(echo mem > /sys/power/state &)")
415cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
425cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
435cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra    def check_dependencies(self):
445cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        if not utils.system('which openvt', ignore_status=True) == 0:
455cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra            raise error.TestError('openvt missing (see control file)')
465cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        if not utils.system('sudo true', ignore_status=True) == 0:
475cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra            raise error.TestError('Insufficient privileges: cannot sudo')
485cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
495cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
505cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra    def prompt(self, banner=">>>>>>>>>>> Achtung! <<<<<<<<<<<"):
515cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        """prompt the user with the supplied banner,
525cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        then wait for them to press enter
535cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
545cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        @param banner: A [possibly multi-line] banner prompt to display
555cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        """
565cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        temp = autotemp.tempfile(unique_id='vtprompt', text=True)
575cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        os.write(temp.fd, banner)
585cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        pcmd = ("sudo openvt -s -w -- " +
595cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra                "sh -c 'clear && cat %s && read -p \"READY> \" REPLY &&" +
605cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra                " echo $REPLY'") % temp.name
615cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        utils.system(pcmd)
625cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        temp.clean()
635cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
645cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
655cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra    def wait_for_host(self, host=None, timeout=30):
665cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        '''Wait for the DUT to come back up, with a timeout
675cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
685cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        @param host: ip address or hostname of DUT
695cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        @param timeout: maximum time in seconds to wait
705cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
715cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        Returns True if the host comes up in time, False otherwise'''
725cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        return site_utils.ping(host, deadline=timeout) == 0
735cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
745cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
755cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra    def have_hid_device(self):
765cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        """Return True is a USB HID device is present, False otherwise"""
775cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        cmd = 'grep "^03$" /sys/bus/usb/devices/[0-9]*/[0-9]*/bInterfaceClass'
785cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        rval = self._client.run(cmd, ignore_status=True)
795cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        return rval.exit_status == 0
805cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
815cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
825cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra    def run_once(self, client_ip):
835cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        """Check to see if a DUT at the given address wakes from suspend
845cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        on USB HID events
855cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra
865cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        @param client_ip: ip address (string) at which the DUT may be found"""
875cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        self.check_dependencies()
885cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        if not client_ip:
895cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra            raise error.TestError('Must have test client IP address')
905cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        self._client = hosts.create_host(client_ip)
915cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        if not self.have_hid_device():
925cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra            raise error.TestError('No HID devices found, please attach one')
935cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        self.suspend()
945cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        self.prompt(banner=press_button_banner)
955cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra        if not self.wait_for_host(host=client_ip, timeout=10):
965cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra            self.prompt(banner=bored_now)
975cdf4f59eea8a6bb834fc4e39062e72d66caba4eVivek Dasmohapatra            raise error.TestFail('DUT did not wake up on HID event')
98