| # Copyright (c) 2014 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. |
| import logging |
| import time |
| |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.server import test |
| |
| |
| class platform_ServoPowerStateController(test.test): |
| """Test servo can power on and off DUT in recovery and non-recovery mode.""" |
| version = 1 |
| |
| |
| def initialize(self, host): |
| """Initialize DUT for testing.""" |
| pass |
| |
| |
| def cleanup(self): |
| """Clean up DUT after servo actions.""" |
| if not self.host.ssh_ping(): |
| # Power off, then power on DUT from internal storage. |
| self.controller.power_off() |
| self.host.servo.switch_usbkey('off') |
| self.controller.power_on(self.controller.REC_OFF) |
| |
| |
| def confirm_dut_on(self, rec_on=False): |
| """Confirm DUT is powered on, claim test failure if DUT is off. |
| |
| @param rec_on: True if DUT should boot from external USB stick as in |
| recovery mode. |
| |
| @raise TestFail: If DUT is off or DUT boot from wrong source. |
| """ |
| if not self.host.wait_up(timeout=300): |
| raise error.TestFail('power_state:%s did not turn DUT on.' % |
| ('rec' if rec_on else 'on')) |
| |
| # Check boot source. Raise TestFail if DUT boot from wrong source. |
| boot_from_usb = self.host.is_boot_from_usb() |
| if boot_from_usb != rec_on: |
| boot_source = ('USB' if boot_from_usb else |
| 'non-removable storage') |
| raise error.TestFail('power_state:%s booted from %s.' % |
| ('rec' if rec_on else 'on', boot_source)) |
| |
| |
| def confirm_dut_off(self, error_message): |
| """Confirm DUT is off and does not turn back on after 30 seconds. |
| |
| @param error_message: Error message to raise if DUT stays on. |
| @raise TestFail: If DUT stays on. |
| """ |
| if not self.host.ping_wait_down(timeout=10): |
| raise error.TestFail(error_message) |
| |
| if self.host.ping_wait_up(timeout=30): |
| raise error.TestFail('%s. %s' % (error_message, 'DUT turns back on' |
| 'after it is turned off.')) |
| |
| |
| def test_with_usb_plugged_in(self): |
| """Run test when USB stick is plugged in servo. |
| """ |
| logging.info('Power off DUT') |
| self.controller.power_off() |
| self.confirm_dut_off('power_state:off did not turn DUT off.') |
| |
| # Power DUT on in non-recovery mode with USB stick plugged in. |
| # DUT shall boot from internal storage. |
| logging.info('Power on DUT in non-recovery mode.') |
| self.controller.power_on(self.controller.REC_OFF) |
| self.confirm_dut_on() |
| |
| logging.info('Power off DUT which is up in non-recovery mode.') |
| self.controller.power_off() |
| self.confirm_dut_off('power_state:off failed after boot from internal ' |
| 'storage.') |
| |
| logging.info('Power DUT on in recovery mode, DUT shall boot from USB.') |
| self.host.servo.switch_usbkey('off') |
| self.controller.power_on(self.controller.REC_ON) |
| self.host.servo.switch_usbkey('dut') |
| time.sleep(30) |
| self.confirm_dut_on(rec_on=True) |
| |
| logging.info('Power off DUT which is up in recovery mode.') |
| self.controller.power_off() |
| self.confirm_dut_off('power_state:off failed after boot from external ' |
| 'USB stick.') |
| |
| logging.info('Power on in non-recovery mode.') |
| self.controller.power_on(self.controller.REC_OFF) |
| self.confirm_dut_on(rec_on=False) |
| |
| |
| def test_with_usb_unplugged(self): |
| """Run test when USB stick is not plugged in servo. |
| """ |
| # Power off DUT regardless its current status. |
| logging.info('Power off DUT.') |
| self.controller.power_off() |
| self.confirm_dut_off('power_state:off did not turn DUT off.') |
| |
| # Try to power off the DUT again, make sure the DUT stays off. |
| logging.info('Power off DUT which is already off.') |
| self.controller.power_off() |
| self.confirm_dut_off('power_state:off turned DUT on.') |
| |
| # USB stick should be unplugged before the test. |
| self.host.servo.switch_usbkey('off') |
| |
| # DUT should be off before calling power_on(REC_ON) |
| logging.info('Power on DUT in recovery mode with USB unplugged.') |
| self.controller.power_on(self.controller.REC_ON) |
| self.confirm_dut_off("power_state:rec didn't stay at recovery screen.") |
| |
| logging.info('Power off DUT in recovery mode with USB unplugged.') |
| self.controller.power_off() |
| self.confirm_dut_off('power_state:off failed at recovery screen.') |
| |
| logging.info('Power on in non-recovery mode.') |
| self.controller.power_on(self.controller.REC_OFF) |
| self.confirm_dut_on(rec_on=False) |
| |
| logging.info('Power DUT off and on without delay. DUT should be on ' |
| 'after power_on is completed.') |
| self.controller.power_off() |
| self.controller.power_on(self.controller.REC_OFF) |
| self.confirm_dut_on(rec_on=False) |
| |
| logging.info('Power DUT off and reset. DUT should be on after reset ' |
| 'is completed.') |
| self.controller.power_off() |
| self.controller.reset() |
| self.confirm_dut_on(rec_on=False) |
| |
| logging.info('Reset DUT when it\'s on. DUT should be on after reset ' |
| 'is completed.') |
| boot_id = self.host.get_boot_id() |
| self.controller.reset() |
| self.confirm_dut_on(rec_on=False) |
| new_boot_id = self.host.get_boot_id() |
| if not new_boot_id or boot_id == new_boot_id: |
| raise error.TestFail('power_state:reset failed to reboot DUT.') |
| |
| |
| def run_once(self, host, usb_available=True): |
| """Run the test. |
| |
| @param host: host object of tested DUT. |
| @param usb_plugged_in: True if USB stick is plugged in servo. |
| """ |
| self.host = host |
| self.controller = host.servo.get_power_state_controller() |
| |
| self.test_with_usb_unplugged() |
| if usb_available: |
| self.host.servo.switch_usbkey('dut') |
| self.test_with_usb_plugged_in() |
| self.host.servo.switch_usbkey('off') |