OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 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 """Provisions Android devices with settings required for bots. | 7 """Provisions Android devices with settings required for bots. |
8 | 8 |
9 Usage: | 9 Usage: |
10 ./provision_devices.py [-d <device serial number>] | 10 ./provision_devices.py [-d <device serial number>] |
11 """ | 11 """ |
12 | 12 |
13 import argparse | 13 import argparse |
14 import datetime | 14 import datetime |
15 import json | 15 import json |
16 import logging | 16 import logging |
17 import os | 17 import os |
18 import posixpath | 18 import posixpath |
19 import random | |
19 import re | 20 import re |
20 import subprocess | 21 import subprocess |
21 import sys | 22 import sys |
22 import time | 23 import time |
23 | 24 |
24 from devil.android import battery_utils | 25 from devil.android import battery_utils |
25 from devil.android import device_blacklist | 26 from devil.android import device_blacklist |
26 from devil.android import device_errors | 27 from devil.android import device_errors |
27 from devil.android import device_utils | 28 from devil.android import device_utils |
28 from devil.android.sdk import version_codes | 29 from devil.android.sdk import version_codes |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 device.WaitUntilFullyBooted(timeout=reboot_timeout, retries=0) | 93 device.WaitUntilFullyBooted(timeout=reboot_timeout, retries=0) |
93 except device_errors.CommandTimeoutError: | 94 except device_errors.CommandTimeoutError: |
94 logging.error('Device did not finish booting. Will try to reboot.') | 95 logging.error('Device did not finish booting. Will try to reboot.') |
95 device.Reboot(timeout=reboot_timeout) | 96 device.Reboot(timeout=reboot_timeout) |
96 phase_func(device, options) | 97 phase_func(device, options) |
97 if reboot: | 98 if reboot: |
98 device.Reboot(False, retries=0) | 99 device.Reboot(False, retries=0) |
99 device.adb.WaitForDevice() | 100 device.adb.WaitForDevice() |
100 | 101 |
101 try: | 102 try: |
103 CheckExternalStorage(device) | |
102 if should_run_phase(_PHASES.WIPE): | 104 if should_run_phase(_PHASES.WIPE): |
103 if options.chrome_specific_wipe: | 105 if options.chrome_specific_wipe: |
104 run_phase(WipeChromeData) | 106 run_phase(WipeChromeData) |
105 else: | 107 else: |
106 run_phase(WipeDevice) | 108 run_phase(WipeDevice) |
107 | 109 |
108 if should_run_phase(_PHASES.PROPERTIES): | 110 if should_run_phase(_PHASES.PROPERTIES): |
109 run_phase(SetProperties) | 111 run_phase(SetProperties) |
110 | 112 |
111 if should_run_phase(_PHASES.FINISH): | 113 if should_run_phase(_PHASES.FINISH): |
112 run_phase(FinishProvisioning, reboot=False) | 114 run_phase(FinishProvisioning, reboot=False) |
113 | 115 |
114 if options.chrome_specific_wipe: | 116 if options.chrome_specific_wipe: |
115 package = "com.google.android.gms" | 117 package = "com.google.android.gms" |
116 version_name = device.GetApplicationVersion(package) | 118 version_name = device.GetApplicationVersion(package) |
117 logging.info("Version name for %s is %s", package, version_name) | 119 logging.info("Version name for %s is %s", package, version_name) |
118 | 120 |
119 except device_errors.CommandTimeoutError: | 121 except device_errors.CommandTimeoutError: |
120 logging.exception('Timed out waiting for device %s. Adding to blacklist.', | 122 logging.exception('Timed out waiting for device %s. Adding to blacklist.', |
121 str(device)) | 123 str(device)) |
122 blacklist.Extend([str(device)]) | 124 blacklist.Extend([str(device)]) |
123 | 125 |
124 except device_errors.CommandFailedError: | 126 except device_errors.CommandFailedError: |
125 logging.exception('Failed to provision device %s. Adding to blacklist.', | 127 logging.exception('Failed to provision device %s. Adding to blacklist.', |
126 str(device)) | 128 str(device)) |
127 blacklist.Extend([str(device)]) | 129 blacklist.Extend([str(device)]) |
128 | 130 |
131 def CheckExternalStorage(device): | |
132 """Checks that storage is writable and if not makes it writable. | |
133 | |
134 Arguments: | |
135 device: The device to check. | |
136 """ | |
137 # Write a file with random name to $EXTERNAL_STORAGE to test writability. | |
jbudorick
2015/09/28 18:01:17
Use DeviceTempFile with dir=device.GetExternalStor
rnephew (Reviews Here)
2015/09/28 18:34:06
Done.
| |
138 file_path = ( | |
139 device.GetExternalStoragePath() + '/' + str(random.randint(0, 9999999))) | |
140 try: | |
141 device.WriteFile(file_path, 'test') | |
142 except device_errors.CommandFailedError: | |
143 logging.info('External storage not writable. Remounting / as RW') | |
144 device.RunShellCommand(['mount', '-o', 'remount,rw', '/'], | |
145 check_return=True, as_root=True) | |
146 device.WriteFile(file_path, 'test') | |
147 finally: | |
148 device.RunShellCommand(['rm', file_path], check_return=True) | |
129 | 149 |
130 def WipeChromeData(device, options): | 150 def WipeChromeData(device, options): |
131 """Wipes chrome specific data from device | 151 """Wipes chrome specific data from device |
132 | 152 |
133 (1) uninstall any app whose name matches *chrom*, except | 153 (1) uninstall any app whose name matches *chrom*, except |
134 com.android.chrome, which is the chrome stable package. Doing so also | 154 com.android.chrome, which is the chrome stable package. Doing so also |
135 removes the corresponding dirs under /data/data/ and /data/app/ | 155 removes the corresponding dirs under /data/data/ and /data/app/ |
136 (2) remove any dir under /data/app-lib/ whose name matches *chrom* | 156 (2) remove any dir under /data/app-lib/ whose name matches *chrom* |
137 (3) remove any files under /data/tombstones/ whose name matches "tombstone*" | 157 (3) remove any files under /data/tombstones/ whose name matches "tombstone*" |
138 (4) remove /data/local.prop if there is any | 158 (4) remove /data/local.prop if there is any |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
385 | 405 |
386 | 406 |
387 def _LaunchHostHeartbeat(): | 407 def _LaunchHostHeartbeat(): |
388 # Kill if existing host_heartbeat | 408 # Kill if existing host_heartbeat |
389 KillHostHeartbeat() | 409 KillHostHeartbeat() |
390 # Launch a new host_heartbeat | 410 # Launch a new host_heartbeat |
391 logging.info('Spawning host heartbeat...') | 411 logging.info('Spawning host heartbeat...') |
392 subprocess.Popen([os.path.join(constants.DIR_SOURCE_ROOT, | 412 subprocess.Popen([os.path.join(constants.DIR_SOURCE_ROOT, |
393 'build/android/host_heartbeat.py')]) | 413 'build/android/host_heartbeat.py')]) |
394 | 414 |
395 | |
396 def KillHostHeartbeat(): | 415 def KillHostHeartbeat(): |
397 ps = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE) | 416 ps = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE) |
398 stdout, _ = ps.communicate() | 417 stdout, _ = ps.communicate() |
399 matches = re.findall('\\n.*host_heartbeat.*', stdout) | 418 matches = re.findall('\\n.*host_heartbeat.*', stdout) |
400 for match in matches: | 419 for match in matches: |
401 logging.info('An instance of host heart beart running... will kill') | 420 logging.info('An instance of host heart beart running... will kill') |
402 pid = re.findall(r'(\S+)', match)[1] | 421 pid = re.findall(r'(\S+)', match)[1] |
403 subprocess.call(['kill', str(pid)]) | 422 subprocess.call(['kill', str(pid)]) |
404 | 423 |
405 | |
406 def main(): | 424 def main(): |
407 # Recommended options on perf bots: | 425 # Recommended options on perf bots: |
408 # --disable-network | 426 # --disable-network |
409 # TODO(tonyg): We eventually want network on. However, currently radios | 427 # TODO(tonyg): We eventually want network on. However, currently radios |
410 # can cause perfbots to drain faster than they charge. | 428 # can cause perfbots to drain faster than they charge. |
411 # --min-battery-level 95 | 429 # --min-battery-level 95 |
412 # Some perf bots run benchmarks with USB charging disabled which leads | 430 # Some perf bots run benchmarks with USB charging disabled which leads |
413 # to gradual draining of the battery. We must wait for a full charge | 431 # to gradual draining of the battery. We must wait for a full charge |
414 # before starting a run in order to keep the devices online. | 432 # before starting a run in order to keep the devices online. |
415 | 433 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
463 args = parser.parse_args() | 481 args = parser.parse_args() |
464 constants.SetBuildType(args.target) | 482 constants.SetBuildType(args.target) |
465 | 483 |
466 run_tests_helper.SetLogLevel(args.verbose) | 484 run_tests_helper.SetLogLevel(args.verbose) |
467 | 485 |
468 return ProvisionDevices(args) | 486 return ProvisionDevices(args) |
469 | 487 |
470 | 488 |
471 if __name__ == '__main__': | 489 if __name__ == '__main__': |
472 sys.exit(main()) | 490 sys.exit(main()) |
OLD | NEW |