10ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
20ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que# Use of this source code is governed by a BSD-style license that can be
30ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que# found in the LICENSE file.
40ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
522802965a9ef49af30445b242823d83302423f4aTodd Brochimport logging, re, commands
6bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Lifrom autotest_lib.client.bin import test, utils
7bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Lifrom autotest_lib.client.common_lib import error
8bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Lifrom autotest_lib.client.cros import power_status
922802965a9ef49af30445b242823d83302423f4aTodd Brochfrom autotest_lib.client.cros import power_utils
100ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
110ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Queclass power_ARMSettings(test.test):
120ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que    version = 1
130ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
1422802965a9ef49af30445b242823d83302423f4aTodd Broch
1522802965a9ef49af30445b242823d83302423f4aTodd Broch    def initialize(self):
1622802965a9ef49af30445b242823d83302423f4aTodd Broch        self._usbpower = power_utils.USBPower()
1722802965a9ef49af30445b242823d83302423f4aTodd Broch
1822802965a9ef49af30445b242823d83302423f4aTodd Broch
190ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que    def run_once(self):
200ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        if not self._check_cpu_type():
210ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            raise error.TestNAError('Unsupported CPU')
220ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
23bee23c2b0ca824c12c39e7a5a4cd4d2a313918b7Eric Li        status = power_status.get_status()
247257208c2acaa5f4e7d37808ddadc60835f91a12Shawn Nematbakhsh        if status.on_ac():
250ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            logging.info('AC Power is online')
260ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            self._on_ac = True
270ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        else:
280ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            logging.info('AC Power is offline')
290ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            self._on_ac = False
300ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
310ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        failures = ''
320ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
330ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        fail_count = self._verify_wifi_power_settings()
340ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        if fail_count:
350ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            failures += 'wifi_failures(%d) ' % fail_count
360ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
370ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        fail_count = self._verify_usb_power_settings()
380ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        if fail_count:
390ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            failures += 'usb_failures(%d) ' % fail_count
400ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
41666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que        fail_count = self._verify_filesystem_power_settings()
42666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que        if fail_count:
43666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que            failures += 'filesystem_failures(%d) ' % fail_count
44666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que
45666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que
460ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        if failures:
470ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            raise error.TestFail(failures)
480ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
490ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
500ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que    def _check_cpu_type(self):
510ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        cpuinfo = utils.read_file('/proc/cpuinfo')
520ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
530ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        # Look for ARM
540ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        match = re.search(r'ARMv[4-7]', cpuinfo)
550ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        if match:
560ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            return True
570ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
580ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        logging.info(cpuinfo)
590ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        return False
600ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
610ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
620ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que    def _verify_wifi_power_settings(self):
630ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        if self._on_ac:
640ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            expected_state = 'off'
650ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        else:
660ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            expected_state = 'on'
670ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
680ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        iwconfig_out = utils.system_output('iwconfig', retain_output=True)
690ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        match = re.search(r'Power Management:(.*)', iwconfig_out)
700ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        if match and match.group(1) == expected_state:
710ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que            return 0
720ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
730ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        logging.info(iwconfig_out)
740ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        return 1
750ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
760ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que
770ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que    def _verify_usb_power_settings(self):
780ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        errors = 0
7922802965a9ef49af30445b242823d83302423f4aTodd Broch        self._usbpower.query_devices()
8022802965a9ef49af30445b242823d83302423f4aTodd Broch        for dev in self._usbpower.devices:
816116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch            # whitelist MUST autosuspend
826116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch            autosuspend = dev.autosuspend()
836116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch            logging.debug("USB %s:%s whitelisted:%s autosuspend:%s",
846116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch                          dev.vid, dev.pid, dev.whitelisted, autosuspend)
856116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch            if dev.whitelisted and not autosuspend:
866116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch                logging.error("Whitelisted USB %s:%s "
876116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch                              "has autosuspend disabled", dev.vid, dev.pid)
880ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que                errors += 1
896116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch            elif not dev.whitelisted:
906116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch                # TODO(crbug.com/242228): Deprecate warnings once we can
916116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch                # definitively identify preferred USB autosuspend settings
926116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch                logging.warning("Non-Whitelisted USB %s:%s present.  "
936116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch                                "Should it be whitelisted?", dev.vid, dev.pid)
946116b22b874c26508017cab9ee4e3b49f6d0be78Todd Broch
950ee81cebe1c4dce845b0430893c9fdba52ad4ec7Simon Que        return errors
96666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que
97666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que
98666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que    def _verify_filesystem_power_settings(self):
99666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que        mount_output = commands.getoutput('mount | fgrep commit=').split('\n')
100666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que        if len(mount_output) == 0:
101666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que            logging.debug('No file system entries with commit intervals found.')
102666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que            return 1
103666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que
104666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que        errors = 0
105666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que        # Parse for 'commit' param
106666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que        for line in mount_output:
107666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que            try:
108666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que                commit = int(re.search(r'(commit=)([0-9]*)', line).group(2))
109666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que            except:
110666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que                logging.debug('Error reading commit value from \'%s\'', line)
111666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que                errors += 1
112666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que                continue
113666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que
1144d5f27f1e6c15a523fa1f6d7a4c6f162f0381fdcSimon Que
115666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que            # Check for the correct commit interval.
1164d5f27f1e6c15a523fa1f6d7a4c6f162f0381fdcSimon Que            if commit != 600:
1174d5f27f1e6c15a523fa1f6d7a4c6f162f0381fdcSimon Que                logging.debug('File System: Incorrect commit interval %d', \
118666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que                              commit)
119666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que                errors += 1
120666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que
121666fb9a63cab2f23d9afce3a0bebe606fe743b9aSimon Que        return errors
122