| #!/usr/bin/env python |
| # |
| # Copyright (c) 2012 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 re |
| |
| from subprocess import Popen, PIPE |
| |
| from autotest_lib.client.bin import test |
| from autotest_lib.client.common_lib import error |
| |
| # Keys for udev db |
| KEY_NAME = 'NAME' |
| KEY_DEVPATH = 'DEVPATH' |
| KEY_ID_INPUT_TOUCHPAD = 'ID_INPUT_TOUCHPAD' |
| |
| # True equivalences |
| TRUE_EQ = ['1', 'on', 'true', 'yes'] |
| |
| # Regular expressions for cmt module related log |
| UNLOAD_CMT_RE = r'UnloadModule.*cmt' |
| USE_CMT_STRING = "Using input driver 'cmt' for '%s'" |
| |
| # Path to xorg log |
| XORG_LOG_PATH = '/var/log/Xorg.0.log' |
| |
| |
| class hardware_TrackpadFunction(test.test): |
| '''Test to make sure trackpad functions correctly''' |
| version = 1 |
| |
| def _udev_from_string(self, device_string): |
| # Sample lines: |
| # P: /devices/LNXSYSTM:00/LNXPWRBN:00 |
| # E: UDEV_LOG=3 |
| # E: DEVPATH=/devices/LNXSYSTM:00/LNXPWRBN:00 |
| properties = {} |
| for line in device_string.split('\n'): |
| _, _, val = line.partition(': ') |
| args = val.partition('=') |
| if args[1] != '': |
| properties[args[0]] = args[2] |
| return properties |
| |
| def _udevadm_export_db(self): |
| p = Popen('udevadm info --export-db', shell=True, stdout=PIPE) |
| output = p.communicate()[0] |
| devs = output.split('\n\n') |
| return [self._udev_from_string(dev) for dev in devs] |
| |
| def run_once(self): |
| """Test if cmt driver is loaded correctly. |
| """ |
| devices = self._udevadm_export_db() |
| named_devices = [dev for dev in devices if KEY_NAME in dev] |
| |
| touchpad_devices = [] |
| for named_device in named_devices: |
| dev_path = named_device.get(KEY_DEVPATH) |
| for dev in devices: |
| # Use device path prefix match to examine if a named device is |
| # touchpad or not. |
| # |
| # Example of named device data: |
| # |
| # P: /devices/platform/i8042/serio4/input/input6 |
| # E: UDEV_LOG=3 |
| # E: DEVPATH=/devices/platform/i8042/serio4/input/input6 |
| # E: PRODUCT=11/2/7/1b1 |
| # E: NAME="SynPS/2 Synaptics TouchPad" |
| # E: PHYS="isa0060/serio4/input0" |
| # |
| # Example of the data whose DEVPATH prefix matches the DEVPATH |
| # above and ID_INPUT_TOUCHPAD is true. |
| # |
| # P: /devices/platform/i8042/serio4/input/input6/event6 |
| # N: input/event6 |
| # S: input/by-path/platform-i8042-serio-4-event-mouse |
| # E: UDEV_LOG=3 |
| # E: DEVPATH=/devices/platform/i8042/serio4/input/input6/event6 |
| # E: MAJOR=13 |
| # E: MINOR=70 |
| # E: DEVNAME=/dev/input/event6 |
| # E: SUBSYSTEM=input |
| # E: ID_INPUT=1 |
| # E: ID_INPUT_TOUCHPAD=1 |
| if (dev.get(KEY_DEVPATH, '').find(dev_path) == 0 and |
| dev.get(KEY_ID_INPUT_TOUCHPAD, '') in TRUE_EQ): |
| touchpad_devices.append(named_device) |
| if touchpad_devices: |
| loaded = False |
| for touchpad_device in touchpad_devices: |
| name = touchpad_device.get(KEY_NAME).strip('"') |
| with open(XORG_LOG_PATH, 'r') as f: |
| for line in f.readlines(): |
| if USE_CMT_STRING % name in line: |
| logging.info('cmt loaded: %s', line) |
| loaded = True |
| if re.search(UNLOAD_CMT_RE, line, re.I): |
| loaded = False |
| break |
| |
| if not loaded: |
| raise error.TestFail('cmt did not load for %s' % name) |
| else: |
| # TODO: when touchpad_devices is empty we should check the board |
| # to see if it's expected. |
| logging.info('no trackpad found') |