• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2017 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Check USB device by running linux command on CfM"""
6
7from __future__ import print_function
8
9import logging
10import re
11import time
12import common
13from autotest_lib.client.common_lib.cros.manual import get_usb_devices
14from autotest_lib.client.common_lib.cros import power_cycle_usb_util
15
16CORE_DIR_LINES = 3
17ATRUS = '18d1:8001'
18
19def check_chrome_logfile(dut):
20    """
21    Get the latest chrome log file.
22    @param dut: The handle of the device under test.
23    @returns: the latest chrome log file
24    """
25    output = None
26    logging.info('---Get the latest chrome log file')
27    cmd = 'ls -latr /var/log/chrome/chrome'
28    try:
29        output = dut.run(cmd, ignore_status=True).stdout
30    except Exception as e:
31        logging.exception('Fail to run command %s.', cmd)
32        return None
33    logging.info('---cmd: %s', cmd)
34    logging.info('---output: %s', output.lower().strip())
35    return output
36
37def check_last_reboot(dut):
38    """
39    Get the last line of eventlog.txt
40    @param dut: The handle of the device under test.
41    @returns: the last line in eventlog.txt
42    """
43    output = None
44    cmd = 'tail -1 /var/log/eventlog.txt'
45    logging.info('---Get the latest reboot log')
46    try:
47        output = dut.run(cmd, ignore_status=True).stdout
48    except Exception as e:
49        logging.exception('Fail to run command %s.', cmd)
50        return None
51    logging.info('---cmd: %s', cmd)
52    logging.info('---output: %s', output.lower().strip())
53    return output
54
55def check_is_platform(dut, name):
56    """
57    Check whether CfM is expected platform.
58    @param dut: The handle of the device under test.
59    @param name: The name of platform
60    @returns: True, if CfM's platform is same as expected.
61              False, if not.
62    """
63    cmd = "mosys platform name"
64    output = dut.run(cmd, ignore_status=True).stdout.strip()
65    logging.info('---cmd: %s', cmd)
66    logging.info('---output: %s', output.lower())
67    return output.lower() == name
68
69
70def get_mgmt_ipv4(dut):
71    """
72    Get mgmt ipv4 address
73    @param dut: The handle of the device under test. Should be initialized in
74                 autotest.
75    @return: ipv4 address for mgmt interface.
76    """
77    cmd = 'ifconfig -a | grep eth0 -A 2 | grep netmask'
78    try:
79        output = dut.run(cmd, ignore_status=True).stdout
80    except Exception as e:
81        logging.exception('Fail to run command %s.', cmd)
82        return None
83    ipv4 = re.findall(r"inet\s*([0-9.]+)\s*netmask.*", output)[0]
84    return ipv4
85
86
87def retrieve_usb_devices(dut):
88    """
89    Populate output of usb-devices on CfM.
90    @param dut: handle of CfM under test
91    @returns dict of all usb devices detected on CfM.
92    """
93    usb_devices = (dut.run('usb-devices', ignore_status=True).
94                   stdout.strip().split('\n\n'))
95    usb_data = get_usb_devices.extract_usb_data(
96               '\nUSB-Device\n'+'\nUSB-Device\n'.join(usb_devices))
97    return usb_data
98
99
100def extract_peripherals_for_cfm(usb_data):
101    """
102    Check CfM has camera, speaker and Mimo connected.
103    @param usb_data: dict extracted from output of "usb-devices"
104    """
105    peripheral_map = {}
106    get_devices_funcs = (get_usb_devices.get_speakers,
107            get_usb_devices.get_cameras, get_usb_devices.get_display_mimo,
108            get_usb_devices.get_controller_mimo)
109    for get_devices in get_devices_funcs:
110        device_list = get_devices(usb_data)
111        for pid_vid, device_count in device_list.iteritems():
112            if device_count > 0:
113                peripheral_map[pid_vid] = device_count
114
115    for pid_vid, device_count in peripheral_map.iteritems():
116        logging.info('---device: %s (%s), count: %d',
117                     pid_vid, get_usb_devices.get_device_prod(pid_vid),
118                     device_count)
119
120    return peripheral_map
121
122
123def check_peripherals_for_cfm(peripheral_map):
124    """
125    Check CfM has one and only one camera,
126    one and only one speaker,
127    or one and only one mimo.
128    @param peripheral_map: dict for connected camera, speaker, or mimo.
129    @returns: True if check passes,
130              False if check fails.
131    """
132    peripherals = peripheral_map.keys()
133
134    type_camera = set(peripherals).intersection(get_usb_devices.CAMERA_LIST)
135    type_speaker = set(peripherals).intersection(get_usb_devices.SPEAKER_LIST)
136    type_controller = set(peripherals).intersection(\
137                      get_usb_devices.TOUCH_CONTROLLER_LIST)
138    type_panel = set(peripherals).intersection(\
139                 get_usb_devices.TOUCH_DISPLAY_LIST)
140
141    # check CfM have one, and only one type camera, huddly and mimo
142    if len(type_camera) == 0:
143        logging.info('No camera is found on CfM.')
144        return False
145
146    if not len(type_camera) == 1:
147        logging.info('More than one type of cameras are found on CfM.')
148        return False
149
150    if len(type_speaker) == 0:
151        logging.info('No speaker is found on CfM.')
152        return False
153
154    if not len(type_speaker) == 1:
155        logging.info('More than one type of speakers are found on CfM.')
156        return False
157
158    if len(type_controller) == 0:
159       logging.info('No controller is found on CfM.')
160       return False
161
162
163    if not len(type_controller) == 1:
164        logging.info('More than one type of controller are found on CfM.')
165        return False
166
167    if len(type_panel) == 0:
168        logging.info('No Display is found on CfM.')
169        return False
170
171    if not len(type_panel) == 1:
172        logging.info('More than one type of displays are found on CfM.')
173        return False
174
175    # check CfM have only one camera, huddly and mimo
176    for pid_vid, device_count in peripheral_map.iteritems():
177        if device_count > 1:
178            logging.info('Number of device %s connected to CfM : %d',
179                         get_usb_devices.get_device_prod(pid_vid),
180                         device_count)
181            return False
182
183    return True
184
185
186def check_usb_enumeration(dut, puts):
187    """
188    Check USB enumeration for devices
189    @param dut: the handle of CfM under test
190    @param puts: the list of peripherals under test
191    @returns True, none if test passes
192             False, errMsg if test test fails
193    """
194    usb_data = retrieve_usb_devices(dut)
195    if not usb_data:
196        logging.warning('No usb devices found on DUT')
197        return False, 'No usb device found on DUT.'
198    else:
199        usb_device_list = extract_peripherals_for_cfm(usb_data)
200        logging.info('---usb device = %s', usb_device_list)
201        if not set(puts).issubset(set(usb_device_list.keys())):
202            logging.info('Detect device fails for usb enumeration')
203            logging.info('Expect enumerated devices: %s', puts)
204            logging.info('Actual enumerated devices: %s',
205                         usb_device_list.keys())
206            return False, 'Some usb devices are not found.'
207        return True, None
208
209
210def check_usb_interface_initializion(dut, puts):
211    """
212    Check CfM shows valid interface for all peripherals connected.
213    @param dut: the handle of CfM under test
214    @param puts: the list of peripherals under test
215    @returns True, none if test passes
216             False, errMsg if test test fails
217    """
218    usb_data = retrieve_usb_devices(dut)
219    for put in puts:
220        number, health = get_usb_devices.is_usb_device_ok(usb_data, put)
221        logging.info('---device interface = %d, %s for %s',
222                     number, health,  get_usb_devices.get_device_prod(put))
223        if '0' in health:
224            logging.warning('Device %s has invalid interface', put)
225            return False, 'Device {} has invalid interface.'.format(put)
226    return True, None
227
228
229def clear_core_file(dut):
230    """clear core files"""
231    cmd = "rm -rf /var/spool/crash/*.*"
232    try:
233        dut.run_output(cmd)
234    except Exception as e:
235        logging.exception('Fail to clean core files under '
236                     '/var/spool/crash')
237        logging.exception('Fail to execute %s :', cmd)
238
239
240def check_process_crash(dut, cdlines):
241    """Check whether there is core file."""
242    cmd = 'ls -latr /var/spool/crash'
243    try:
244        core_files_output = dut.run_output(cmd).splitlines()
245    except Exception as e:
246        logging.exception('Can not find file under /var/spool/crash.')
247        logging.exception('Fail to execute %s:', cmd)
248        return True,  CORE_DIR_LINES
249    logging.info('---%s\n---%s', cmd, core_files_output)
250    if len(core_files_output) - cdlines <= 0:
251        logging.info('---length of files: %d', len(core_files_output))
252        return True, len(core_files_output)
253    else:
254        return False, len(core_files_output)
255
256
257def gpio_usb_test(dut, gpio_list, device_list, pause, board):
258    """
259    Run GPIO test to powercycle usb port.
260    @parama dut: handler of CfM,
261    @param gpio_list: the list of gpio ports,
262    @param device_list: the list of usb devices,
263    @param pause: time needs to wait before restoring power to usb port,
264                  in seconds
265    @param board: board name for CfM
266    @returns True
267    """
268    for device in device_list:
269       vid, pid  = device.split(':')
270       logging.info('---going to powercyle device %s:%s', vid, pid)
271       try:
272            power_cycle_usb_util.power_cycle_usb_vidpid(dut, board,
273                                                        vid, pid, pause)
274       except Exception as e:
275           errmsg = 'Fail to power cycle device.'
276           logging.exception('%s.', errmsg)
277           return False, errmsg
278
279    return True, None
280
281
282def reboot_test(dut, pause):
283    """
284    Reboot CfM.
285    @parama dut: handler of CfM,
286    @param pause: time needs to wait after issuing reboot command, in seconds,
287
288    """
289    try:
290        dut.reboot()
291    except Exception as e:
292        logging.exception('Fail to reboot CfM.')
293        return False
294    logging.info('---reboot done')
295    time.sleep(pause)
296    return True
297
298
299
300def find_last_log(dut, speaker):
301    """
302    Get the lastlast_lines line for log files.
303    @param dut: handler of CfM
304    @param speaker: vidpid if speaker.
305    @returns: the list of string of the last line of logs.
306    """
307    last_lines = {
308              'messages':[],
309              'chrome':[],
310              'ui': [],
311              'atrus': []
312                  }
313    logging.debug('Get the last line of log file, speaker %s', speaker)
314    try:
315        cmd = "tail -1 /var/log/messages | awk -v N=1 '{print $N}'"
316        last_lines['messages'] = dut.run_output(cmd).strip().split()[0]
317        cmd = "tail -1 /var/log/chrome/chrome | awk -v N=1 '{print $N}'"
318        last_lines['chrome'] = dut.run_output(cmd).strip().split()[0]
319        cmd = "tail -1 /var/log/ui/ui.LATEST | awk -v N=1 '{print $N}'"
320        last_lines['ui']= dut.run_output(cmd)
321        if speaker == ATRUS and check_is_platform(dut, 'guado'):
322            logging.info('---atrus speaker %s connected to CfM', speaker)
323            cmd = 'tail -1 /var/log/atrus.log | awk -v N=1 "{print $N}"'
324            last_lines['atrus'] = dut.run_output(cmd).strip().split()[0]
325    except Exception as e:
326        logging.exception('Fail to get the last line from log files.')
327    for item, timestamp in last_lines.iteritems():
328        logging.debug('---%s: %s', item, timestamp)
329    return last_lines
330
331
332def collect_log_since_last_check(dut, lastlines, logfile):
333    """Collect log file since last check."""
334    output = None
335    if logfile == "messages":
336        cmd ='awk \'/{}/,0\' /var/log/messages'.format(lastlines[logfile])
337    if logfile == "chrome":
338        cmd ='awk \'/{}/,0\' /var/log/chrome/chrome'.format(lastlines[logfile])
339    if logfile == "ui":
340        cmd ='awk \'/{}/,0\' /var/log/ui/ui.LATEST'.format(lastlines[logfile])
341    if logfile == 'atrus':
342         cmd ='awk \'/{}/,0\' /var/log/atrus.log'.format(lastlines[logfile])
343    logging.info('---cmd = %s', cmd)
344    try:
345        output =  dut.run_output(cmd).split('\n')
346    except Exception as e:
347        logging.exception('Fail to get output from log files.')
348    logging.info('---length of log: %d', len(output))
349    if not output:
350        logging.info('--fail to find match log, check the latest log.')
351
352    if not output:
353        if logfile == "messages":
354            cmd ='cat /var/log/messages'
355        if logfile == "chrome":
356            cmd ='cat /var/log/chrome/chrome'
357        if logfile == "ui":
358            cmd ='cat /var/log/ui/ui.LATEST'
359        if logfile == 'atrus':
360            cmd ='cat /var/log/atrus.log'
361        output =  dut.run_output(cmd).split('\n')
362        logging.info('---length of log: %d', len(output))
363    return output
364
365def check_log(dut, timestamp, error_list, checkitem, logfile):
366    """
367    Check logfile does not contain any element in error_list[checkitem].
368    """
369    error_log_list = []
370    logging.info('---now check log %s in file %s', checkitem, logfile)
371    output = collect_log_since_last_check(dut, timestamp, logfile)
372    for _error in error_list[checkitem]:
373         error_log_list.extend([s for s in output if _error in str(s)])
374    if not error_log_list:
375        return True, None
376    else:
377        tempmsg = '\n'.join(error_log_list)
378        errmsg = 'Error_Found:in_log_file:{}:{}.'.format(logfile, tempmsg)
379        logging.info('---%s', errmsg)
380        return False, errmsg
381