Kalin Stoyanov | 4afee9f | 2014-05-02 12:56:34 -0700 | [diff] [blame] | 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 | |
Kalin Stoyanov | d592acd | 2014-05-06 18:58:55 -0700 | [diff] [blame] | 5 | import logging, re, time |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 6 | from autotest_lib.server import autotest, test |
Kalin Stoyanov | 4afee9f | 2014-05-02 12:56:34 -0700 | [diff] [blame] | 7 | from autotest_lib.client.common_lib import error |
| 8 | |
| 9 | _CHARGING = 'CHARGING' |
| 10 | _DISCHARGING = 'DISCHARGING' |
Kalin Stoyanov | a69b9ae | 2014-10-02 15:34:11 -0700 | [diff] [blame] | 11 | _WAIT_SECS_AFTER_SWITCH = 5 |
Kalin Stoyanov | 62e0e2d | 2015-04-07 12:10:12 -0700 | [diff] [blame] | 12 | _LONG_TIMEOUT = 120 |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 13 | _CLIENT_LOGIN = 'desktopui_SimpleLogin' |
Kalin Stoyanov | 62e0e2d | 2015-04-07 12:10:12 -0700 | [diff] [blame] | 14 | _WAKE_PRESS_IN_SEC = 0.2 |
| 15 | _SUSPEND_TIME = 10 |
Kalin Stoyanov | 4afee9f | 2014-05-02 12:56:34 -0700 | [diff] [blame] | 16 | |
| 17 | class platform_PowerStatusStress(test.test): |
Kalin Stoyanov | 568436be | 2014-11-06 10:29:09 -0800 | [diff] [blame] | 18 | """Uses RPM and servo to test the power_supply_info output. """ |
Kalin Stoyanov | 4afee9f | 2014-05-02 12:56:34 -0700 | [diff] [blame] | 19 | version = 1 |
| 20 | |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 21 | |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 22 | def action_login(self): |
| 23 | """Login i.e. runs running client test |
| 24 | |
| 25 | @exception TestFail failed to login within timeout. |
| 26 | |
| 27 | """ |
| 28 | self.autotest_client.run_test(_CLIENT_LOGIN, |
| 29 | exit_without_logout=True) |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 30 | |
| 31 | |
| 32 | def wait_to_suspend(self, suspend_timeout = _LONG_TIMEOUT): |
| 33 | """Wait for DUT to suspend. |
| 34 | |
| 35 | @param suspend_timeout: Time in seconds to wait to disconnect |
| 36 | |
| 37 | @exception TestFail if fail to suspend/disconnect in time |
Kalin Stoyanov | 62e0e2d | 2015-04-07 12:10:12 -0700 | [diff] [blame] | 38 | |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 39 | """ |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 40 | if not self.host.ping_wait_down(timeout=suspend_timeout): |
| 41 | raise error.TestFail("Unable to suspend in %s sec" % |
| 42 | suspend_timeout) |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 43 | |
| 44 | |
Kalin Stoyanov | 62e0e2d | 2015-04-07 12:10:12 -0700 | [diff] [blame] | 45 | def wait_to_come_up(self, resume_timeout = _LONG_TIMEOUT): |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 46 | """Wait for DUT to resume. |
| 47 | |
| 48 | @param resume_timeout: Time in seconds to wait to come up |
| 49 | |
| 50 | @exception TestFail if fail to come_up in time |
Kalin Stoyanov | 62e0e2d | 2015-04-07 12:10:12 -0700 | [diff] [blame] | 51 | |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 52 | """ |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 53 | if not self.host.wait_up(timeout=resume_timeout): |
| 54 | raise error.TestFail("Unable to resume in %s sec" % |
| 55 | resume_timeout) |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 56 | |
| 57 | |
Kalin Stoyanov | 62e0e2d | 2015-04-07 12:10:12 -0700 | [diff] [blame] | 58 | def do_suspend_resume(self): |
Kalin Stoyanov | a69b9ae | 2014-10-02 15:34:11 -0700 | [diff] [blame] | 59 | """ Suspends the DUT through powerd_dbus_suspend |
Kalin Stoyanov | a69b9ae | 2014-10-02 15:34:11 -0700 | [diff] [blame] | 60 | """ |
Kalin Stoyanov | 62e0e2d | 2015-04-07 12:10:12 -0700 | [diff] [blame] | 61 | #Suspend |
| 62 | logging.debug('Suspending...') |
| 63 | if self.has_lid: |
| 64 | self.host.servo.lid_close() |
| 65 | self.wait_to_suspend() |
| 66 | time.sleep(_SUSPEND_TIME) |
| 67 | else: |
| 68 | self.host.suspend(suspend_time=_SUSPEND_TIME) |
| 69 | |
| 70 | #Resume |
| 71 | logging.debug('Resuming...') |
| 72 | if self.has_lid: |
| 73 | self.host.servo.lid_open() |
| 74 | else: |
| 75 | self.host.servo.power_key(_WAKE_PRESS_IN_SEC) |
| 76 | self.wait_to_come_up() |
| 77 | |
| 78 | |
Kalin Stoyanov | d592acd | 2014-05-06 18:58:55 -0700 | [diff] [blame] | 79 | def cleanup(self): |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 80 | """ Finish as powered on and lid open""" |
Kalin Stoyanov | d592acd | 2014-05-06 18:58:55 -0700 | [diff] [blame] | 81 | self.host.power_on() |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 82 | self.host.servo.lid_open() |
Kalin Stoyanov | a69b9ae | 2014-10-02 15:34:11 -0700 | [diff] [blame] | 83 | |
| 84 | |
Kalin Stoyanov | d592acd | 2014-05-06 18:58:55 -0700 | [diff] [blame] | 85 | def switch_power_and_verify(self, powered_on, expected): |
Kalin Stoyanov | a69b9ae | 2014-10-02 15:34:11 -0700 | [diff] [blame] | 86 | """ Main action on switching the power state, and verifying status |
| 87 | |
| 88 | @param powered_on: a boolean ON if True, OFF else |
| 89 | @param expected: touple of cmd and values to verify |
| 90 | |
| 91 | @exception TestFail if line_power or battery state do not match |
| 92 | """ |
| 93 | bat_state = _CHARGING if powered_on else _DISCHARGING, |
Kalin Stoyanov | 568436be | 2014-11-06 10:29:09 -0800 | [diff] [blame] | 94 | logging.info('Switching status to %s ', bat_state) |
Kalin Stoyanov | d592acd | 2014-05-06 18:58:55 -0700 | [diff] [blame] | 95 | if powered_on: |
| 96 | self.host.power_on() |
| 97 | else: |
| 98 | self.host.power_off() |
| 99 | time.sleep(_WAIT_SECS_AFTER_SWITCH) |
| 100 | |
| 101 | # Get power_supply_info output |
| 102 | psi_output = self.host.run('power_supply_info').stdout.strip() |
| 103 | psi_output = psi_output.replace('\n', '') |
| 104 | |
| 105 | exp_psi_online, exp_psi_enum_type, exp_psi_bat_state = expected |
| 106 | |
| 107 | is_psi_online = re.match(r'.+online:\s+%s.+' % exp_psi_online, |
| 108 | psi_output) is not None |
| 109 | is_psi_enum_type = re.match(r'.+enum type:\s+%s.+' % exp_psi_enum_type, |
| 110 | psi_output) is not None |
| 111 | is_psi_bat_state = re.match(r'.+state:\s+%s.+' % exp_psi_bat_state, |
| 112 | psi_output) is not None |
| 113 | |
| 114 | if not all([is_psi_online, is_psi_enum_type, is_psi_bat_state]): |
Kalin Stoyanov | a69b9ae | 2014-10-02 15:34:11 -0700 | [diff] [blame] | 115 | raise error.TestFail('Bad %s state!' % bat_state) |
Kalin Stoyanov | d592acd | 2014-05-06 18:58:55 -0700 | [diff] [blame] | 116 | |
| 117 | |
Kalin Stoyanov | 62e0e2d | 2015-04-07 12:10:12 -0700 | [diff] [blame] | 118 | def run_once(self, host, loop_count): |
Kalin Stoyanov | d592acd | 2014-05-06 18:58:55 -0700 | [diff] [blame] | 119 | self.host = host |
Rohit Makasana | 8a4923c | 2015-08-13 17:04:26 -0700 | [diff] [blame^] | 120 | dut_type = host.get_board_type() |
| 121 | if dut_type is not 'CHROMEBOOK': |
| 122 | raise error.TestError( |
| 123 | 'This test is not supported on %s' % dut_type) |
Kalin Stoyanov | f64e2c9 | 2014-10-23 16:13:22 -0700 | [diff] [blame] | 124 | self.autotest_client = autotest.Autotest(self.host) |
Kalin Stoyanov | d592acd | 2014-05-06 18:58:55 -0700 | [diff] [blame] | 125 | |
| 126 | # Start as powered on |
| 127 | if self.host.has_power(): |
| 128 | self.host.power_on() |
Kalin Stoyanov | 4afee9f | 2014-05-02 12:56:34 -0700 | [diff] [blame] | 129 | else: |
| 130 | raise error.TestFail('No RPM is setup to device') |
Kalin Stoyanov | 62e0e2d | 2015-04-07 12:10:12 -0700 | [diff] [blame] | 131 | |
| 132 | # Check if DUT has lid. |
| 133 | self.has_lid = True |
| 134 | if self.host.servo.get('lid_open') == 'not_applicable': |
| 135 | self.has_lid = False |
| 136 | else: |
| 137 | # Check if lid_open control is good. |
| 138 | self.host.servo.lid_open() |
| 139 | if self.host.servo.get('lid_open') != 'yes': |
| 140 | raise error.TestError('BAD lid_open control. Reset servo!') |
| 141 | |
Kalin Stoyanov | 568436be | 2014-11-06 10:29:09 -0800 | [diff] [blame] | 142 | # Login to device |
| 143 | self.action_login() |
Kalin Stoyanov | 4afee9f | 2014-05-02 12:56:34 -0700 | [diff] [blame] | 144 | |
| 145 | pdu_connected = True |
Kalin Stoyanov | d592acd | 2014-05-06 18:58:55 -0700 | [diff] [blame] | 146 | for i in xrange(loop_count): |
Kalin Stoyanov | 568436be | 2014-11-06 10:29:09 -0800 | [diff] [blame] | 147 | logging.info('--- Iteration %d', (i + 1)) |
Kalin Stoyanov | 4afee9f | 2014-05-02 12:56:34 -0700 | [diff] [blame] | 148 | |
Kalin Stoyanov | 6b0c673 | 2014-05-13 17:59:15 -0700 | [diff] [blame] | 149 | # Suspend/resume |
Kalin Stoyanov | 62e0e2d | 2015-04-07 12:10:12 -0700 | [diff] [blame] | 150 | self.do_suspend_resume() |
| 151 | |
| 152 | # Discharging state |
| 153 | expected = ('no', 'Disconnected', 'Discharging') |
| 154 | self.switch_power_and_verify(False, expected) |
| 155 | |
| 156 | # Suspend/resume |
| 157 | self.do_suspend_resume() |
Kalin Stoyanov | 6b0c673 | 2014-05-13 17:59:15 -0700 | [diff] [blame] | 158 | |
Kalin Stoyanov | a69b9ae | 2014-10-02 15:34:11 -0700 | [diff] [blame] | 159 | # Charging state - it could be any of the three below |
| 160 | expected = ('yes', 'AC', '(Charging|Fully charged|Discharging)') |
Kalin Stoyanov | d592acd | 2014-05-06 18:58:55 -0700 | [diff] [blame] | 161 | self.switch_power_and_verify(True, expected) |