| 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 |