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 argparse | 8 import argparse |
9 import json | 9 import json |
10 import logging | 10 import logging |
11 import os | 11 import os |
12 import psutil | 12 import psutil |
13 import re | 13 import re |
14 import signal | 14 import signal |
15 import smtplib | 15 import smtplib |
16 import subprocess | |
17 import sys | 16 import sys |
18 import time | |
19 import urllib | |
20 | 17 |
21 import bb_annotations | 18 import bb_annotations |
22 import bb_utils | |
23 | 19 |
24 sys.path.append(os.path.join(os.path.dirname(__file__), | 20 sys.path.append(os.path.join(os.path.dirname(__file__), |
25 os.pardir, os.pardir, 'util', 'lib', | 21 os.pardir, os.pardir, 'util', 'lib', |
26 'common')) | 22 'common')) |
27 import perf_tests_results_helper # pylint: disable=F0401 | 23 import perf_tests_results_helper # pylint: disable=F0401 |
28 | 24 |
29 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) | 25 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) |
30 from devil.android import battery_utils | 26 from devil.android import battery_utils |
31 from devil.android import device_blacklist | 27 from devil.android import device_blacklist |
32 from devil.android import device_errors | 28 from devil.android import device_errors |
33 from devil.android import device_list | 29 from devil.android import device_list |
34 from devil.android import device_utils | 30 from devil.android import device_utils |
35 from devil.android.sdk import adb_wrapper | 31 from devil.android.sdk import adb_wrapper |
36 from devil.utils import reset_usb | 32 from devil.utils import reset_usb |
37 from devil.utils import run_tests_helper | 33 from devil.utils import run_tests_helper |
38 from devil.utils import timeout_retry | |
39 from pylib import constants | 34 from pylib import constants |
40 from pylib.cmd_helper import GetCmdOutput | |
41 | 35 |
42 _RE_DEVICE_ID = re.compile('Device ID = (\d+)') | 36 _RE_DEVICE_ID = re.compile(r'Device ID = (\d+)') |
43 | 37 |
44 def DeviceInfo(device, args): | 38 def DeviceInfo(device, args): |
45 """Gathers info on a device via various adb calls. | 39 """Gathers info on a device via various adb calls. |
46 | 40 |
47 Args: | 41 Args: |
48 device: A DeviceUtils instance for the device to construct info about. | 42 device: A DeviceUtils instance for the device to construct info about. |
49 | 43 |
50 Returns: | 44 Returns: |
51 Tuple of device type, build id, report as a string, error messages, and | 45 Tuple of device type, build id, report as a string, error messages, and |
52 boolean indicating whether or not device can be used for testing. | 46 boolean indicating whether or not device can be used for testing. |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 last_missing_devices = [] | 137 last_missing_devices = [] |
144 | 138 |
145 missing_devs = list(set(last_devices) - device_serials) | 139 missing_devs = list(set(last_devices) - device_serials) |
146 new_missing_devs = list(set(missing_devs) - set(last_missing_devices)) | 140 new_missing_devs = list(set(missing_devs) - set(last_missing_devices)) |
147 | 141 |
148 buildbot_slavename = os.environ.get('BUILDBOT_SLAVENAME') | 142 buildbot_slavename = os.environ.get('BUILDBOT_SLAVENAME') |
149 buildbot_buildername = os.environ.get('BUILDBOT_BUILDERNAME') | 143 buildbot_buildername = os.environ.get('BUILDBOT_BUILDERNAME') |
150 buildbot_buildnumber = os.environ.get('BUILDBOT_BUILDNUMBER') | 144 buildbot_buildnumber = os.environ.get('BUILDBOT_BUILDNUMBER') |
151 | 145 |
152 if new_missing_devs and buildbot_slavename: | 146 if new_missing_devs and buildbot_slavename: |
153 logging.info('new_missing_devs %s' % new_missing_devs) | 147 logging.info('new_missing_devs %s', new_missing_devs) |
154 devices_missing_msg = '%d devices not detected.' % len(missing_devs) | 148 devices_missing_msg = '%d devices not detected.' % len(missing_devs) |
155 bb_annotations.PrintSummaryText(devices_missing_msg) | 149 bb_annotations.PrintSummaryText(devices_missing_msg) |
156 | 150 |
157 from_address = 'chrome-bot@chromium.org' | 151 from_address = 'chrome-bot@chromium.org' |
158 to_addresses = ['chrome-labs-tech-ticket@google.com', | 152 to_addresses = ['chrome-labs-tech-ticket@google.com', |
159 'chrome-android-device-alert@google.com'] | 153 'chrome-android-device-alert@google.com'] |
160 cc_addresses = ['chrome-android-device-alert@google.com'] | 154 cc_addresses = ['chrome-android-device-alert@google.com'] |
161 subject = 'Devices offline on %s, %s, %s' % ( | 155 subject = 'Devices offline on %s, %s, %s' % ( |
162 buildbot_slavename, buildbot_buildername, buildbot_buildnumber) | 156 buildbot_slavename, buildbot_buildername, buildbot_buildnumber) |
163 msg = ('Please reboot the following devices:\n%s' % | 157 msg = ('Please reboot the following devices:\n%s' % |
164 '\n'.join(map(str, new_missing_devs))) | 158 '\n'.join(str(d) for d in new_missing_devs)) |
165 SendEmail(from_address, to_addresses, cc_addresses, subject, msg) | 159 SendEmail(from_address, to_addresses, cc_addresses, subject, msg) |
166 | 160 |
167 unauthorized_devices = adb_wrapper.AdbWrapper.Devices( | 161 unauthorized_devices = adb_wrapper.AdbWrapper.Devices( |
168 desired_state='unauthorized') | 162 desired_state='unauthorized') |
169 if unauthorized_devices: | 163 if unauthorized_devices: |
170 logging.info('unauthorized devices:') | 164 logging.info('unauthorized devices:') |
171 for ud in unauthorized_devices: | 165 for ud in unauthorized_devices: |
172 logging.info(' %s', ud) | 166 logging.info(' %s', ud) |
173 | 167 |
174 if buildbot_slavename: | 168 if buildbot_slavename: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 # TODO(jbudorick): Transition from email alerts for every failure to a more | 206 # TODO(jbudorick): Transition from email alerts for every failure to a more |
213 # sustainable solution. | 207 # sustainable solution. |
214 msg_body = '\r\n'.join(['From: %s' % from_address, | 208 msg_body = '\r\n'.join(['From: %s' % from_address, |
215 'To: %s' % ', '.join(to_addresses), | 209 'To: %s' % ', '.join(to_addresses), |
216 'CC: %s' % ', '.join(cc_addresses), | 210 'CC: %s' % ', '.join(cc_addresses), |
217 'Subject: %s' % subject, '', msg]) | 211 'Subject: %s' % subject, '', msg]) |
218 try: | 212 try: |
219 server = smtplib.SMTP('localhost') | 213 server = smtplib.SMTP('localhost') |
220 server.sendmail(from_address, to_addresses, msg_body) | 214 server.sendmail(from_address, to_addresses, msg_body) |
221 server.quit() | 215 server.quit() |
222 except Exception: | 216 except Exception: # pylint: disable=broad-except |
223 logging.exception('Failed to send alert email.') | 217 logging.exception('Failed to send alert email.') |
224 | 218 |
225 | 219 |
226 def KillAllAdb(): | 220 def KillAllAdb(): |
227 def GetAllAdb(): | 221 def GetAllAdb(): |
228 for p in psutil.process_iter(): | 222 for p in psutil.process_iter(): |
229 try: | 223 try: |
230 if 'adb' in p.name: | 224 if 'adb' in p.name: |
231 yield p | 225 yield p |
232 except (psutil.NoSuchProcess, psutil.AccessDenied): | 226 except (psutil.NoSuchProcess, psutil.AccessDenied): |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 zip(*[DeviceInfo(dev, args) for dev in devices])) | 330 zip(*[DeviceInfo(dev, args) for dev in devices])) |
337 | 331 |
338 # Write device info to file for buildbot info display. | 332 # Write device info to file for buildbot info display. |
339 if os.path.exists('/home/chrome-bot'): | 333 if os.path.exists('/home/chrome-bot'): |
340 with open('/home/chrome-bot/.adb_device_info', 'w') as f: | 334 with open('/home/chrome-bot/.adb_device_info', 'w') as f: |
341 for device in json_data: | 335 for device in json_data: |
342 try: | 336 try: |
343 f.write('%s %s %s %.1fC %s%%\n' % (device['serial'], device['type'], | 337 f.write('%s %s %s %.1fC %s%%\n' % (device['serial'], device['type'], |
344 device['build'], float(device['battery']['temperature']) / 10, | 338 device['build'], float(device['battery']['temperature']) / 10, |
345 device['battery']['level'])) | 339 device['battery']['level'])) |
346 except Exception: | 340 except Exception: # pylint: disable=broad-except |
347 pass | 341 pass |
348 | 342 |
349 err_msg = CheckForMissingDevices(args, devices) or [] | 343 err_msg = CheckForMissingDevices(args, devices) or [] |
350 | 344 |
351 unique_types = list(set(types)) | 345 unique_types = list(set(types)) |
352 unique_builds = list(set(builds)) | 346 unique_builds = list(set(builds)) |
353 | 347 |
354 bb_annotations.PrintMsg('Online devices: %d. Device types %s, builds %s' | 348 bb_annotations.PrintMsg('Online devices: %d. Device types %s, builds %s' |
355 % (len(devices), unique_types, unique_builds)) | 349 % (len(devices), unique_types, unique_builds)) |
356 | 350 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 | 403 |
410 if num_failed_devs == len(devices): | 404 if num_failed_devs == len(devices): |
411 return 2 | 405 return 2 |
412 | 406 |
413 if not devices: | 407 if not devices: |
414 return 1 | 408 return 1 |
415 | 409 |
416 | 410 |
417 if __name__ == '__main__': | 411 if __name__ == '__main__': |
418 sys.exit(main()) | 412 sys.exit(main()) |
OLD | NEW |