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

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

Issue 351603002: [Android] Unit tests for DeviceUtils. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 6 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
« no previous file with comments | « no previous file | build/android/pylib/device/decorators.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 # pylint: disable-all 9 # pylint: disable-all
10 10
(...skipping 21 matching lines...) Expand all
32 except ImportError: 32 except ImportError:
33 pexpect = None 33 pexpect = None
34 34
35 sys.path.append(os.path.join( 35 sys.path.append(os.path.join(
36 constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner')) 36 constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner'))
37 import adb_interface 37 import adb_interface
38 import am_instrument_parser 38 import am_instrument_parser
39 import errors 39 import errors
40 40
41 from pylib.device import device_blacklist 41 from pylib.device import device_blacklist
42 from pylib.device import device_errors
42 43
43 # Pattern to search for the next whole line of pexpect output and capture it 44 # Pattern to search for the next whole line of pexpect output and capture it
44 # into a match group. We can't use ^ and $ for line start end with pexpect, 45 # into a match group. We can't use ^ and $ for line start end with pexpect,
45 # see http://www.noah.org/python/pexpect/#doc for explanation why. 46 # see http://www.noah.org/python/pexpect/#doc for explanation why.
46 PEXPECT_LINE_RE = re.compile('\n([^\r]*)\r') 47 PEXPECT_LINE_RE = re.compile('\n([^\r]*)\r')
47 48
48 # Set the adb shell prompt to be a unique marker that will [hopefully] not 49 # Set the adb shell prompt to be a unique marker that will [hopefully] not
49 # appear at the start of any line of a command's output. 50 # appear at the start of any line of a command's output.
50 SHELL_PROMPT = '~+~PQ\x17RS~+~' 51 SHELL_PROMPT = '~+~PQ\x17RS~+~'
51 52
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 self._adb.SendCommand('wait-for-device') 381 self._adb.SendCommand('wait-for-device')
381 return return_value 382 return return_value
382 383
383 def GetDeviceYear(self): 384 def GetDeviceYear(self):
384 """Returns the year information of the date on device.""" 385 """Returns the year information of the date on device."""
385 return self.RunShellCommand('date +%Y')[0] 386 return self.RunShellCommand('date +%Y')[0]
386 387
387 def GetExternalStorage(self): 388 def GetExternalStorage(self):
388 if not self._external_storage: 389 if not self._external_storage:
389 self._external_storage = self.RunShellCommand('echo $EXTERNAL_STORAGE')[0] 390 self._external_storage = self.RunShellCommand('echo $EXTERNAL_STORAGE')[0]
390 assert self._external_storage, 'Unable to find $EXTERNAL_STORAGE' 391 if not self._external_storage:
392 raise device_errors.CommandFailedError(
393 ['shell', "'echo $EXTERNAL_STORAGE'"],
394 'Unable to find $EXTERNAL_STORAGE')
391 return self._external_storage 395 return self._external_storage
392 396
393 def WaitForDevicePm(self): 397 def WaitForDevicePm(self):
394 """Blocks until the device's package manager is available. 398 """Blocks until the device's package manager is available.
395 399
396 To workaround http://b/5201039, we restart the shell and retry if the 400 To workaround http://b/5201039, we restart the shell and retry if the
397 package manager isn't back after 120 seconds. 401 package manager isn't back after 120 seconds.
398 402
399 Raises: 403 Raises:
400 errors.WaitForResponseTimedOutError after max retries reached. 404 errors.WaitForResponseTimedOutError after max retries reached.
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 output = self.RunShellCommand('ls ' + external_storage) 645 output = self.RunShellCommand('ls ' + external_storage)
642 if output: 646 if output:
643 sdcard_ready = True 647 sdcard_ready = True
644 else: 648 else:
645 time.sleep(wait_period) 649 time.sleep(wait_period)
646 attempts += 1 650 attempts += 1
647 if not sdcard_ready: 651 if not sdcard_ready:
648 raise errors.WaitForResponseTimedOutError( 652 raise errors.WaitForResponseTimedOutError(
649 'SD card not ready after %s seconds' % timeout_time) 653 'SD card not ready after %s seconds' % timeout_time)
650 654
651 def _CheckCommandIsValid(self, command):
652 """Raises a ValueError if the command is not valid."""
653
654 # A dict of commands the user should not run directly and a mapping to the
655 # API they should use instead.
656 preferred_apis = {
657 'getprop': 'system_properties[<PROPERTY>]',
658 'setprop': 'system_properties[<PROPERTY>]',
659 }
660
661 # A dict of commands to methods that may call them.
662 whitelisted_callers = {
663 'getprop': 'ProvisionDevices',
664 }
665
666 base_command = shlex.split(command)[0].strip(';')
667 if (base_command in preferred_apis and
668 (base_command not in whitelisted_callers or
669 whitelisted_callers[base_command] not in [
670 f[3] for f in inspect.stack()])):
671 error_msg = ('%s should not be run directly. Instead use: %s' %
672 (base_command, preferred_apis[base_command]))
673 raise ValueError(error_msg)
674
675 def GetAndroidToolStatusAndOutput(self, command, lib_path=None, *args, **kw): 655 def GetAndroidToolStatusAndOutput(self, command, lib_path=None, *args, **kw):
676 """Runs a native Android binary, wrapping the command as necessary. 656 """Runs a native Android binary, wrapping the command as necessary.
677 657
678 This is a specialization of GetShellCommandStatusAndOutput, which is meant 658 This is a specialization of GetShellCommandStatusAndOutput, which is meant
679 for running tools/android/ binaries and handle properly: (1) setting the 659 for running tools/android/ binaries and handle properly: (1) setting the
680 lib path (for component=shared_library), (2) using the PIE wrapper on ICS. 660 lib path (for component=shared_library), (2) using the PIE wrapper on ICS.
681 See crbug.com/373219 for more context. 661 See crbug.com/373219 for more context.
682 662
683 Args: 663 Args:
684 command: String containing the command to send. 664 command: String containing the command to send.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 command: String containing the shell command to send. Must not include 697 command: String containing the shell command to send. Must not include
718 the single quotes as we use them to escape the whole command. 698 the single quotes as we use them to escape the whole command.
719 timeout_time: Number of seconds to wait for command to respond before 699 timeout_time: Number of seconds to wait for command to respond before
720 retrying, used by AdbInterface.SendShellCommand. 700 retrying, used by AdbInterface.SendShellCommand.
721 log_result: Boolean to indicate whether we should log the result of the 701 log_result: Boolean to indicate whether we should log the result of the
722 shell command. 702 shell command.
723 703
724 Returns: 704 Returns:
725 list containing the lines of output received from running the command 705 list containing the lines of output received from running the command
726 """ 706 """
727 self._CheckCommandIsValid(command)
728 self._LogShell(command) 707 self._LogShell(command)
729 if "'" in command: 708 if "'" in command:
730 logging.warning(command + " contains ' quotes") 709 logging.warning(command + " contains ' quotes")
731 result = self._adb.SendShellCommand( 710 result = self._adb.SendShellCommand(
732 "'%s'" % command, timeout_time).splitlines() 711 "'%s'" % command, timeout_time).splitlines()
733 # TODO(b.kelemen): we should really be able to drop the stderr of the 712 # TODO(b.kelemen): we should really be able to drop the stderr of the
734 # command or raise an exception based on what the caller wants. 713 # command or raise an exception based on what the caller wants.
735 result = [ l for l in result if not l.startswith('WARNING') ] 714 result = [ l for l in result if not l.startswith('WARNING') ]
736 if ['error: device not found'] == result: 715 if ['error: device not found'] == result:
737 raise errors.DeviceUnresponsiveError('device not found') 716 raise errors.DeviceUnresponsiveError('device not found')
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1897 dest: absolute path of destination directory 1876 dest: absolute path of destination directory
1898 """ 1877 """
1899 logging.info('In EfficientDeviceDirectoryCopy %s %s', source, dest) 1878 logging.info('In EfficientDeviceDirectoryCopy %s %s', source, dest)
1900 with DeviceTempFile(self, suffix=".sh") as temp_script_file: 1879 with DeviceTempFile(self, suffix=".sh") as temp_script_file:
1901 host_script_path = os.path.join(constants.DIR_SOURCE_ROOT, 1880 host_script_path = os.path.join(constants.DIR_SOURCE_ROOT,
1902 'build', 1881 'build',
1903 'android', 1882 'android',
1904 'pylib', 1883 'pylib',
1905 'efficient_android_directory_copy.sh') 1884 'efficient_android_directory_copy.sh')
1906 self._adb.Push(host_script_path, temp_script_file.name) 1885 self._adb.Push(host_script_path, temp_script_file.name)
1907 self.EnableAdbRoot
1908 out = self.RunShellCommand( 1886 out = self.RunShellCommand(
1909 'sh %s %s %s' % (temp_script_file.name, source, dest), 1887 'sh %s %s %s' % (temp_script_file.name, source, dest),
1910 timeout_time=120) 1888 timeout_time=120)
1911 if self._device: 1889 if self._device:
1912 device_repr = self._device[-4:] 1890 device_repr = self._device[-4:]
1913 else: 1891 else:
1914 device_repr = '????' 1892 device_repr = '????'
1915 for line in out: 1893 for line in out:
1916 logging.info('[%s]> %s', device_repr, line) 1894 logging.info('[%s]> %s', device_repr, line)
1917 1895
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1983 """ 1961 """
1984 def __init__(self, output): 1962 def __init__(self, output):
1985 self._output = output 1963 self._output = output
1986 1964
1987 def write(self, data): 1965 def write(self, data):
1988 data = data.replace('\r\r\n', '\n') 1966 data = data.replace('\r\r\n', '\n')
1989 self._output.write(data) 1967 self._output.write(data)
1990 1968
1991 def flush(self): 1969 def flush(self):
1992 self._output.flush() 1970 self._output.flush()
OLDNEW
« no previous file with comments | « no previous file | build/android/pylib/device/decorators.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698