blob: 5a2152c62c6470daebb50ff97f81f6f556abfa8f [file] [log] [blame]
# -*- coding: utf-8 -*-
#
# Copyright (c) 2011 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.
# DESCRIPTION :
#
# Factory test for USB ports. The test checks USB ports are functional by
# requiring that an USB device be plugged in and unplugged from the number of
# ports specified.
import gtk
import logging
import os
import pango
import pyudev
import pyudev.glib
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import factory_setup_modules
from cros.factory.test import factory
from cros.factory.test import ui as ful
_UDEV_ACTION_INSERT = 'add'
_UDEV_ACTION_REMOVE = 'remove'
_PROMPT_FMT_STR = ('Plug device into each USB port, {0} to go...\n'
'在每个 USB 端口插入装置, 还有 {0} 个待测试...')
class factory_USB(test.test):
version = 1
def record_path(self, sys_path):
bus_path = os.path.dirname(sys_path)
bus_ver_path = os.path.join(bus_path, 'version')
bus_version = int(float(open(bus_ver_path, 'r').read().strip()))
if bus_version == 2:
self._seen_usb2_paths.add(sys_path)
elif bus_version == 3:
self._seen_usb3_paths.add(sys_path)
else:
logging.warning('usb event for unknown bus version: %r',
bus_version)
return
usb2_count = len(self._seen_usb2_paths)
usb3_count = len(self._seen_usb3_paths)
total_count = usb2_count + usb3_count
finished = True
if self._num_usb_ports:
finished &= total_count >= self._num_usb_ports
if self._num_usb2_ports:
finished &= usb2_count >= self._num_usb2_ports
if self._num_usb3_ports:
finished &= usb3_count >= self._num_usb3_ports
if finished:
if self._started:
gtk.main_quit()
else:
self._succeed = True
else:
txt = _PROMPT_FMT_STR.format(self._num_usb_ports - total_count)
self._prompt.set_text(txt)
def usb_event_cb(self, action, device):
if action not in [_UDEV_ACTION_INSERT, _UDEV_ACTION_REMOVE]:
return
factory.log('USB %s device path %s' % (action, device.sys_path))
if self._expected_paths and device.sys_path not in self._expected_paths:
return
self.record_path(device.sys_path)
def run_once(self,
expected_paths=None,
num_usb_ports=None,
num_usb2_ports=None,
num_usb3_ports=None):
assert ((num_usb_ports and (num_usb_ports > 0)) or
(num_usb2_ports and (num_usb2_ports > 0)) or
(num_usb3_ports and (num_usb3_ports > 0))), (
'USB port count not specified.')
if not num_usb_ports:
num_usb_ports = (num_usb2_ports or 0) + (num_usb3_ports or 0)
self._num_usb_ports = num_usb_ports
self._num_usb2_ports = num_usb2_ports
self._num_usb3_ports = num_usb3_ports
self._seen_usb2_paths = set()
self._seen_usb3_paths = set()
self._expected_paths = expected_paths
self._started = False
self._succeed = False
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='usb', device_type='usb_device')
observer = pyudev.glib.GUDevMonitorObserver(monitor)
observer.connect('device-event',
lambda observer, action, device: \
self.usb_event_cb(action, device))
monitor.start()
label = gtk.Label('')
label.modify_font(pango.FontDescription('courier new condensed 20'))
label.set_alignment(0.5, 0.5)
label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('light green'))
self._prompt = label
self._prompt.set_text(_PROMPT_FMT_STR.format(self._num_usb_ports))
vbox = gtk.VBox()
vbox.pack_start(label, False, False)
test_widget = gtk.EventBox()
test_widget.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('black'))
test_widget.add(vbox)
if self._expected_paths:
for path in self._expected_paths:
if os.path.exists(path):
self.record_path(path)
if not self._succeed:
self._started = True
ful.run_test_widget(self.job, test_widget)
factory.log('%s run_once finished' % self.__class__)