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

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

Issue 19968004: Reimplement device status check dashboard option. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove exlicit call to default emulator=True. Created 7 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | build/android/pylib/android_commands.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 logging 8 import logging
9 import optparse 9 import optparse
10 import os 10 import os
11 import smtplib 11 import smtplib
12 import sys 12 import sys
13 import re 13 import re
14 14
15 import bb_annotations 15 import bb_annotations
16 16
17 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) 17 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
18 from pylib import android_commands 18 from pylib import android_commands
19 from pylib import constants 19 from pylib import constants
20 from pylib import perf_tests_helper
20 from pylib.cmd_helper import GetCmdOutput 21 from pylib.cmd_helper import GetCmdOutput
21 22
22 23
23 def DeviceInfo(serial, options): 24 def DeviceInfo(serial, options):
24 """Gathers info on a device via various adb calls. 25 """Gathers info on a device via various adb calls.
25 26
26 Args: 27 Args:
27 serial: The serial of the attached device to construct info about. 28 serial: The serial of the attached device to construct info about.
28 29
29 Returns: 30 Returns:
30 Tuple of device type, build id, report as a string, error messages, and 31 Tuple of device type, build id, report as a string, error messages, and
31 boolean indicating whether or not device can be used for testing. 32 boolean indicating whether or not device can be used for testing.
32 """ 33 """
33 34
34 def AdbShellCmd(cmd):
35 return GetCmdOutput('adb -s %s shell %s' % (serial, cmd),
36 shell=True).strip()
37
38 device_adb = android_commands.AndroidCommands(serial) 35 device_adb = android_commands.AndroidCommands(serial)
39 36
40 # TODO(navabi): Replace AdbShellCmd with device_adb. 37 # TODO(navabi): Replace AdbShellCmd with device_adb.
41 device_type = AdbShellCmd('getprop ro.build.product') 38 device_type = device_adb.GetBuildProduct()
42 device_build = AdbShellCmd('getprop ro.build.id') 39 device_build = device_adb.GetBuildId()
43 device_build_type = AdbShellCmd('getprop ro.build.type') 40 device_build_type = device_adb.GetBuildType()
44 device_product_name = AdbShellCmd('getprop ro.product.name') 41 device_product_name = device_adb.GetProductName()
45 42
46 setup_wizard_disabled = AdbShellCmd( 43 setup_wizard_disabled = device_adb.GetSetupWizardStatus() == 'DISABLED'
47 'getprop ro.setupwizard.mode') == 'DISABLED' 44 battery = device_adb.GetBatteryInfo()
48 battery = AdbShellCmd('dumpsys battery')
49 install_output = GetCmdOutput( 45 install_output = GetCmdOutput(
50 ['%s/build/android/adb_install_apk.py' % constants.DIR_SOURCE_ROOT, '--apk', 46 ['%s/build/android/adb_install_apk.py' % constants.DIR_SOURCE_ROOT, '--apk',
51 '%s/build/android/CheckInstallApk-debug.apk' % constants.DIR_SOURCE_ROOT]) 47 '%s/build/android/CheckInstallApk-debug.apk' % constants.DIR_SOURCE_ROOT])
52 install_speed_found = re.findall('(\d+) KB/s', install_output) 48 install_speed_found = re.findall('(\d+) KB/s', install_output)
53 if install_speed_found: 49 if install_speed_found:
54 install_speed = int(install_speed_found[0]) 50 install_speed = int(install_speed_found[0])
55 else: 51 else:
56 install_speed = 'Unknown' 52 install_speed = 'Unknown'
57 if 'Error' in battery: 53 if 'Error' in battery:
58 ac_power = 'Unknown' 54 ac_power = 'Unknown'
59 battery_level = 'Unknown' 55 battery_level = 'Unknown'
60 battery_temp = 'Unknown' 56 battery_temp = 'Unknown'
61 else: 57 else:
62 ac_power = re.findall('AC powered: (\w+)', battery)[0] 58 ac_power = re.findall('AC powered: (\w+)', battery)[0]
63 battery_level = int(re.findall('level: (\d+)', battery)[0]) 59 battery_level = int(re.findall('level: (\d+)', battery)[0])
64 battery_temp = float(re.findall('temperature: (\d+)', battery)[0]) / 10 60 battery_temp = float(re.findall('temperature: (\d+)', battery)[0]) / 10
61 sub_info = device_adb.GetSubscriberInfo()
62 imei_slice = re.findall('Device ID = (\d+)', sub_info)[0][-6:]
65 report = ['Device %s (%s)' % (serial, device_type), 63 report = ['Device %s (%s)' % (serial, device_type),
66 ' Build: %s (%s)' % (device_build, 64 ' Build: %s (%s)' %
67 AdbShellCmd('getprop ro.build.fingerprint')), 65 (device_build, device_adb.GetBuildFingerprint()),
68 ' Battery: %s%%' % battery_level, 66 ' Battery: %s%%' % battery_level,
69 ' Battery temp: %s' % battery_temp, 67 ' Battery temp: %s' % battery_temp,
70 ' IMEI slice: %s' % AdbShellCmd('dumpsys iphonesubinfo ' 68 ' IMEI slice: %s' % imei_slice,
71 '| grep Device' 69 ' Wifi IP: %s' % device_adb.GetWifiIP(),
72 "| awk '{print $4}'")[-6:],
73 ' Wifi IP: %s' % AdbShellCmd('getprop dhcp.wlan0.ipaddress'),
74 ' Install Speed: %s KB/s' % install_speed, 70 ' Install Speed: %s KB/s' % install_speed,
75 ''] 71 '']
76 72
77 errors = [] 73 errors = []
78 if battery_level < 15: 74 if battery_level < 15:
79 errors += ['Device critically low in battery. Turning off device.'] 75 errors += ['Device critically low in battery. Turning off device.']
80 if (not setup_wizard_disabled and device_build_type != 'user' and 76 if (not setup_wizard_disabled and device_build_type != 'user' and
81 not options.no_provisioning_check): 77 not options.no_provisioning_check):
82 errors += ['Setup wizard not disabled. Was it provisioned correctly?'] 78 errors += ['Setup wizard not disabled. Was it provisioned correctly?']
83 if device_product_name == 'mantaray' and ac_power != 'true': 79 if device_product_name == 'mantaray' and ac_power != 'true':
84 errors += ['Mantaray device not connected to AC power.'] 80 errors += ['Mantaray device not connected to AC power.']
85 # TODO(navabi): Insert warning once we have a better handle of what install 81 # TODO(navabi): Insert warning once we have a better handle of what install
86 # speeds to expect. The following lines were causing too many alerts. 82 # speeds to expect. The following lines were causing too many alerts.
87 # if install_speed < 500: 83 # if install_speed < 500:
88 # errors += ['Device install speed too low. Do not use for testing.'] 84 # errors += ['Device install speed too low. Do not use for testing.']
89 85
90 # Causing the device status check step fail for slow install speed or low 86 # Causing the device status check step fail for slow install speed or low
91 # battery currently is too disruptive to the bots (especially try bots). 87 # battery currently is too disruptive to the bots (especially try bots).
92 # Turn off devices with low battery and the step does not fail. 88 # Turn off devices with low battery and the step does not fail.
93 if battery_level < 15: 89 if battery_level < 15:
94 device_adb.EnableAdbRoot() 90 device_adb.EnableAdbRoot()
95 AdbShellCmd('reboot -p') 91 device_adb.Shutdown()
96 return device_type, device_build, '\n'.join(report), errors, True 92 full_report = '\n'.join(report)
93 return device_type, device_build, battery_level, full_report, errors, True
97 94
98 95
99 def CheckForMissingDevices(options, adb_online_devs): 96 def CheckForMissingDevices(options, adb_online_devs):
100 """Uses file of previous online devices to detect broken phones. 97 """Uses file of previous online devices to detect broken phones.
101 98
102 Args: 99 Args:
103 options: out_dir parameter of options argument is used as the base 100 options: out_dir parameter of options argument is used as the base
104 directory to load and update the cache file. 101 directory to load and update the cache file.
105 adb_online_devs: A list of serial numbers of the currently visible 102 adb_online_devs: A list of serial numbers of the currently visible
106 and online attached devices. 103 and online attached devices.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 print 'Failed to send alert email. Error: %s' % e 179 print 'Failed to send alert email. Error: %s' % e
183 180
184 181
185 def main(): 182 def main():
186 parser = optparse.OptionParser() 183 parser = optparse.OptionParser()
187 parser.add_option('', '--out-dir', 184 parser.add_option('', '--out-dir',
188 help='Directory where the device path is stored', 185 help='Directory where the device path is stored',
189 default=os.path.join(constants.DIR_SOURCE_ROOT, 'out')) 186 default=os.path.join(constants.DIR_SOURCE_ROOT, 'out'))
190 parser.add_option('--no-provisioning-check', 187 parser.add_option('--no-provisioning-check',
191 help='Will not check if devices are provisioned properly.') 188 help='Will not check if devices are provisioned properly.')
192 189 parser.add_option('--device-status-dashboard',
190 help='Output device status data for dashboard.')
193 options, args = parser.parse_args() 191 options, args = parser.parse_args()
194 if args: 192 if args:
195 parser.error('Unknown options %s' % args) 193 parser.error('Unknown options %s' % args)
196 devices = android_commands.GetAttachedDevices() 194 devices = android_commands.GetAttachedDevices()
197 types, builds, reports, errors = [], [], [], [] 195 # TODO(navabi): Test to make sure this fails and then fix call
196 offline_devices = android_commands.GetAttachedDevices(hardware=False,
197 emulator=False,
198 offline=True)
199
200 types, builds, batteries, reports, errors = [], [], [], [], []
198 fail_step_lst = [] 201 fail_step_lst = []
199 if devices: 202 if devices:
200 types, builds, reports, errors, fail_step_lst = ( 203 types, builds, batteries, reports, errors, fail_step_lst = (
201 zip(*[DeviceInfo(dev, options) for dev in devices])) 204 zip(*[DeviceInfo(dev, options) for dev in devices]))
202 205
203 err_msg = CheckForMissingDevices(options, devices) or [] 206 err_msg = CheckForMissingDevices(options, devices) or []
204 207
205 unique_types = list(set(types)) 208 unique_types = list(set(types))
206 unique_builds = list(set(builds)) 209 unique_builds = list(set(builds))
207 210
208 bb_annotations.PrintMsg('Online devices: %d. Device types %s, builds %s' 211 bb_annotations.PrintMsg('Online devices: %d. Device types %s, builds %s'
209 % (len(devices), unique_types, unique_builds)) 212 % (len(devices), unique_types, unique_builds))
210 print '\n'.join(reports) 213 print '\n'.join(reports)
211 214
212 for serial, dev_errors in zip(devices, errors): 215 for serial, dev_errors in zip(devices, errors):
213 if dev_errors: 216 if dev_errors:
214 err_msg += ['%s errors:' % serial] 217 err_msg += ['%s errors:' % serial]
215 err_msg += [' %s' % error for error in dev_errors] 218 err_msg += [' %s' % error for error in dev_errors]
216 219
217 if err_msg: 220 if err_msg:
218 bb_annotations.PrintWarning() 221 bb_annotations.PrintWarning()
219 msg = '\n'.join(err_msg) 222 msg = '\n'.join(err_msg)
220 print msg 223 print msg
221 SendDeviceStatusAlert(msg) 224 SendDeviceStatusAlert(msg)
222 225
226 if options.device_status_dashboard:
227 perf_tests_helper.PrintPerfResult('BotDevices', 'OnlineDevices',
228 [len(devices)], 'devices')
229 perf_tests_helper.PrintPerfResult('BotDevices', 'OfflineDevices',
230 [len(offline_devices)], 'devices',
231 'unimportant')
232 for serial, battery in zip(devices, batteries):
233 perf_tests_helper.PrintPerfResult('DeviceBattery', serial, [battery], '%',
234 'unimportant')
235
223 if False in fail_step_lst: 236 if False in fail_step_lst:
224 # TODO(navabi): Build fails on device status check step if there exists any 237 # TODO(navabi): Build fails on device status check step if there exists any
225 # devices with critically low battery or install speed. Remove those devices 238 # devices with critically low battery or install speed. Remove those devices
226 # from testing, allowing build to continue with good devices. 239 # from testing, allowing build to continue with good devices.
227 return 1 240 return 1
228 241
229 if not devices: 242 if not devices:
230 return 1 243 return 1
231 244
232 245
233 if __name__ == '__main__': 246 if __name__ == '__main__':
234 sys.exit(main()) 247 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | build/android/pylib/android_commands.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698