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 |