1 #!/usr/bin/env python 2 # 3 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 4 # Use of this source code is governed by a BSD-style license that can be 5 # found in the LICENSE file. 6 7 import logging 8 import re 9 10 from subprocess import Popen, PIPE 11 12 from autotest_lib.client.bin import test 13 from autotest_lib.client.bin import utils 14 from autotest_lib.client.common_lib import error 15 16 # Keys for udev db 17 KEY_NAME = 'NAME' 18 KEY_DEVPATH = 'DEVPATH' 19 KEY_ID_INPUT_TOUCHPAD = 'ID_INPUT_TOUCHPAD' 20 21 # True equivalences 22 TRUE_EQ = ['1', 'on', 'true', 'yes'] 23 24 # Regular expressions for cmt module related log 25 UNLOAD_CMT_RE = r'UnloadModule.*cmt' 26 USE_CMT_STRING = "Using input driver 'cmt' for '%s'" 27 28 # Path to xorg log 29 XORG_LOG_PATH = '/var/log/Xorg.0.log' 30 31 32 class hardware_TrackpadFunction(test.test): 33 '''Test to make sure trackpad functions correctly''' 34 version = 1 35 36 def _udev_from_string(self, device_string): 37 # Sample lines: 38 # P: /devices/LNXSYSTM:00/LNXPWRBN:00 39 # E: UDEV_LOG=3 40 # E: DEVPATH=/devices/LNXSYSTM:00/LNXPWRBN:00 41 properties = {} 42 for line in device_string.split('\n'): 43 _, _, val = line.partition(': ') 44 args = val.partition('=') 45 if args[1] != '': 46 properties[args[0]] = args[2] 47 return properties 48 49 def _udevadm_export_db(self): 50 p = Popen('udevadm info --export-db', shell=True, stdout=PIPE) 51 output = p.communicate()[0] 52 devs = output.split('\n\n') 53 return [self._udev_from_string(dev) for dev in devs] 54 55 def run_once(self): 56 """Test if cmt driver is loaded correctly. 57 """ 58 # TODO(ihf): Delete this test once all boards run freon. 59 if utils.is_freon(): 60 return 61 62 devices = self._udevadm_export_db() 63 named_devices = [dev for dev in devices if KEY_NAME in dev] 64 65 touchpad_devices = [] 66 for named_device in named_devices: 67 dev_path = named_device.get(KEY_DEVPATH) 68 for dev in devices: 69 # Use device path prefix match to examine if a named device is 70 # touchpad or not. 71 # 72 # Example of named device data: 73 # 74 # P: /devices/platform/i8042/serio4/input/input6 75 # E: UDEV_LOG=3 76 # E: DEVPATH=/devices/platform/i8042/serio4/input/input6 77 # E: PRODUCT=11/2/7/1b1 78 # E: NAME="SynPS/2 Synaptics TouchPad" 79 # E: PHYS="isa0060/serio4/input0" 80 # 81 # Example of the data whose DEVPATH prefix matches the DEVPATH 82 # above and ID_INPUT_TOUCHPAD is true. 83 # 84 # P: /devices/platform/i8042/serio4/input/input6/event6 85 # N: input/event6 86 # S: input/by-path/platform-i8042-serio-4-event-mouse 87 # E: UDEV_LOG=3 88 # E: DEVPATH=/devices/platform/i8042/serio4/input/input6/event6 89 # E: MAJOR=13 90 # E: MINOR=70 91 # E: DEVNAME=/dev/input/event6 92 # E: SUBSYSTEM=input 93 # E: ID_INPUT=1 94 # E: ID_INPUT_TOUCHPAD=1 95 if (dev.get(KEY_DEVPATH, '').find(dev_path) == 0 and 96 dev.get(KEY_ID_INPUT_TOUCHPAD, '') in TRUE_EQ): 97 touchpad_devices.append(named_device) 98 if touchpad_devices: 99 loaded = False 100 for touchpad_device in touchpad_devices: 101 name = touchpad_device.get(KEY_NAME).strip('"') 102 with open(XORG_LOG_PATH, 'r') as f: 103 for line in f.readlines(): 104 if USE_CMT_STRING % name in line: 105 logging.info('cmt loaded: %s', line) 106 loaded = True 107 if re.search(UNLOAD_CMT_RE, line, re.I): 108 loaded = False 109 break 110 111 if not loaded: 112 raise error.TestFail('cmt did not load for %s' % name) 113 else: 114 # TODO: when touchpad_devices is empty we should check the board 115 # to see if it's expected. 116 logging.info('no trackpad found') 117