#!/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.bin import utils
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.
"""
# TODO(ihf): Delete this test once all boards run freon.
if utils.is_freon():
return
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')