Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: build/android/buildbot/bb_device_status_check.py

Issue 1124763003: Update from https://crrev.com/327068 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: update nacl, buildtools, fix display_change_notifier_unittest Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 json 8 import json
9 import logging 9 import logging
10 import optparse 10 import optparse
(...skipping 12 matching lines...) Expand all
23 23
24 sys.path.append(os.path.join(os.path.dirname(__file__), 24 sys.path.append(os.path.join(os.path.dirname(__file__),
25 os.pardir, os.pardir, 'util', 'lib', 25 os.pardir, os.pardir, 'util', 'lib',
26 'common')) 26 'common'))
27 import perf_tests_results_helper # pylint: disable=F0401 27 import perf_tests_results_helper # pylint: disable=F0401
28 28
29 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) 29 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
30 from pylib import android_commands 30 from pylib import android_commands
31 from pylib import constants 31 from pylib import constants
32 from pylib.cmd_helper import GetCmdOutput 32 from pylib.cmd_helper import GetCmdOutput
33 from pylib.device import battery_utils
33 from pylib.device import device_blacklist 34 from pylib.device import device_blacklist
35 from pylib.device import device_errors
34 from pylib.device import device_list 36 from pylib.device import device_list
35 from pylib.device import device_utils 37 from pylib.device import device_utils
38 from pylib.utils import run_tests_helper
39
40 _RE_DEVICE_ID = re.compile('Device ID = (\d+)')
36 41
37 def DeviceInfo(serial, options): 42 def DeviceInfo(serial, options):
38 """Gathers info on a device via various adb calls. 43 """Gathers info on a device via various adb calls.
39 44
40 Args: 45 Args:
41 serial: The serial of the attached device to construct info about. 46 serial: The serial of the attached device to construct info about.
42 47
43 Returns: 48 Returns:
44 Tuple of device type, build id, report as a string, error messages, and 49 Tuple of device type, build id, report as a string, error messages, and
45 boolean indicating whether or not device can be used for testing. 50 boolean indicating whether or not device can be used for testing.
46 """ 51 """
52 device = device_utils.DeviceUtils(serial)
53 battery = battery_utils.BatteryUtils(device)
47 54
48 device_adb = device_utils.DeviceUtils(serial) 55 battery_info = {}
49 device_type = device_adb.build_product 56 battery_level = 100
50 device_build = device_adb.build_id 57 errors = []
51 device_build_type = device_adb.build_type 58 dev_good = True
52 device_product_name = device_adb.product_name 59 json_data = {
60 'serial': serial,
61 'type': device.build_product,
62 'build': device.build_id,
63 'build_detail': device.GetProp('ro.build.fingerprint'),
64 'battery': {},
65 'imei_slice': 'Unknown',
66 'wifi_ip': device.GetProp('dhcp.wlan0.ipaddress'),
67 }
53 68
54 try: 69 try:
55 battery_info = device_adb.old_interface.GetBatteryInfo() 70 try:
56 except Exception as e: 71 battery_info = battery.GetBatteryInfo(timeout=5)
57 battery_info = {} 72 battery_level = int(battery_info.get('level', battery_level))
58 logging.error('Unable to obtain battery info for %s, %s', serial, e) 73 json_data['battery'] = battery_info
74 except device_errors.CommandFailedError:
75 logging.exception('Failed to get battery information for %s', serial)
59 76
60 def _GetData(re_expression, line, lambda_function=lambda x: x): 77 try:
61 if not line: 78 for l in device.RunShellCommand(['dumpsys', 'iphonesubinfo'],
62 return 'Unknown' 79 check_return=True, timeout=5):
63 found = re.findall(re_expression, line) 80 m = _RE_DEVICE_ID.match(l)
64 if found and len(found): 81 if m:
65 return lambda_function(found[0]) 82 json_data['imei_slice'] = m.group(1)[-6:]
66 return 'Unknown' 83 except device_errors.CommandFailedError:
84 logging.exception('Failed to get IMEI slice for %s', serial)
67 85
68 battery_level = int(battery_info.get('level', 100)) 86 if battery_level < 15:
69 imei_slice = _GetData(r'Device ID = (\d+)', 87 errors += ['Device critically low in battery.']
70 device_adb.old_interface.GetSubscriberInfo(), 88 dev_good = False
71 lambda x: x[-6:]) 89 if not battery.GetCharging():
72 json_data = { 90 battery.SetCharging(True)
73 'serial': serial, 91 if not options.no_provisioning_check:
74 'type': device_type, 92 setup_wizard_disabled = (
75 'build': device_build, 93 device.GetProp('ro.setupwizard.mode') == 'DISABLED')
76 'build_detail': device_adb.GetProp('ro.build.fingerprint'), 94 if not setup_wizard_disabled and device.build_type != 'user':
77 'battery': battery_info, 95 errors += ['Setup wizard not disabled. Was it provisioned correctly?']
78 'imei_slice': imei_slice, 96 if (device.product_name == 'mantaray' and
79 'wifi_ip': device_adb.GetProp('dhcp.wlan0.ipaddress'), 97 battery_info.get('AC powered', None) != 'true'):
80 } 98 errors += ['Mantaray device not connected to AC power.']
81 report = ['Device %s (%s)' % (serial, device_type), 99 except device_errors.CommandFailedError:
82 ' Build: %s (%s)' % 100 logging.exception('Failure while getting device status.')
83 (device_build, json_data['build_detail']), 101 dev_good = False
84 ' Current Battery Service state: ', 102 except device_errors.CommandTimeoutError:
85 '\n'.join([' %s: %s' % (k, v) 103 logging.exception('Timeout while getting device status.')
86 for k, v in battery_info.iteritems()]), 104 dev_good = False
87 ' IMEI slice: %s' % imei_slice,
88 ' Wifi IP: %s' % json_data['wifi_ip'],
89 '']
90 105
91 errors = [] 106 return (device.build_product, device.build_id, battery_level, errors,
92 dev_good = True 107 dev_good, json_data)
93 if battery_level < 15:
94 errors += ['Device critically low in battery. Will add to blacklist.']
95 dev_good = False
96 if not device_adb.old_interface.IsDeviceCharging():
97 if device_adb.old_interface.CanControlUsbCharging():
98 device_adb.old_interface.EnableUsbCharging()
99 else:
100 logging.error('Device %s is not charging' % serial)
101 if not options.no_provisioning_check:
102 setup_wizard_disabled = (
103 device_adb.GetProp('ro.setupwizard.mode') == 'DISABLED')
104 if not setup_wizard_disabled and device_build_type != 'user':
105 errors += ['Setup wizard not disabled. Was it provisioned correctly?']
106 if (device_product_name == 'mantaray' and
107 battery_info.get('AC powered', None) != 'true'):
108 errors += ['Mantaray device not connected to AC power.']
109
110 full_report = '\n'.join(report)
111
112 return (device_type, device_build, battery_level, full_report, errors,
113 dev_good, json_data)
114 108
115 109
116 def CheckForMissingDevices(options, adb_online_devs): 110 def CheckForMissingDevices(options, adb_online_devs):
117 """Uses file of previous online devices to detect broken phones. 111 """Uses file of previous online devices to detect broken phones.
118 112
119 Args: 113 Args:
120 options: out_dir parameter of options argument is used as the base 114 options: out_dir parameter of options argument is used as the base
121 directory to load and update the cache file. 115 directory to load and update the cache file.
122 adb_online_devs: A list of serial numbers of the currently visible 116 adb_online_devs: A list of serial numbers of the currently visible
123 and online attached devices. 117 and online attached devices.
124 """ 118 """
125 # TODO(navabi): remove this once the bug that causes different number
126 # of devices to be detected between calls is fixed.
127 logger = logging.getLogger()
128 logger.setLevel(logging.INFO)
129
130 out_dir = os.path.abspath(options.out_dir) 119 out_dir = os.path.abspath(options.out_dir)
131 120
132 # last_devices denotes all known devices prior to this run 121 # last_devices denotes all known devices prior to this run
133 last_devices_path = os.path.join(out_dir, device_list.LAST_DEVICES_FILENAME) 122 last_devices_path = os.path.join(out_dir, device_list.LAST_DEVICES_FILENAME)
134 last_missing_devices_path = os.path.join(out_dir, 123 last_missing_devices_path = os.path.join(out_dir,
135 device_list.LAST_MISSING_DEVICES_FILENAME) 124 device_list.LAST_MISSING_DEVICES_FILENAME)
136 try: 125 try:
137 last_devices = device_list.GetPersistentDeviceList(last_devices_path) 126 last_devices = device_list.GetPersistentDeviceList(last_devices_path)
138 except IOError: 127 except IOError:
139 # Ignore error, file might not exist 128 # Ignore error, file might not exist
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 crbug_link = ('https://code.google.com/p/chromium/issues/entry?summary=' 171 crbug_link = ('https://code.google.com/p/chromium/issues/entry?summary='
183 '%s&comment=%s&labels=Restrict-View-Google,OS-Android,Infra' % 172 '%s&comment=%s&labels=Restrict-View-Google,OS-Android,Infra' %
184 (urllib.quote('Device Offline'), 173 (urllib.quote('Device Offline'),
185 urllib.quote('Buildbot: %s %s\n' 174 urllib.quote('Buildbot: %s %s\n'
186 'Build: %s\n' 175 'Build: %s\n'
187 '(please don\'t change any labels)' % 176 '(please don\'t change any labels)' %
188 (os.environ.get('BUILDBOT_BUILDERNAME'), 177 (os.environ.get('BUILDBOT_BUILDERNAME'),
189 os.environ.get('BUILDBOT_SLAVENAME'), 178 os.environ.get('BUILDBOT_SLAVENAME'),
190 os.environ.get('BUILDBOT_BUILDNUMBER'))))) 179 os.environ.get('BUILDBOT_BUILDNUMBER')))))
191 return ['Current online devices: %s' % adb_online_devs, 180 return ['Current online devices: %s' % adb_online_devs,
192 '%s are no longer visible. Were they removed?\n' % missing_devs, 181 '%s are no longer visible. Were they removed?' % missing_devs,
193 'SHERIFF:\n', 182 'SHERIFF:',
194 '@@@STEP_LINK@Click here to file a bug@%s@@@\n' % crbug_link, 183 '@@@STEP_LINK@Click here to file a bug@%s@@@' % crbug_link,
195 'Cache file: %s\n\n' % last_devices_path, 184 'Cache file: %s' % last_devices_path,
196 'adb devices: %s' % GetCmdOutput(['adb', 'devices']), 185 'adb devices: %s' % GetCmdOutput(['adb', 'devices']),
197 'adb devices(GetAttachedDevices): %s' % adb_online_devs] 186 'adb devices(GetAttachedDevices): %s' % adb_online_devs]
198 else: 187 else:
199 new_devs = set(adb_online_devs) - set(last_devices) 188 new_devs = set(adb_online_devs) - set(last_devices)
200 if new_devs and os.path.exists(last_devices_path): 189 if new_devs and os.path.exists(last_devices_path):
201 bb_annotations.PrintWarning() 190 bb_annotations.PrintWarning()
202 bb_annotations.PrintSummaryText( 191 bb_annotations.PrintSummaryText(
203 '%d new devices detected' % len(new_devs)) 192 '%d new devices detected' % len(new_devs))
204 print ('New devices detected %s. And now back to your ' 193 logging.info('New devices detected:')
205 'regularly scheduled program.' % list(new_devs)) 194 for d in new_devs:
195 logging.info(' %s', d)
206 196
207 197
208 def SendEmail(from_address, to_addresses, cc_addresses, subject, msg): 198 def SendEmail(from_address, to_addresses, cc_addresses, subject, msg):
209 msg_body = '\r\n'.join(['From: %s' % from_address, 199 msg_body = '\r\n'.join(['From: %s' % from_address,
210 'To: %s' % ', '.join(to_addresses), 200 'To: %s' % ', '.join(to_addresses),
211 'CC: %s' % ', '.join(cc_addresses), 201 'CC: %s' % ', '.join(cc_addresses),
212 'Subject: %s' % subject, '', msg]) 202 'Subject: %s' % subject, '', msg])
213 try: 203 try:
214 server = smtplib.SMTP('localhost') 204 server = smtplib.SMTP('localhost')
215 server.sendmail(from_address, to_addresses, msg_body) 205 server.sendmail(from_address, to_addresses, msg_body)
216 server.quit() 206 server.quit()
217 except Exception as e: 207 except Exception:
218 print 'Failed to send alert email. Error: %s' % e 208 logging.exception('Failed to send alert email.')
219 209
220 210
221 def RestartUsb(): 211 def RestartUsb():
222 if not os.path.isfile('/usr/bin/restart_usb'): 212 if not os.path.isfile('/usr/bin/restart_usb'):
223 print ('ERROR: Could not restart usb. /usr/bin/restart_usb not installed ' 213 logging.error('Could not restart usb. ''/usr/bin/restart_usb not '
224 'on host (see BUG=305769).') 214 'installed on host (see BUG=305769).')
225 return False 215 return False
226 216
227 lsusb_proc = bb_utils.SpawnCmd(['lsusb'], stdout=subprocess.PIPE) 217 lsusb_proc = bb_utils.SpawnCmd(['lsusb'], stdout=subprocess.PIPE)
228 lsusb_output, _ = lsusb_proc.communicate() 218 lsusb_output, _ = lsusb_proc.communicate()
229 if lsusb_proc.returncode: 219 if lsusb_proc.returncode:
230 print 'Error: Could not get list of USB ports (i.e. lsusb).' 220 logging.error('Could not get list of USB ports (i.e. lsusb).')
231 return lsusb_proc.returncode 221 return lsusb_proc.returncode
232 222
233 usb_devices = [re.findall(r'Bus (\d\d\d) Device (\d\d\d)', lsusb_line)[0] 223 usb_devices = [re.findall(r'Bus (\d\d\d) Device (\d\d\d)', lsusb_line)[0]
234 for lsusb_line in lsusb_output.strip().split('\n')] 224 for lsusb_line in lsusb_output.strip().split('\n')]
235 225
236 all_restarted = True 226 all_restarted = True
237 # Walk USB devices from leaves up (i.e reverse sorted) restarting the 227 # Walk USB devices from leaves up (i.e reverse sorted) restarting the
238 # connection. If a parent node (e.g. usb hub) is restarted before the 228 # connection. If a parent node (e.g. usb hub) is restarted before the
239 # devices connected to it, the (bus, dev) for the hub can change, making the 229 # devices connected to it, the (bus, dev) for the hub can change, making the
240 # output we have wrong. This way we restart the devices before the hub. 230 # output we have wrong. This way we restart the devices before the hub.
241 for (bus, dev) in reversed(sorted(usb_devices)): 231 for (bus, dev) in reversed(sorted(usb_devices)):
242 # Can not restart root usb connections 232 # Can not restart root usb connections
243 if dev != '001': 233 if dev != '001':
244 return_code = bb_utils.RunCmd(['/usr/bin/restart_usb', bus, dev]) 234 return_code = bb_utils.RunCmd(['/usr/bin/restart_usb', bus, dev])
245 if return_code: 235 if return_code:
246 print 'Error restarting USB device /dev/bus/usb/%s/%s' % (bus, dev) 236 logging.error('Error restarting USB device /dev/bus/usb/%s/%s',
237 bus, dev)
247 all_restarted = False 238 all_restarted = False
248 else: 239 else:
249 print 'Restarted USB device /dev/bus/usb/%s/%s' % (bus, dev) 240 logging.info('Restarted USB device /dev/bus/usb/%s/%s', bus, dev)
250 241
251 return all_restarted 242 return all_restarted
252 243
253 244
254 def KillAllAdb(): 245 def KillAllAdb():
255 def GetAllAdb(): 246 def GetAllAdb():
256 for p in psutil.process_iter(): 247 for p in psutil.process_iter():
257 try: 248 try:
258 if 'adb' in p.name: 249 if 'adb' in p.name:
259 yield p 250 yield p
260 except (psutil.NoSuchProcess, psutil.AccessDenied): 251 except (psutil.NoSuchProcess, psutil.AccessDenied):
261 pass 252 pass
262 253
263 for sig in [signal.SIGTERM, signal.SIGQUIT, signal.SIGKILL]: 254 for sig in [signal.SIGTERM, signal.SIGQUIT, signal.SIGKILL]:
264 for p in GetAllAdb(): 255 for p in GetAllAdb():
265 try: 256 try:
266 print 'kill %d %d (%s [%s])' % (sig, p.pid, p.name, 257 logging.info('kill %d %d (%s [%s])', sig, p.pid, p.name,
267 ' '.join(p.cmdline)) 258 ' '.join(p.cmdline))
268 p.send_signal(sig) 259 p.send_signal(sig)
269 except (psutil.NoSuchProcess, psutil.AccessDenied): 260 except (psutil.NoSuchProcess, psutil.AccessDenied):
270 pass 261 pass
271 for p in GetAllAdb(): 262 for p in GetAllAdb():
272 try: 263 try:
273 print 'Unable to kill %d (%s [%s])' % (p.pid, p.name, ' '.join(p.cmdline)) 264 logging.error('Unable to kill %d (%s [%s])', p.pid, p.name,
265 ' '.join(p.cmdline))
274 except (psutil.NoSuchProcess, psutil.AccessDenied): 266 except (psutil.NoSuchProcess, psutil.AccessDenied):
275 pass 267 pass
276 268
277 269
278 def main(): 270 def main():
279 parser = optparse.OptionParser() 271 parser = optparse.OptionParser()
280 parser.add_option('', '--out-dir', 272 parser.add_option('', '--out-dir',
281 help='Directory where the device path is stored', 273 help='Directory where the device path is stored',
282 default=os.path.join(constants.DIR_SOURCE_ROOT, 'out')) 274 default=os.path.join(constants.DIR_SOURCE_ROOT, 'out'))
283 parser.add_option('--no-provisioning-check', action='store_true', 275 parser.add_option('--no-provisioning-check', action='store_true',
284 help='Will not check if devices are provisioned properly.') 276 help='Will not check if devices are provisioned properly.')
285 parser.add_option('--device-status-dashboard', action='store_true', 277 parser.add_option('--device-status-dashboard', action='store_true',
286 help='Output device status data for dashboard.') 278 help='Output device status data for dashboard.')
287 parser.add_option('--restart-usb', action='store_true', 279 parser.add_option('--restart-usb', action='store_true',
288 help='Restart USB ports before running device check.') 280 help='Restart USB ports before running device check.')
289 parser.add_option('--json-output', 281 parser.add_option('--json-output',
290 help='Output JSON information into a specified file.') 282 help='Output JSON information into a specified file.')
283 parser.add_option('-v', '--verbose', action='count', default=1,
284 help='Log more information.')
291 285
292 options, args = parser.parse_args() 286 options, args = parser.parse_args()
293 if args: 287 if args:
294 parser.error('Unknown options %s' % args) 288 parser.error('Unknown options %s' % args)
295 289
290 run_tests_helper.SetLogLevel(options.verbose)
291
296 # Remove the last build's "bad devices" before checking device statuses. 292 # Remove the last build's "bad devices" before checking device statuses.
297 device_blacklist.ResetBlacklist() 293 device_blacklist.ResetBlacklist()
298 294
299 try: 295 try:
300 expected_devices = device_list.GetPersistentDeviceList( 296 expected_devices = device_list.GetPersistentDeviceList(
301 os.path.join(options.out_dir, device_list.LAST_DEVICES_FILENAME)) 297 os.path.join(options.out_dir, device_list.LAST_DEVICES_FILENAME))
302 except IOError: 298 except IOError:
303 expected_devices = [] 299 expected_devices = []
304 devices = android_commands.GetAttachedDevices() 300 devices = android_commands.GetAttachedDevices()
305 # Only restart usb if devices are missing. 301 # Only restart usb if devices are missing.
306 if set(expected_devices) != set(devices): 302 if set(expected_devices) != set(devices):
307 print 'expected_devices: %s, devices: %s' % (expected_devices, devices) 303 logging.warning('expected_devices: %s', expected_devices)
304 logging.warning('devices: %s', devices)
308 KillAllAdb() 305 KillAllAdb()
309 retries = 5 306 retries = 5
310 usb_restarted = True 307 usb_restarted = True
311 if options.restart_usb: 308 if options.restart_usb:
312 if not RestartUsb(): 309 if not RestartUsb():
313 usb_restarted = False 310 usb_restarted = False
314 bb_annotations.PrintWarning() 311 bb_annotations.PrintWarning()
315 print 'USB reset stage failed, wait for any device to come back.' 312 logging.error('USB reset stage failed, '
313 'wait for any device to come back.')
316 while retries: 314 while retries:
317 print 'retry adb devices...' 315 logging.info('retry adb devices...')
318 time.sleep(1) 316 time.sleep(1)
319 devices = android_commands.GetAttachedDevices() 317 devices = android_commands.GetAttachedDevices()
320 if set(expected_devices) == set(devices): 318 if set(expected_devices) == set(devices):
321 # All devices are online, keep going. 319 # All devices are online, keep going.
322 break 320 break
323 if not usb_restarted and devices: 321 if not usb_restarted and devices:
324 # The USB wasn't restarted, but there's at least one device online. 322 # The USB wasn't restarted, but there's at least one device online.
325 # No point in trying to wait for all devices. 323 # No point in trying to wait for all devices.
326 break 324 break
327 retries -= 1 325 retries -= 1
328 326
329 # TODO(navabi): Test to make sure this fails and then fix call 327 # TODO(navabi): Test to make sure this fails and then fix call
330 offline_devices = android_commands.GetAttachedDevices( 328 offline_devices = android_commands.GetAttachedDevices(
331 hardware=False, emulator=False, offline=True) 329 hardware=False, emulator=False, offline=True)
332 330
333 types, builds, batteries, reports, errors, json_data = [], [], [], [], [], [] 331 types, builds, batteries, errors, devices_ok, json_data = (
334 fail_step_lst = [] 332 [], [], [], [], [], [])
335 if devices: 333 if devices:
336 types, builds, batteries, reports, errors, fail_step_lst, json_data = ( 334 types, builds, batteries, errors, devices_ok, json_data = (
337 zip(*[DeviceInfo(dev, options) for dev in devices])) 335 zip(*[DeviceInfo(dev, options) for dev in devices]))
338 336
339 # Write device info to file for buildbot info display. 337 # Write device info to file for buildbot info display.
340 if os.path.exists('/home/chrome-bot'): 338 if os.path.exists('/home/chrome-bot'):
341 with open('/home/chrome-bot/.adb_device_info', 'w') as f: 339 with open('/home/chrome-bot/.adb_device_info', 'w') as f:
342 for device in json_data: 340 for device in json_data:
343 try: 341 try:
344 f.write('%s %s %s %.1fC %s%%\n' % (device['serial'], device['type'], 342 f.write('%s %s %s %.1fC %s%%\n' % (device['serial'], device['type'],
345 device['build'], float(device['battery']['temperature']) / 10, 343 device['build'], float(device['battery']['temperature']) / 10,
346 device['battery']['level'])) 344 device['battery']['level']))
347 except Exception: 345 except Exception:
348 pass 346 pass
349 347
350 err_msg = CheckForMissingDevices(options, devices) or [] 348 err_msg = CheckForMissingDevices(options, devices) or []
351 349
352 unique_types = list(set(types)) 350 unique_types = list(set(types))
353 unique_builds = list(set(builds)) 351 unique_builds = list(set(builds))
354 352
355 bb_annotations.PrintMsg('Online devices: %d. Device types %s, builds %s' 353 bb_annotations.PrintMsg('Online devices: %d. Device types %s, builds %s'
356 % (len(devices), unique_types, unique_builds)) 354 % (len(devices), unique_types, unique_builds))
357 print '\n'.join(reports) 355
356 for j in json_data:
357 logging.info('Device %s (%s)', j.get('serial'), j.get('type'))
358 logging.info(' Build: %s (%s)', j.get('build'), j.get('build_detail'))
359 logging.info(' Current Battery Service state:')
360 for k, v in j.get('battery', {}).iteritems():
361 logging.info(' %s: %s', k, v)
362 logging.info(' IMEI slice: %s', j.get('imei_slice'))
363 logging.info(' WiFi IP: %s', j.get('wifi_ip'))
364
358 365
359 for serial, dev_errors in zip(devices, errors): 366 for serial, dev_errors in zip(devices, errors):
360 if dev_errors: 367 if dev_errors:
361 err_msg += ['%s errors:' % serial] 368 err_msg += ['%s errors:' % serial]
362 err_msg += [' %s' % error for error in dev_errors] 369 err_msg += [' %s' % error for error in dev_errors]
363 370
364 if err_msg: 371 if err_msg:
365 bb_annotations.PrintWarning() 372 bb_annotations.PrintWarning()
366 msg = '\n'.join(err_msg) 373 for e in err_msg:
367 print msg 374 logging.error(e)
368 from_address = 'buildbot@chromium.org' 375 from_address = 'buildbot@chromium.org'
369 to_addresses = ['chromium-android-device-alerts@google.com'] 376 to_addresses = ['chromium-android-device-alerts@google.com']
370 bot_name = os.environ.get('BUILDBOT_BUILDERNAME') 377 bot_name = os.environ.get('BUILDBOT_BUILDERNAME')
371 slave_name = os.environ.get('BUILDBOT_SLAVENAME') 378 slave_name = os.environ.get('BUILDBOT_SLAVENAME')
372 subject = 'Device status check errors on %s, %s.' % (slave_name, bot_name) 379 subject = 'Device status check errors on %s, %s.' % (slave_name, bot_name)
373 SendEmail(from_address, to_addresses, [], subject, msg) 380 SendEmail(from_address, to_addresses, [], subject, '\n'.join(err_msg))
374 381
375 if options.device_status_dashboard: 382 if options.device_status_dashboard:
376 perf_tests_results_helper.PrintPerfResult('BotDevices', 'OnlineDevices', 383 perf_tests_results_helper.PrintPerfResult('BotDevices', 'OnlineDevices',
377 [len(devices)], 'devices') 384 [len(devices)], 'devices')
378 perf_tests_results_helper.PrintPerfResult('BotDevices', 'OfflineDevices', 385 perf_tests_results_helper.PrintPerfResult('BotDevices', 'OfflineDevices',
379 [len(offline_devices)], 'devices', 386 [len(offline_devices)], 'devices',
380 'unimportant') 387 'unimportant')
381 for serial, battery in zip(devices, batteries): 388 for serial, battery in zip(devices, batteries):
382 perf_tests_results_helper.PrintPerfResult('DeviceBattery', serial, 389 perf_tests_results_helper.PrintPerfResult('DeviceBattery', serial,
383 [battery], '%', 390 [battery], '%',
384 'unimportant') 391 'unimportant')
385 392
386 if options.json_output: 393 if options.json_output:
387 with open(options.json_output, 'wb') as f: 394 with open(options.json_output, 'wb') as f:
388 f.write(json.dumps(json_data, indent=4)) 395 f.write(json.dumps(json_data, indent=4))
389 396
390 num_failed_devs = 0 397 num_failed_devs = 0
391 for fail_status, device in zip(fail_step_lst, devices): 398 for device_ok, device in zip(devices_ok, devices):
392 if not fail_status: 399 if not device_ok:
400 logging.warning('Blacklisting %s', str(device))
393 device_blacklist.ExtendBlacklist([str(device)]) 401 device_blacklist.ExtendBlacklist([str(device)])
394 num_failed_devs += 1 402 num_failed_devs += 1
395 403
396 if num_failed_devs == len(devices): 404 if num_failed_devs == len(devices):
397 return 2 405 return 2
398 406
399 if not devices: 407 if not devices:
400 return 1 408 return 1
401 409
402 410
403 if __name__ == '__main__': 411 if __name__ == '__main__':
404 sys.exit(main()) 412 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698