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 logging | 8 import logging |
9 import optparse | 9 import optparse |
10 import os | 10 import os |
11 import psutil | 11 import psutil |
| 12 import re |
12 import signal | 13 import signal |
13 import smtplib | 14 import smtplib |
14 import subprocess | 15 import subprocess |
15 import sys | 16 import sys |
16 import re | 17 import time |
17 import urllib | 18 import urllib |
18 | 19 |
19 import bb_annotations | 20 import bb_annotations |
20 import bb_utils | 21 import bb_utils |
21 | 22 |
22 sys.path.append(os.path.join(os.path.dirname(__file__), | 23 sys.path.append(os.path.join(os.path.dirname(__file__), |
23 os.pardir, os.pardir, 'util', 'lib', | 24 os.pardir, os.pardir, 'util', 'lib', |
24 'common')) | 25 'common')) |
25 import perf_tests_results_helper # pylint: disable=F0401 | 26 import perf_tests_results_helper # pylint: disable=F0401 |
26 | 27 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 # Causing the device status check step fail for slow install speed or low | 105 # Causing the device status check step fail for slow install speed or low |
105 # battery currently is too disruptive to the bots (especially try bots). | 106 # battery currently is too disruptive to the bots (especially try bots). |
106 # Turn off devices with low battery and the step does not fail. | 107 # Turn off devices with low battery and the step does not fail. |
107 if battery_level < 15: | 108 if battery_level < 15: |
108 device_adb.EnableAdbRoot() | 109 device_adb.EnableAdbRoot() |
109 device_adb.Shutdown() | 110 device_adb.Shutdown() |
110 full_report = '\n'.join(report) | 111 full_report = '\n'.join(report) |
111 return device_type, device_build, battery_level, full_report, errors, True | 112 return device_type, device_build, battery_level, full_report, errors, True |
112 | 113 |
113 | 114 |
| 115 def GetLastDevices(out_dir): |
| 116 """Returns a list of devices that have been seen on the bot. |
| 117 |
| 118 Args: |
| 119 options: out_dir parameter of options argument is used as the base |
| 120 directory to load and update the cache file. |
| 121 |
| 122 Returns: List of device serial numbers that were on the bot. |
| 123 """ |
| 124 devices_path = os.path.join(out_dir, '.last_devices') |
| 125 devices = [] |
| 126 try: |
| 127 with open(devices_path) as f: |
| 128 devices = f.read().splitlines() |
| 129 except IOError: |
| 130 # Ignore error, file might not exist |
| 131 pass |
| 132 return devices |
| 133 |
| 134 |
114 def CheckForMissingDevices(options, adb_online_devs): | 135 def CheckForMissingDevices(options, adb_online_devs): |
115 """Uses file of previous online devices to detect broken phones. | 136 """Uses file of previous online devices to detect broken phones. |
116 | 137 |
117 Args: | 138 Args: |
118 options: out_dir parameter of options argument is used as the base | 139 options: out_dir parameter of options argument is used as the base |
119 directory to load and update the cache file. | 140 directory to load and update the cache file. |
120 adb_online_devs: A list of serial numbers of the currently visible | 141 adb_online_devs: A list of serial numbers of the currently visible |
121 and online attached devices. | 142 and online attached devices. |
122 """ | 143 """ |
123 # TODO(navabi): remove this once the bug that causes different number | 144 # TODO(navabi): remove this once the bug that causes different number |
124 # of devices to be detected between calls is fixed. | 145 # of devices to be detected between calls is fixed. |
125 logger = logging.getLogger() | 146 logger = logging.getLogger() |
126 logger.setLevel(logging.INFO) | 147 logger.setLevel(logging.INFO) |
127 | 148 |
128 out_dir = os.path.abspath(options.out_dir) | 149 out_dir = os.path.abspath(options.out_dir) |
129 | 150 |
130 def ReadDeviceList(file_name): | |
131 devices_path = os.path.join(out_dir, file_name) | |
132 devices = [] | |
133 try: | |
134 with open(devices_path) as f: | |
135 devices = f.read().splitlines() | |
136 except IOError: | |
137 # Ignore error, file might not exist | |
138 pass | |
139 return devices | |
140 | |
141 def WriteDeviceList(file_name, device_list): | 151 def WriteDeviceList(file_name, device_list): |
142 path = os.path.join(out_dir, file_name) | 152 path = os.path.join(out_dir, file_name) |
143 if not os.path.exists(out_dir): | 153 if not os.path.exists(out_dir): |
144 os.makedirs(out_dir) | 154 os.makedirs(out_dir) |
145 with open(path, 'w') as f: | 155 with open(path, 'w') as f: |
146 # Write devices currently visible plus devices previously seen. | 156 # Write devices currently visible plus devices previously seen. |
147 f.write('\n'.join(set(device_list))) | 157 f.write('\n'.join(set(device_list))) |
148 | 158 |
149 last_devices_path = os.path.join(out_dir, '.last_devices') | 159 last_devices_path = os.path.join(out_dir, '.last_devices') |
150 last_devices = ReadDeviceList('.last_devices') | 160 last_devices = GetLastDevices(out_dir) |
151 missing_devs = list(set(last_devices) - set(adb_online_devs)) | 161 missing_devs = list(set(last_devices) - set(adb_online_devs)) |
152 | 162 |
153 all_known_devices = list(set(adb_online_devs) | set(last_devices)) | 163 all_known_devices = list(set(adb_online_devs) | set(last_devices)) |
154 WriteDeviceList('.last_devices', all_known_devices) | 164 WriteDeviceList('.last_devices', all_known_devices) |
155 WriteDeviceList('.last_missing', missing_devs) | 165 WriteDeviceList('.last_missing', missing_devs) |
156 | 166 |
157 if not all_known_devices: | 167 if not all_known_devices: |
158 # This can happen if for some reason the .last_devices file is not | 168 # This can happen if for some reason the .last_devices file is not |
159 # present or if it was empty. | 169 # present or if it was empty. |
160 return ['No online devices. Have any devices been plugged in?'] | 170 return ['No online devices. Have any devices been plugged in?'] |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 help='Will not check if devices are provisioned properly.') | 280 help='Will not check if devices are provisioned properly.') |
271 parser.add_option('--device-status-dashboard', action='store_true', | 281 parser.add_option('--device-status-dashboard', action='store_true', |
272 help='Output device status data for dashboard.') | 282 help='Output device status data for dashboard.') |
273 parser.add_option('--restart-usb', action='store_true', | 283 parser.add_option('--restart-usb', action='store_true', |
274 help='Restart USB ports before running device check.') | 284 help='Restart USB ports before running device check.') |
275 options, args = parser.parse_args() | 285 options, args = parser.parse_args() |
276 if args: | 286 if args: |
277 parser.error('Unknown options %s' % args) | 287 parser.error('Unknown options %s' % args) |
278 | 288 |
279 if options.restart_usb: | 289 if options.restart_usb: |
280 KillAllAdb() | 290 expected_devices = GetLastDevices(os.path.abspath(options.out_dir)) |
281 rc = RestartUsb() | 291 devices = android_commands.GetAttachedDevices() |
282 if rc: | 292 # Only restart usb if devices are missing |
283 return 1 | 293 if set(expected_devices) != set(devices): |
| 294 KillAllAdb() |
| 295 if RestartUsb(): |
| 296 return 1 |
| 297 retries = 5 |
| 298 while retries: |
| 299 time.sleep(1) |
| 300 devices = android_commands.GetAttachedDevices() |
| 301 if set(expected_devices) == set(devices): |
| 302 break |
| 303 retries -= 1 |
284 | 304 |
285 devices = android_commands.GetAttachedDevices() | 305 devices = android_commands.GetAttachedDevices() |
286 # TODO(navabi): Test to make sure this fails and then fix call | 306 # TODO(navabi): Test to make sure this fails and then fix call |
287 offline_devices = android_commands.GetAttachedDevices(hardware=False, | 307 offline_devices = android_commands.GetAttachedDevices(hardware=False, |
288 emulator=False, | 308 emulator=False, |
289 offline=True) | 309 offline=True) |
290 | 310 |
291 types, builds, batteries, reports, errors = [], [], [], [], [] | 311 types, builds, batteries, reports, errors = [], [], [], [], [] |
292 fail_step_lst = [] | 312 fail_step_lst = [] |
293 if devices: | 313 if devices: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 # devices with critically low battery or install speed. Remove those devices | 350 # devices with critically low battery or install speed. Remove those devices |
331 # from testing, allowing build to continue with good devices. | 351 # from testing, allowing build to continue with good devices. |
332 return 1 | 352 return 1 |
333 | 353 |
334 if not devices: | 354 if not devices: |
335 return 1 | 355 return 1 |
336 | 356 |
337 | 357 |
338 if __name__ == '__main__': | 358 if __name__ == '__main__': |
339 sys.exit(main()) | 359 sys.exit(main()) |
OLD | NEW |