Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 764 build_id = self.RunShellCommand('getprop ro.build.id')[0] | 764 build_id = self.RunShellCommand('getprop ro.build.id')[0] |
| 765 assert build_id | 765 assert build_id |
| 766 return build_id | 766 return build_id |
| 767 | 767 |
| 768 def GetBuildType(self): | 768 def GetBuildType(self): |
| 769 """Returns the build type of the system (e.g. eng).""" | 769 """Returns the build type of the system (e.g. eng).""" |
| 770 build_type = self.RunShellCommand('getprop ro.build.type')[0] | 770 build_type = self.RunShellCommand('getprop ro.build.type')[0] |
| 771 assert build_type | 771 assert build_type |
| 772 return build_type | 772 return build_type |
| 773 | 773 |
| 774 def StartMonitoringLogcat(self, clear=True, timeout=10, logfile=None, | 774 def StartMonitoringLogcat(self, clear=True, logfile=None, filters=None): |
| 775 filters=None): | |
| 776 """Starts monitoring the output of logcat, for use with WaitForLogMatch. | 775 """Starts monitoring the output of logcat, for use with WaitForLogMatch. |
| 777 | 776 |
| 778 Args: | 777 Args: |
| 779 clear: If True the existing logcat output will be cleared, to avoiding | 778 clear: If True the existing logcat output will be cleared, to avoiding |
| 780 matching historical output lurking in the log. | 779 matching historical output lurking in the log. |
| 781 timeout: How long WaitForLogMatch will wait for the given match | |
| 782 filters: A list of logcat filters to be used. | 780 filters: A list of logcat filters to be used. |
| 783 """ | 781 """ |
| 784 if clear: | 782 if clear: |
| 785 self.RunShellCommand('logcat -c') | 783 self.RunShellCommand('logcat -c') |
| 786 args = [] | 784 args = [] |
| 787 if self._adb._target_arg: | 785 if self._adb._target_arg: |
| 788 args += shlex.split(self._adb._target_arg) | 786 args += shlex.split(self._adb._target_arg) |
| 789 args += ['logcat', '-v', 'threadtime'] | 787 args += ['logcat', '-v', 'threadtime'] |
| 790 if filters: | 788 if filters: |
| 791 args.extend(filters) | 789 args.extend(filters) |
| 792 else: | 790 else: |
| 793 args.append('*:v') | 791 args.append('*:v') |
| 794 | 792 |
| 795 if logfile: | 793 if logfile: |
| 796 logfile = NewLineNormalizer(logfile) | 794 logfile = NewLineNormalizer(logfile) |
| 797 | 795 |
| 798 # Spawn logcat and syncronize with it. | 796 # Spawn logcat and syncronize with it. |
| 799 for _ in range(4): | 797 for _ in range(4): |
| 800 self._logcat = pexpect.spawn('adb', args, timeout=timeout, | 798 self._logcat = pexpect.spawn('adb', args, timeout=10, logfile=logfile) |
| 801 logfile=logfile) | |
| 802 self.RunShellCommand('log startup_sync') | 799 self.RunShellCommand('log startup_sync') |
| 803 if self._logcat.expect(['startup_sync', pexpect.EOF, | 800 if self._logcat.expect(['startup_sync', pexpect.EOF, |
| 804 pexpect.TIMEOUT]) == 0: | 801 pexpect.TIMEOUT]) == 0: |
| 805 break | 802 break |
| 806 self._logcat.close(force=True) | 803 self._logcat.close(force=True) |
| 807 else: | 804 else: |
| 808 logging.critical('Error reading from logcat: ' + str(self._logcat.match)) | 805 logging.critical('Error reading from logcat: ' + str(self._logcat.match)) |
| 809 sys.exit(1) | 806 sys.exit(1) |
| 810 | 807 |
| 811 def GetMonitoredLogCat(self): | 808 def GetMonitoredLogCat(self): |
| 812 """Returns an "adb logcat" command as created by pexpected.spawn.""" | 809 """Returns an "adb logcat" command as created by pexpected.spawn.""" |
| 813 if not self._logcat: | 810 if not self._logcat: |
| 814 self.StartMonitoringLogcat(clear=False) | 811 self.StartMonitoringLogcat(clear=False) |
| 815 return self._logcat | 812 return self._logcat |
| 816 | 813 |
| 817 def WaitForLogMatch(self, success_re, error_re, clear=False, timeout=10): | 814 def WaitForLogMatch(self, success_re, error_re, clear=False, timeout=10): |
| 818 """Blocks until a matching line is logged or a timeout occurs. | 815 """Blocks until a matching line is logged or a timeout occurs. |
| 819 | 816 |
| 820 Args: | 817 Args: |
| 821 success_re: A compiled re to search each line for. | 818 success_re: A compiled re to search each line for. |
| 822 error_re: A compiled re which, if found, terminates the search for | 819 error_re: A compiled re which, if found, terminates the search for |
| 823 |success_re|. If None is given, no error condition will be detected. | 820 |success_re|. If None is given, no error condition will be detected. |
|
frankf
2013/01/22 18:34:22
Make this an optional param?
bulach
2013/02/04 11:21:24
hmm, making an optional param in the middle is kin
| |
| 824 clear: If True the existing logcat output will be cleared, defaults to | 821 clear: If True the existing logcat output will be cleared, defaults to |
| 825 false. | 822 false. |
| 826 | 823 |
| 827 Raises: | 824 Raises: |
| 828 pexpect.TIMEOUT upon the timeout specified by StartMonitoringLogcat(). | 825 pexpect.TIMEOUT upon the timeout specified by StartMonitoringLogcat(). |
|
Sami
2013/01/22 02:36:37
Also here :)
bulach
2013/01/22 02:40:58
the other one took care of it :)
as soon as that o
| |
| 829 | 826 |
| 830 Returns: | 827 Returns: |
| 831 The re match object if |success_re| is matched first or None if |error_re| | 828 The re match object if |success_re| is matched first or None if |error_re| |
| 832 is matched first. | 829 is matched first. |
| 833 """ | 830 """ |
| 834 logging.info('<<< Waiting for logcat:' + str(success_re.pattern)) | 831 logging.info('<<< Waiting for logcat:' + str(success_re.pattern)) |
| 835 t0 = time.time() | 832 t0 = time.time() |
| 836 while True: | 833 while True: |
| 837 if not self._logcat: | 834 if not self._logcat: |
| 838 self.StartMonitoringLogcat(clear, timeout=timeout) | 835 self.StartMonitoringLogcat(clear) |
| 839 try: | 836 try: |
| 840 while True: | 837 while True: |
| 841 # Note this will block for upto the timeout _per log line_, so we need | 838 # Note this will block for upto the timeout _per log line_, so we need |
| 842 # to calculate the overall timeout remaining since t0. | 839 # to calculate the overall timeout remaining since t0. |
| 843 time_remaining = t0 + self._logcat.timeout - time.time() | 840 time_remaining = t0 + self._logcat.timeout - time.time() |
| 844 if time_remaining < 0: raise pexpect.TIMEOUT(self._logcat) | 841 if time_remaining < 0: raise pexpect.TIMEOUT(self._logcat) |
| 845 self._logcat.expect(PEXPECT_LINE_RE, timeout=time_remaining) | 842 self._logcat.expect(PEXPECT_LINE_RE, timeout=time_remaining) |
| 846 line = self._logcat.match.group(1) | 843 line = self._logcat.match.group(1) |
| 847 if error_re: | 844 if error_re: |
| 848 error_match = error_re.search(line) | 845 error_match = error_re.search(line) |
| 849 if error_match: | 846 if error_match: |
| 850 return None | 847 return None |
| 851 success_match = success_re.search(line) | 848 success_match = success_re.search(line) |
| 852 if success_match: | 849 if success_match: |
| 853 return success_match | 850 return success_match |
| 854 logging.info('<<< Skipped Logcat Line:' + str(line)) | 851 logging.info('<<< Skipped Logcat Line:' + str(line)) |
| 855 except pexpect.TIMEOUT: | 852 except pexpect.TIMEOUT: |
| 856 raise pexpect.TIMEOUT( | 853 raise pexpect.TIMEOUT( |
| 857 'Timeout (%ds) exceeded waiting for pattern "%s" (tip: use -vv ' | 854 'Timeout (%ds) exceeded waiting for pattern "%s" (tip: use -vv ' |
| 858 'to debug)' % | 855 'to debug)' % |
| 859 (self._logcat.timeout, success_re.pattern)) | 856 (self._logcat.timeout, success_re.pattern)) |
|
aberent
2013/01/29 13:25:08
I think the timeout here should be "timeout", not
bulach
2013/02/04 11:21:24
thanks! your patch took care of it.. :)
| |
| 860 except pexpect.EOF: | 857 except pexpect.EOF: |
| 861 # It seems that sometimes logcat can end unexpectedly. This seems | 858 # It seems that sometimes logcat can end unexpectedly. This seems |
| 862 # to happen during Chrome startup after a reboot followed by a cache | 859 # to happen during Chrome startup after a reboot followed by a cache |
| 863 # clean. I don't understand why this happens, but this code deals with | 860 # clean. I don't understand why this happens, but this code deals with |
| 864 # getting EOF in logcat. | 861 # getting EOF in logcat. |
| 865 logging.critical('Found EOF in adb logcat. Restarting...') | 862 logging.critical('Found EOF in adb logcat. Restarting...') |
| 866 # Rerun spawn with original arguments. Note that self._logcat.args[0] is | 863 # Rerun spawn with original arguments. Note that self._logcat.args[0] is |
| 867 # the path of adb, so we don't want it in the arguments. | 864 # the path of adb, so we don't want it in the arguments. |
| 868 self._logcat = pexpect.spawn('adb', | 865 self._logcat = pexpect.spawn('adb', |
| 869 self._logcat.args[1:], | 866 self._logcat.args[1:], |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1146 """ | 1143 """ |
| 1147 def __init__(self, output): | 1144 def __init__(self, output): |
| 1148 self._output = output | 1145 self._output = output |
| 1149 | 1146 |
| 1150 def write(self, data): | 1147 def write(self, data): |
| 1151 data = data.replace('\r\r\n', '\n') | 1148 data = data.replace('\r\r\n', '\n') |
| 1152 self._output.write(data) | 1149 self._output.write(data) |
| 1153 | 1150 |
| 1154 def flush(self): | 1151 def flush(self): |
| 1155 self._output.flush() | 1152 self._output.flush() |
| OLD | NEW |