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 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 from pylib import android_commands |
15 from pylib import buildbot_report | 16 from pylib import buildbot_report |
16 from pylib import android_commands | 17 from pylib import constants |
17 from pylib.cmd_helper import GetCmdOutput | 18 from pylib.cmd_helper import GetCmdOutput |
18 | 19 |
19 | 20 |
20 def DeviceInfo(serial): | 21 def DeviceInfo(serial): |
21 """Gathers info on a device via various adb calls. | 22 """Gathers info on a device via various adb calls. |
22 | 23 |
23 Args: | 24 Args: |
24 serial: The serial of the attached device to construct info about. | 25 serial: The serial of the attached device to construct info about. |
25 | 26 |
26 Returns: | 27 Returns: |
27 Tuple of device type, build id, report as a string, error messages, and | 28 Tuple of device type, build id, report as a string, error messages, and |
28 boolean indicating whether or not device can be used for testing. | 29 boolean indicating whether or not device can be used for testing. |
29 """ | 30 """ |
30 | 31 |
31 def AdbShellCmd(cmd): | 32 def AdbShellCmd(cmd): |
32 return GetCmdOutput('adb -s %s shell %s' % (serial, cmd), | 33 return GetCmdOutput('adb -s %s shell %s' % (serial, cmd), |
33 shell=True).strip() | 34 shell=True).strip() |
34 | 35 |
35 device_type = AdbShellCmd('getprop ro.build.product') | 36 device_type = AdbShellCmd('getprop ro.build.product') |
36 device_build = AdbShellCmd('getprop ro.build.id') | 37 device_build = AdbShellCmd('getprop ro.build.id') |
37 device_product_name = AdbShellCmd('getprop ro.product.name') | 38 device_product_name = AdbShellCmd('getprop ro.product.name') |
38 | 39 |
39 setup_wizard_disabled = AdbShellCmd( | 40 setup_wizard_disabled = AdbShellCmd( |
40 'getprop ro.setupwizard.mode') == 'DISABLED' | 41 'getprop ro.setupwizard.mode') == 'DISABLED' |
41 battery = AdbShellCmd('dumpsys battery') | 42 battery = AdbShellCmd('dumpsys battery') |
42 install_output = GetCmdOutput(['build/android/adb_install_apk.py', '--apk', | 43 install_output = GetCmdOutput( |
43 'build/android/CheckInstallApk-debug.apk']) | 44 ['%s/build/android/adb_install_apk.py' % constants.CHROME_DIR, '--apk', |
| 45 '%s/build/android/CheckInstallApk-debug.apk' % constants.CHROME_DIR]) |
44 install_speed_found = re.findall('(\d+) KB/s', install_output) | 46 install_speed_found = re.findall('(\d+) KB/s', install_output) |
45 if install_speed_found: | 47 if install_speed_found: |
46 install_speed = int(install_speed_found[0]) | 48 install_speed = int(install_speed_found[0]) |
47 else: | 49 else: |
48 install_speed = 'Unknown' | 50 install_speed = 'Unknown' |
49 if 'Error' in battery: | 51 if 'Error' in battery: |
50 ac_power = 'Unknown' | 52 ac_power = 'Unknown' |
51 battery_level = 'Unknown' | 53 battery_level = 'Unknown' |
52 battery_temp = 'Unknown' | 54 battery_temp = 'Unknown' |
53 else: | 55 else: |
54 ac_power = re.findall('AC powered: (\w+)', battery)[0] | 56 ac_power = re.findall('AC powered: (\w+)', battery)[0] |
55 battery_level = int(re.findall('level: (\d+)', battery)[0]) | 57 battery_level = int(re.findall('level: (\d+)', battery)[0]) |
56 battery_temp = float(re.findall('temperature: (\d+)', battery)[0]) / 10 | 58 battery_temp = float(re.findall('temperature: (\d+)', battery)[0]) / 10 |
57 report = ['Device %s (%s)' % (serial, device_type), | 59 report = ['Device %s (%s)' % (serial, device_type), |
58 ' Build: %s (%s)' % (device_build, | 60 ' Build: %s (%s)' % (device_build, |
59 AdbShellCmd('getprop ro.build.fingerprint')), | 61 AdbShellCmd('getprop ro.build.fingerprint')), |
60 ' Battery: %s%%' % battery_level, | 62 ' Battery: %s%%' % battery_level, |
61 ' Battery temp: %s' % battery_temp, | 63 ' Battery temp: %s' % battery_temp, |
62 ' IMEI slice: %s' % AdbShellCmd('dumpsys iphonesubinfo ' | 64 ' IMEI slice: %s' % AdbShellCmd('dumpsys iphonesubinfo ' |
63 '| grep Device' | 65 '| grep Device' |
64 "| awk '{print $4}'")[-6:], | 66 "| awk '{print $4}'")[-6:], |
65 ' Wifi IP: %s' % AdbShellCmd('getprop dhcp.wlan0.ipaddress'), | 67 ' Wifi IP: %s' % AdbShellCmd('getprop dhcp.wlan0.ipaddress'), |
66 ' Install Speed: %s KB/s' % install_speed, | 68 ' Install Speed: %s KB/s' % install_speed, |
67 ''] | 69 ''] |
68 | 70 |
69 errors = [] | 71 errors = [] |
70 if battery_level < 5: | 72 if battery_level < 15: |
71 errors += ['Device critically low in battery. Do not use for testing.'] | 73 errors += ['Device critically low in battery. Do not use for testing.'] |
72 if not setup_wizard_disabled: | 74 if not setup_wizard_disabled: |
73 errors += ['Setup wizard not disabled. Was it provisioned correctly?'] | 75 errors += ['Setup wizard not disabled. Was it provisioned correctly?'] |
74 if device_product_name == 'mantaray' and ac_power != 'true': | 76 if device_product_name == 'mantaray' and ac_power != 'true': |
75 errors += ['Mantaray device not connected to AC power.'] | 77 errors += ['Mantaray device not connected to AC power.'] |
76 if install_speed < 800: | 78 # TODO(navabi): Insert warning once we have a better handle of what install |
77 errors += ['Device install speed too low. Do not use for testing.'] | 79 # speeds to expect. The following lines were causing too many alerts. |
| 80 # if install_speed < 500: |
| 81 # errors += ['Device install speed too low. Do not use for testing.'] |
78 | 82 |
79 # TODO(navabi): Determine if device status check step should fail on slow | 83 # TODO(navabi): Determine if device status check step should fail on slow |
80 # install speed. The original CL caused the step to fail but was reverted | 84 # install speed. The original CL caused the step to fail but was reverted |
81 # because it caused too many early failures. Determine if it was just flake. | 85 # because it caused too many early failures. Determine if it was just flake. |
82 # Also, do not fail on 'Unknown' caused by offline device, because other | 86 # Also, do not fail on 'Unknown' caused by offline device, because other |
83 # devices can still be used for tests. | 87 # devices can still be used for tests. |
84 fail_step = (battery_level == 'Unknown' or battery_level >= 5) | 88 fail_step = (battery_level == 'Unknown' or battery_level >= 15) |
85 return device_type, device_build, '\n'.join(report), errors, fail_step | 89 return device_type, device_build, '\n'.join(report), errors, fail_step |
86 | 90 |
87 | 91 |
88 def CheckForMissingDevices(options, adb_online_devs): | 92 def CheckForMissingDevices(options, adb_online_devs): |
89 """Uses file of previous online devices to detect broken phones. | 93 """Uses file of previous online devices to detect broken phones. |
90 | 94 |
91 Args: | 95 Args: |
92 options: out_dir parameter of options argument is used as the base | 96 options: out_dir parameter of options argument is used as the base |
93 directory to load and update the cache file. | 97 directory to load and update the cache file. |
94 adb_online_devs: A list of serial numbers of the currently visible | 98 adb_online_devs: A list of serial numbers of the currently visible |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 parser.add_option('', '--out-dir', | 180 parser.add_option('', '--out-dir', |
177 help='Directory where the device path is stored', | 181 help='Directory where the device path is stored', |
178 default=os.path.join(os.path.dirname(__file__), '..', | 182 default=os.path.join(os.path.dirname(__file__), '..', |
179 '..', 'out')) | 183 '..', 'out')) |
180 | 184 |
181 options, args = parser.parse_args() | 185 options, args = parser.parse_args() |
182 if args: | 186 if args: |
183 parser.error('Unknown options %s' % args) | 187 parser.error('Unknown options %s' % args) |
184 devices = android_commands.GetAttachedDevices() | 188 devices = android_commands.GetAttachedDevices() |
185 types, builds, reports, errors = [], [], [], [] | 189 types, builds, reports, errors = [], [], [], [] |
| 190 fail_step_lst = [] |
186 if devices: | 191 if devices: |
187 types, builds, reports, errors, fail_step_lst = zip(*[DeviceInfo(dev) | 192 types, builds, reports, errors, fail_step_lst = zip(*[DeviceInfo(dev) |
188 for dev in devices]) | 193 for dev in devices]) |
189 | 194 |
190 err_msg = CheckForMissingDevices(options, devices) or [] | 195 err_msg = CheckForMissingDevices(options, devices) or [] |
191 | 196 |
192 unique_types = list(set(types)) | 197 unique_types = list(set(types)) |
193 unique_builds = list(set(builds)) | 198 unique_builds = list(set(builds)) |
194 | 199 |
195 buildbot_report.PrintMsg('Online devices: %d. Device types %s, builds %s' | 200 buildbot_report.PrintMsg('Online devices: %d. Device types %s, builds %s' |
(...skipping 16 matching lines...) Expand all Loading... |
212 # devices with critically low battery or install speed. Remove those devices | 217 # devices with critically low battery or install speed. Remove those devices |
213 # from testing, allowing build to continue with good devices. | 218 # from testing, allowing build to continue with good devices. |
214 return 1 | 219 return 1 |
215 | 220 |
216 if not devices: | 221 if not devices: |
217 return 1 | 222 return 1 |
218 | 223 |
219 | 224 |
220 if __name__ == '__main__': | 225 if __name__ == '__main__': |
221 sys.exit(main()) | 226 sys.exit(main()) |
OLD | NEW |