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

Side by Side Diff: build/android/pylib/android_commands.py

Issue 11232037: Retry tests on other bots if the device is unresponsive/offline (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: changes according to bulach's comments Created 8 years, 2 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/base_test_sharder.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 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Provides an interface to communicate with the device via the adb command. 5 """Provides an interface to communicate with the device via the adb command.
6 6
7 Assumes adb binary is currently on system path. 7 Assumes adb binary is currently on system path.
8 """ 8 """
9 9
10 import collections 10 import collections
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 emulator-5554 offline 100 emulator-5554 offline
101 """ 101 """
102 re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE) 102 re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE)
103 devices = re_device.findall(cmd_helper.GetCmdOutput(['adb', 'devices'])) 103 devices = re_device.findall(cmd_helper.GetCmdOutput(['adb', 'devices']))
104 preferred_device = os.environ.get('ANDROID_SERIAL') 104 preferred_device = os.environ.get('ANDROID_SERIAL')
105 if preferred_device in devices: 105 if preferred_device in devices:
106 devices.remove(preferred_device) 106 devices.remove(preferred_device)
107 devices.insert(0, preferred_device) 107 devices.insert(0, preferred_device)
108 return devices 108 return devices
109 109
110 def IsDeviceAttached(device):
Isaac (away) 2012/10/24 17:33:12 We can simplify this to: def IsDeviceAttached(dev
yongsheng 2012/10/25 01:20:06 yes, that's good. I'll change it.
111 devices = GetAttachedDevices()
112 if device in devices:
113 return True
114 return False
115
110 def _GetFilesFromRecursiveLsOutput(path, ls_output, re_file, utc_offset=None): 116 def _GetFilesFromRecursiveLsOutput(path, ls_output, re_file, utc_offset=None):
111 """Gets a list of files from `ls` command output. 117 """Gets a list of files from `ls` command output.
112 118
113 Python's os.walk isn't used because it doesn't work over adb shell. 119 Python's os.walk isn't used because it doesn't work over adb shell.
114 120
115 Args: 121 Args:
116 path: The path to list. 122 path: The path to list.
117 ls_output: A list of lines returned by an `ls -lR` command. 123 ls_output: A list of lines returned by an `ls -lR` command.
118 re_file: A compiled regular expression which parses a line into named groups 124 re_file: A compiled regular expression which parses a line into named groups
119 consisting of at minimum "filename", "date", "time", "size" and 125 consisting of at minimum "filename", "date", "time", "size" and
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 195
190 Args: 196 Args:
191 device: If given, adb commands are only send to the device of this ID. 197 device: If given, adb commands are only send to the device of this ID.
192 Otherwise commands are sent to all attached devices. 198 Otherwise commands are sent to all attached devices.
193 """ 199 """
194 200
195 def __init__(self, device=None): 201 def __init__(self, device=None):
196 self._adb = adb_interface.AdbInterface() 202 self._adb = adb_interface.AdbInterface()
197 if device: 203 if device:
198 self._adb.SetTargetSerial(device) 204 self._adb.SetTargetSerial(device)
205 self._device = device
199 self._logcat = None 206 self._logcat = None
200 self.logcat_process = None 207 self.logcat_process = None
201 self._pushed_files = [] 208 self._pushed_files = []
202 self._device_utc_offset = self.RunShellCommand('date +%z')[0] 209 self._device_utc_offset = self.RunShellCommand('date +%z')[0]
203 self._md5sum_path = '' 210 self._md5sum_path = ''
204 self._external_storage = '' 211 self._external_storage = ''
205 212
206 def Adb(self): 213 def Adb(self):
207 """Returns our AdbInterface to avoid us wrapping all its methods.""" 214 """Returns our AdbInterface to avoid us wrapping all its methods."""
208 return self._adb 215 return self._adb
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 def FileExistsOnDevice(self, file_name): 1040 def FileExistsOnDevice(self, file_name):
1034 """Checks whether the given file exists on the device. 1041 """Checks whether the given file exists on the device.
1035 1042
1036 Args: 1043 Args:
1037 file_name: Full path of file to check. 1044 file_name: Full path of file to check.
1038 1045
1039 Returns: 1046 Returns:
1040 True if the file exists, False otherwise. 1047 True if the file exists, False otherwise.
1041 """ 1048 """
1042 assert '"' not in file_name, 'file_name cannot contain double quotes' 1049 assert '"' not in file_name, 'file_name cannot contain double quotes'
1043 status = self._adb.SendShellCommand( 1050 try:
1044 '\'test -e "%s"; echo $?\'' % (file_name)) 1051 status = self._adb.SendShellCommand(
1045 if 'test: not found' not in status: 1052 '\'test -e "%s"; echo $?\'' % (file_name))
1053 if 'test: not found' not in status:
1054 return int(status) == 0
1055
1056 status = self._adb.SendShellCommand(
1057 '\'ls "%s" >/dev/null 2>&1; echo $?\'' % (file_name))
1046 return int(status) == 0 1058 return int(status) == 0
1059 except ValueError:
1060 if IsDeviceAttached(self._device):
1061 raise errors.DeviceUnresponsiveError('Device may be offline.')
1047 1062
1048 status = self._adb.SendShellCommand( 1063 return False
1049 '\'ls "%s" >/dev/null 2>&1; echo $?\'' % (file_name))
1050 return int(status) == 0
1051 1064
1052 1065
1053 class NewLineNormalizer(object): 1066 class NewLineNormalizer(object):
1054 """A file-like object to normalize EOLs to '\n'. 1067 """A file-like object to normalize EOLs to '\n'.
1055 1068
1056 Pexpect runs adb within a pseudo-tty device (see 1069 Pexpect runs adb within a pseudo-tty device (see
1057 http://www.noah.org/wiki/pexpect), so any '\n' printed by adb is written 1070 http://www.noah.org/wiki/pexpect), so any '\n' printed by adb is written
1058 as '\r\n' to the logfile. Since adb already uses '\r\n' to terminate 1071 as '\r\n' to the logfile. Since adb already uses '\r\n' to terminate
1059 lines, the log ends up having '\r\r\n' at the end of each line. This 1072 lines, the log ends up having '\r\r\n' at the end of each line. This
1060 filter replaces the above with a single '\n' in the data stream. 1073 filter replaces the above with a single '\n' in the data stream.
1061 """ 1074 """
1062 def __init__(self, output): 1075 def __init__(self, output):
1063 self._output = output 1076 self._output = output
1064 1077
1065 def write(self, data): 1078 def write(self, data):
1066 data = data.replace('\r\r\n', '\n') 1079 data = data.replace('\r\r\n', '\n')
1067 self._output.write(data) 1080 self._output.write(data)
1068 1081
1069 def flush(self): 1082 def flush(self):
1070 self._output.flush() 1083 self._output.flush()
1071 1084
OLDNEW
« no previous file with comments | « no previous file | build/android/pylib/base_test_sharder.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698