1 # Copyright (c) 2014 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 import logging 5 import time 6 7 from autotest_lib.client.common_lib import error 8 from autotest_lib.server import test 9 10 11 class platform_ServoPowerStateController(test.test): 12 """Test servo can power on and off DUT in recovery and non-recovery mode.""" 13 version = 1 14 15 16 def initialize(self, host): 17 """Initialize DUT for testing.""" 18 pass 19 20 21 def cleanup(self): 22 """Clean up DUT after servo actions.""" 23 if not self.host.ssh_ping(): 24 # Power off, then power on DUT from internal storage. 25 self.controller.power_off() 26 self.host.servo.switch_usbkey('off') 27 self.controller.power_on(self.controller.REC_OFF) 28 29 30 def assert_dut_on(self, rec_on=False): 31 """Confirm DUT is powered on, claim test failure if DUT is off. 32 33 @param rec_on: True if DUT should boot from external USB stick as in 34 recovery mode. 35 36 @raise TestFail: If DUT is off or DUT boot from wrong source. 37 """ 38 if not self.host.wait_up(timeout=300): 39 raise error.TestFail('power_state:%s did not turn DUT on.' % 40 ('rec' if rec_on else 'on')) 41 42 # Check boot source. Raise TestFail if DUT boot from wrong source. 43 boot_from_usb = self.host.is_boot_from_usb() 44 if boot_from_usb != rec_on: 45 boot_source = ('USB' if boot_from_usb else 46 'non-removable storage') 47 raise error.TestFail('power_state:%s booted from %s.' % 48 ('rec' if rec_on else 'on', boot_source)) 49 50 51 def assert_dut_off(self, error_message): 52 """Confirm DUT is off and does not turn back on after 30 seconds. 53 54 @param error_message: Error message to raise if DUT stays on. 55 @raise TestFail: If DUT stays on. 56 """ 57 if not self.host.ping_wait_down(timeout=10): 58 raise error.TestFail(error_message) 59 60 if self.host.ping_wait_up(timeout=30): 61 raise error.TestFail('%s. %s' % (error_message, 'DUT turns back on' 62 ' after it is turned off.')) 63 64 65 def test_with_usb_plugged_in(self): 66 """Run test when USB stick is plugged in to servo.""" 67 logging.info('Power off DUT') 68 self.controller.power_off() 69 self.assert_dut_off('power_state:off did not turn DUT off.') 70 71 logging.info('Power DUT on in recovery mode, DUT shall boot from USB.') 72 self.host.servo.switch_usbkey('off') 73 self.controller.power_on(self.controller.REC_ON) 74 self.assert_dut_off('power_state:rec didn\'t stay at recovery screen.') 75 76 self.host.servo.switch_usbkey('dut') 77 time.sleep(30) 78 self.assert_dut_on(rec_on=True) 79 80 logging.info('Power off DUT which is up in recovery mode.') 81 self.controller.power_off() 82 self.assert_dut_off('power_state:off failed after boot from external ' 83 'USB stick.') 84 85 logging.info('Power DUT off in recovery mode without booting.') 86 self.host.servo.switch_usbkey('off') 87 self.controller.power_on(self.controller.REC_ON) 88 self.controller.power_off() 89 self.assert_dut_off('power_state:off failed at recovery screen ') 90 91 # Power DUT on in non-recovery mode with USB stick plugged in. 92 # DUT shall boot from internal storage. 93 logging.info('Power on DUT in non-recovery mode.') 94 self.host.servo.switch_usbkey('dut') 95 self.controller.power_on(self.controller.REC_OFF) 96 self.assert_dut_on() 97 self.host.servo.switch_usbkey('off') 98 99 100 def test_with_usb_unplugged(self): 101 """Run test when USB stick is not plugged in servo.""" 102 # Power off DUT regardless its current status. 103 logging.info('Power off DUT.') 104 self.controller.power_off() 105 self.assert_dut_off('power_state:off did not turn DUT off.') 106 107 # Try to power off the DUT again, make sure the DUT stays off. 108 logging.info('Power off DUT which is already off.') 109 self.controller.power_off() 110 self.assert_dut_off('power_state:off turned DUT on.') 111 112 # USB stick should be unplugged before the test. 113 self.host.servo.switch_usbkey('off') 114 115 logging.info('Power on in non-recovery mode.') 116 self.controller.power_on(self.controller.REC_OFF) 117 self.assert_dut_on(rec_on=False) 118 119 logging.info('Power DUT off and on without delay. DUT should be ' 120 'on after power_on is completed.') 121 self.controller.power_off() 122 self.controller.power_on(self.controller.REC_OFF) 123 self.assert_dut_on(rec_on=False) 124 125 logging.info('Power off DUT which is up in non-recovery mode.') 126 self.controller.power_off() 127 self.assert_dut_off('power_state:off failed after boot from ' 128 'internal storage.') 129 130 logging.info('Power DUT off and reset. DUT should be on after ' 131 'reset is completed.') 132 self.controller.reset() 133 self.assert_dut_on(rec_on=False) 134 135 logging.info('Reset DUT when it\'s on. DUT should be on after ' 136 'reset is completed.') 137 boot_id = self.host.get_boot_id() 138 self.controller.reset() 139 self.assert_dut_on(rec_on=False) 140 new_boot_id = self.host.get_boot_id() 141 if not new_boot_id or boot_id == new_boot_id: 142 raise error.TestFail('power_state:reset failed to reboot DUT.') 143 144 145 def run_once(self, host, usb_available=True): 146 """Run the test. 147 148 @param host: host object of tested DUT. 149 @param usb_plugged_in: True if USB stick is plugged in servo. 150 """ 151 self.host = host 152 self.controller = host.servo.get_power_state_controller() 153 154 self.test_with_usb_unplugged() 155 if usb_available: 156 self.test_with_usb_plugged_in() 157