 Chromium Code Reviews
 Chromium Code Reviews Issue 11021004:
  Make device_status_check.py email clank-infra if devices go offline.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 11021004:
  Make device_status_check.py email clank-infra if devices go offline.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| OLD | NEW | 
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python | 
| 2 # | 2 # | 
| 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2012 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 | 8 | 
| 9 import optparse | 9 import optparse | 
| 10 import os | 10 import os | 
| 11 import smtplib | |
| 11 import sys | 12 import sys | 
| 12 | 13 | 
| 13 from pylib import buildbot_report | 14 from pylib import buildbot_report | 
| 14 from pylib.android_commands import GetAttachedDevices | 15 from pylib.android_commands import GetAttachedDevices | 
| 15 from pylib.cmd_helper import GetCmdOutput | 16 from pylib.cmd_helper import GetCmdOutput | 
| 16 | 17 | 
| 17 | 18 | 
| 18 def DeviceInfo(serial): | 19 def DeviceInfo(serial): | 
| 19 """Gathers info on a device via various adb calls. | 20 """Gathers info on a device via various adb calls. | 
| 20 | 21 | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 def CheckForMissingDevices(options, adb_online_devs): | 53 def CheckForMissingDevices(options, adb_online_devs): | 
| 53 """Uses file of previous online devices to detect broken phones. | 54 """Uses file of previous online devices to detect broken phones. | 
| 54 | 55 | 
| 55 Args: | 56 Args: | 
| 56 options: out_dir parameter of options argument is used as the base | 57 options: out_dir parameter of options argument is used as the base | 
| 57 directory to load and update the cache file. | 58 directory to load and update the cache file. | 
| 58 adb_online_devs: A list of serial numbers of the currently visible | 59 adb_online_devs: A list of serial numbers of the currently visible | 
| 59 and online attached devices. | 60 and online attached devices. | 
| 60 """ | 61 """ | 
| 61 out_dir = os.path.abspath(options.out_dir) | 62 out_dir = os.path.abspath(options.out_dir) | 
| 63 | |
| 64 def ReadDeviceList(file_name): | |
| 65 devices_path = os.path.join(out_dir, file_name) | |
| 66 devices = [] | |
| 67 try: | |
| 68 with open(devices_path) as f: | |
| 69 devices = f.read().splitlines() | |
| 70 except IOError: | |
| 71 # Ignore error, file might not exist | |
| 72 pass | |
| 73 return devices | |
| 74 | |
| 75 def WriteDeviceList(file_name, device_list): | |
| 76 path = os.path.join(out_dir, file_name) | |
| 77 if not os.path.exists(out_dir): | |
| 78 os.makedirs(out_dir) | |
| 79 with open(path, 'w') as f: | |
| 80 # Write devices currently visible plus devices previously seen. | |
| 81 f.write('\n'.join(set(device_list))) | |
| 82 | |
| 62 last_devices_path = os.path.join(out_dir, '.last_devices') | 83 last_devices_path = os.path.join(out_dir, '.last_devices') | 
| 63 last_devices = [] | 84 last_devices = ReadDeviceList('.last_devices') | 
| 64 try: | |
| 65 with open(last_devices_path) as f: | |
| 66 last_devices = f.read().splitlines() | |
| 67 except IOError: | |
| 68 # Ignore error, file might not exist | |
| 69 pass | |
| 70 | 85 | 
| 71 missing_devs = list(set(last_devices) - set(adb_online_devs)) | 86 missing_devs = list(set(last_devices) - set(adb_online_devs)) | 
| 72 if missing_devs: | 87 if missing_devs: | 
| 88 from_address = 'buildbot@chromium.org' | |
| 89 to_address = 'chromium-android-device-alerts@google.com' | |
| 90 bot_name = os.environ['BUILDBOT_BUILDERNAME'] | |
| 91 slave_name = os.environ['BUILDBOT_SLAVENAME'] | |
| 92 num_online_devs = len(adb_online_devs) | |
| 93 subject = 'Devices offline on %s, %s (%d remaining).' % (slave_name, | |
| 94 bot_name, | |
| 95 num_online_devs) | |
| 73 buildbot_report.PrintWarning() | 96 buildbot_report.PrintWarning() | 
| 74 buildbot_report.PrintSummaryText( | 97 devices_missing_msg = '%d devices not detected.' % len(missing_devs) | 
| 75 '%d devices not detected.' % len(missing_devs)) | 98 buildbot_report.PrintSummaryText(devices_missing_msg) | 
| 76 print 'Current online devices: %s' % adb_online_devs | 99 | 
| 77 print '%s are no longer visible. Were they removed?\n' % missing_devs | 100 body = '\n'.join( | 
| 78 print 'SHERIFF: See go/chrome_device_monitor' | 101 ['Current online devices: %s' % adb_online_devs, | 
| 79 print 'Cache file: %s\n\n' % last_devices_path | 102 '%s are no longer visible. Were they removed?\n' % missing_devs, | 
| 80 print 'adb devices' | 103 'SHERIFF: See go/clank/engineering/buildbots/troubleshooting', | 
| 
Isaac (away)
2012/10/03 06:39:50
Why did you change this link?  Please fix this, to
 | |
| 81 print GetCmdOutput(['adb', 'devices']) | 104 'Cache file: %s\n\n' % last_devices_path, | 
| 105 'adb devices: %s' % GetCmdOutput(['adb', 'devices'])]) | |
| 106 | |
| 107 print body | |
| 108 | |
| 109 # Only send email if the first time a particular device goes offline | |
| 110 last_missing = ReadDeviceList('.last_missing') | |
| 111 new_missing_devs = set(missing_devs) - set(last_missing) | |
| 112 | |
| 113 if new_missing_devs: | |
| 114 msg_body = '\r\n'.join( | |
| 115 ['From: %s' % from_address, | |
| 116 'To: %s' % to_address, | |
| 117 'Subject: %s' % subject, | |
| 118 '', body]) | |
| 119 server = smtplib.SMTP('localhost') | |
| 120 server.sendmail(from_address, [to_address], msg_body) | |
| 121 server.quit() | |
| 82 else: | 122 else: | 
| 83 new_devs = set(adb_online_devs) - set(last_devices) | 123 new_devs = set(adb_online_devs) - set(last_devices) | 
| 84 if new_devs and os.path.exists(last_devices_path): | 124 if new_devs and os.path.exists(last_devices_path): | 
| 85 buildbot_report.PrintWarning() | 125 buildbot_report.PrintWarning() | 
| 86 buildbot_report.PrintSummaryText( | 126 buildbot_report.PrintSummaryText( | 
| 87 '%d new devices detected' % len(new_devs)) | 127 '%d new devices detected' % len(new_devs)) | 
| 88 print ('New devices detected %s. And now back to your ' | 128 print ('New devices detected %s. And now back to your ' | 
| 89 'regularly scheduled program.' % list(new_devs)) | 129 'regularly scheduled program.' % list(new_devs)) | 
| 90 | 130 WriteDeviceList('.last_devices', (adb_online_devs + last_devices)) | 
| 91 if not os.path.exists(out_dir): | 131 WriteDeviceList('.last_missing', missing_devs) | 
| 92 os.makedirs(out_dir) | |
| 93 with open(last_devices_path, 'w') as f: | |
| 94 # Write devices currently visible plus devices previously seen. | |
| 95 f.write('\n'.join(set(adb_online_devs + last_devices))) | |
| 96 | 132 | 
| 97 | 133 | 
| 98 def main(): | 134 def main(): | 
| 99 parser = optparse.OptionParser() | 135 parser = optparse.OptionParser() | 
| 100 parser.add_option('', '--out-dir', | 136 parser.add_option('', '--out-dir', | 
| 101 help='Directory where the device path is stored', | 137 help='Directory where the device path is stored', | 
| 102 default=os.path.join(os.path.dirname(__file__), '..', | 138 default=os.path.join(os.path.dirname(__file__), '..', | 
| 103 '..', 'out')) | 139 '..', 'out')) | 
| 104 | 140 | 
| 105 options, args = parser.parse_args() | 141 options, args = parser.parse_args() | 
| 106 if args: | 142 if args: | 
| 107 parser.error('Unknown options %s' % args) | 143 parser.error('Unknown options %s' % args) | 
| 108 buildbot_report.PrintNamedStep('Device Status Check') | 144 buildbot_report.PrintNamedStep('Device Status Check') | 
| 109 devices = GetAttachedDevices() | 145 devices = GetAttachedDevices() | 
| 110 types, builds, reports = [], [], [] | 146 types, builds, reports = [], [], [] | 
| 111 if devices: | 147 if devices: | 
| 112 types, builds, reports = zip(*[DeviceInfo(dev) for dev in devices]) | 148 types, builds, reports = zip(*[DeviceInfo(dev) for dev in devices]) | 
| 113 | 149 | 
| 114 unique_types = list(set(types)) | 150 unique_types = list(set(types)) | 
| 115 unique_builds = list(set(builds)) | 151 unique_builds = list(set(builds)) | 
| 116 | 152 | 
| 117 buildbot_report.PrintMsg('Online devices: %d. Device types %s, builds %s' | 153 buildbot_report.PrintMsg('Online devices: %d. Device types %s, builds %s' | 
| 118 % (len(devices), unique_types, unique_builds)) | 154 % (len(devices), unique_types, unique_builds)) | 
| 119 print '\n'.join(reports) | 155 print '\n'.join(reports) | 
| 120 CheckForMissingDevices(options, devices) | 156 CheckForMissingDevices(options, devices) | 
| 121 | 157 | 
| 122 if __name__ == '__main__': | 158 if __name__ == '__main__': | 
| 123 sys.exit(main()) | 159 sys.exit(main()) | 
| OLD | NEW |