OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2013 The Chromium Authors. All rights reserved. | 3 # Copyright 2013 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """A class to keep track of devices across builds and report state.""" | 7 """A class to keep track of devices across builds and report state.""" |
8 import logging | 8 import logging |
9 import optparse | 9 import optparse |
10 import os | 10 import os |
11 import smtplib | 11 import smtplib |
12 import subprocess | |
12 import sys | 13 import sys |
13 import re | 14 import re |
14 import urllib | 15 import urllib |
15 | 16 |
16 import bb_annotations | 17 import bb_annotations |
18 import bb_utils | |
17 | 19 |
18 sys.path.append(os.path.join(os.path.dirname(__file__), | 20 sys.path.append(os.path.join(os.path.dirname(__file__), |
19 os.pardir, os.pardir, 'util', 'lib', | 21 os.pardir, os.pardir, 'util', 'lib', |
20 'common')) | 22 'common')) |
21 import perf_tests_results_helper # pylint: disable=F0401 | 23 import perf_tests_results_helper # pylint: disable=F0401 |
22 | 24 |
23 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) | 25 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) |
24 from pylib import android_commands | 26 from pylib import android_commands |
25 from pylib import constants | 27 from pylib import constants |
26 from pylib.cmd_helper import GetCmdOutput | 28 from pylib.cmd_helper import GetCmdOutput |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
196 msg_body = '\r\n'.join(['From: %s' % from_address, 'To: %s' % to_address, | 198 msg_body = '\r\n'.join(['From: %s' % from_address, 'To: %s' % to_address, |
197 'Subject: %s' % subject, '', msg]) | 199 'Subject: %s' % subject, '', msg]) |
198 try: | 200 try: |
199 server = smtplib.SMTP('localhost') | 201 server = smtplib.SMTP('localhost') |
200 server.sendmail(from_address, [to_address], msg_body) | 202 server.sendmail(from_address, [to_address], msg_body) |
201 server.quit() | 203 server.quit() |
202 except Exception as e: | 204 except Exception as e: |
203 print 'Failed to send alert email. Error: %s' % e | 205 print 'Failed to send alert email. Error: %s' % e |
204 | 206 |
205 | 207 |
208 def RestartUsb(): | |
Isaac (away)
2013/10/11 18:10:08
I'd rather this return error than warning.
This c
navabi
2013/10/11 18:39:02
I disagree. The failure of restart_usb.py should n
Isaac (away)
2013/10/11 19:04:10
If you're not failing here, what's your plan to en
navabi
2013/10/11 22:03:28
The plan is to add error (or email notification) o
navabi
2013/10/11 22:03:28
bb_device_status_check does not run in testing mod
| |
209 if not os.path.isfile('/usr/bin/restart_usb'): | |
210 print ('WARNING: Could not restart usb. /usr/bin/restart_usb not installed ' | |
211 'on host (see BUG=305769).') | |
212 return | |
213 | |
214 lsusb_proc = bb_utils.SpawnCmd(['lsusb'], stdout=subprocess.PIPE) | |
215 lsusb_output, _ = lsusb_proc.communicate() | |
216 if lsusb_proc.returncode: | |
Isaac (away)
2013/10/11 18:10:08
Please return error.
navabi
2013/10/11 22:03:28
Done.
| |
217 print ('WARNING: Could not restart usb. Error getting list of USB ports.') | |
218 return | |
219 | |
220 usb_devices = [re.findall('Bus (\d\d\d) Device (\d\d\d)', lsusb_line)[0] | |
221 for lsusb_line in lsusb_output.strip().split('\n')] | |
222 | |
223 # Walk USB devices from leaves up (i.e reverse sorted) restarting the | |
224 # connection. If a parent node (e.g. usb hub) is restarted before the | |
225 # devices connected to it, the (bus, dev) for the hub can change, making the | |
226 # output we have wrong. This way we restart the devices before the hub. | |
227 for (bus, dev) in reversed(sorted(usb_devices)): | |
Isaac (away)
2013/10/11 18:10:08
Is this possible to restrict to only android devic
navabi
2013/10/11 18:39:02
It is, but I don't think that's what we want. I th
Isaac (away)
2013/10/11 19:04:10
I'd be surprised if a USB hub needed to be reset.
navabi
2013/10/11 22:03:28
The script has always restarted all usb ports (inc
| |
228 # Can not restart root usb connections | |
229 if dev != '001': | |
230 return_code = bb_utils.RunCmd(['/usr/bin/restart_usb', bus, dev], | |
231 flunk_on_failure=False) | |
Isaac (away)
2013/10/11 18:10:08
flunk on failure.
navabi
2013/10/11 18:39:02
See first comment. I don't think this should flunk
Isaac (away)
2013/10/11 19:04:10
Do you expect this binary to occasionally fail?
navabi
2013/10/11 22:03:28
Let's land it and see. We don't know yet as curren
| |
232 if return_code: | |
233 print 'Error restarting USB device /dev/bus/usb/%s/%s' % (bus, dev) | |
234 else: | |
235 print 'Restarted USB device /dev/bus/usb/%s/%s' % (bus, dev) | |
236 | |
237 | |
206 def main(): | 238 def main(): |
207 parser = optparse.OptionParser() | 239 parser = optparse.OptionParser() |
208 parser.add_option('', '--out-dir', | 240 parser.add_option('', '--out-dir', |
209 help='Directory where the device path is stored', | 241 help='Directory where the device path is stored', |
210 default=os.path.join(constants.DIR_SOURCE_ROOT, 'out')) | 242 default=os.path.join(constants.DIR_SOURCE_ROOT, 'out')) |
211 parser.add_option('--no-provisioning-check', action='store_true', | 243 parser.add_option('--no-provisioning-check', action='store_true', |
212 help='Will not check if devices are provisioned properly.') | 244 help='Will not check if devices are provisioned properly.') |
213 parser.add_option('--device-status-dashboard', action='store_true', | 245 parser.add_option('--device-status-dashboard', action='store_true', |
214 help='Output device status data for dashboard.') | 246 help='Output device status data for dashboard.') |
247 parser.add_option('--restart-usb', action='store_true', | |
248 help='Restart USB ports before running device check.') | |
215 options, args = parser.parse_args() | 249 options, args = parser.parse_args() |
216 if args: | 250 if args: |
217 parser.error('Unknown options %s' % args) | 251 parser.error('Unknown options %s' % args) |
252 | |
253 if options.restart_usb: | |
254 RestartUsb() | |
255 | |
218 devices = android_commands.GetAttachedDevices() | 256 devices = android_commands.GetAttachedDevices() |
219 # TODO(navabi): Test to make sure this fails and then fix call | 257 # TODO(navabi): Test to make sure this fails and then fix call |
220 offline_devices = android_commands.GetAttachedDevices(hardware=False, | 258 offline_devices = android_commands.GetAttachedDevices(hardware=False, |
221 emulator=False, | 259 emulator=False, |
222 offline=True) | 260 offline=True) |
223 | 261 |
224 types, builds, batteries, reports, errors = [], [], [], [], [] | 262 types, builds, batteries, reports, errors = [], [], [], [], [] |
225 fail_step_lst = [] | 263 fail_step_lst = [] |
226 if devices: | 264 if devices: |
227 types, builds, batteries, reports, errors, fail_step_lst = ( | 265 types, builds, batteries, reports, errors, fail_step_lst = ( |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 # devices with critically low battery or install speed. Remove those devices | 301 # devices with critically low battery or install speed. Remove those devices |
264 # from testing, allowing build to continue with good devices. | 302 # from testing, allowing build to continue with good devices. |
265 return 1 | 303 return 1 |
266 | 304 |
267 if not devices: | 305 if not devices: |
268 return 1 | 306 return 1 |
269 | 307 |
270 | 308 |
271 if __name__ == '__main__': | 309 if __name__ == '__main__': |
272 sys.exit(main()) | 310 sys.exit(main()) |
OLD | NEW |