OLD | NEW |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 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 # pylint: disable=unused-argument | 5 # pylint: disable=unused-argument |
6 | 6 |
7 import collections | 7 import collections |
8 import itertools | 8 import itertools |
9 import logging | 9 import logging |
10 import subprocess | 10 import subprocess |
11 import tempfile | 11 import tempfile |
12 import time | 12 import time |
13 import re | 13 import re |
14 | 14 |
15 from pylib.device import adb_wrapper | 15 from pylib.device import adb_wrapper |
16 from pylib.device import decorators | 16 from pylib.device import decorators |
17 from pylib.device import device_errors | 17 from pylib.device import device_errors |
18 | 18 |
19 | 19 |
20 class LogcatMonitor(object): | 20 class LogcatMonitor(object): |
21 | 21 |
22 # Format: <DATE> <TIME> <PID> <TID> <LEVEL> <COMPONENT>: <MESSAGE> | 22 # Format: <DATE> <TIME> <PID> <TID> <LEVEL> <COMPONENT>: <MESSAGE> |
23 _THREADTIME_RE_FORMAT = r'\S* +\S* +(%s) +(%s) +(%s) +(%s): +(%s)$' | 23 _THREADTIME_RE_FORMAT = r'\S* +\S* +(%s) +(%s) +(%s) +(%s): +(%s)$' |
24 | 24 |
25 def __init__(self, adb, clear=True, filter_specs=None): | 25 def __init__(self, adb, clear=True): |
26 """Create a LogcatMonitor instance. | 26 """Create a LogcatMonitor instance. |
27 | 27 |
28 Args: | 28 Args: |
29 adb: An instance of adb_wrapper.AdbWrapper. | 29 adb: An instance of adb_wrapper.AdbWrapper. |
30 clear: If True, clear the logcat when monitoring starts. | 30 clear: If True, clear the logcat when monitoring starts. |
31 filter_specs: An optional list of '<tag>[:priority]' strings. | |
32 """ | 31 """ |
33 if isinstance(adb, adb_wrapper.AdbWrapper): | 32 if isinstance(adb, adb_wrapper.AdbWrapper): |
34 self._adb = adb | 33 self._adb = adb |
35 else: | 34 else: |
36 raise ValueError('Unsupported type passed for argument "device"') | 35 raise ValueError('Unsupported type passed for argument "device"') |
37 self._clear = clear | 36 self._clear = clear |
38 self._filter_specs = filter_specs | |
39 self._logcat_out = None | 37 self._logcat_out = None |
40 self._logcat_out_file = None | 38 self._logcat_out_file = None |
41 self._logcat_proc = None | 39 self._logcat_proc = None |
42 | 40 |
43 @decorators.WithTimeoutAndRetriesDefaults(10, 0) | 41 @decorators.WithTimeoutAndRetriesDefaults(10, 0) |
44 def WaitFor(self, success_regex, failure_regex=None, timeout=None, | 42 def WaitFor(self, success_regex, failure_regex=None, timeout=None, |
45 retries=None): | 43 retries=None): |
46 """Wait for a matching logcat line or until a timeout occurs. | 44 """Wait for a matching logcat line or until a timeout occurs. |
47 | 45 |
48 This will attempt to match lines in the logcat against both |success_regex| | 46 This will attempt to match lines in the logcat against both |success_regex| |
(...skipping 22 matching lines...) Expand all Loading... |
71 if isinstance(failure_regex, basestring): | 69 if isinstance(failure_regex, basestring): |
72 failure_regex = re.compile(failure_regex) | 70 failure_regex = re.compile(failure_regex) |
73 | 71 |
74 logging.debug('Waiting %d seconds for "%s"', timeout, success_regex.pattern) | 72 logging.debug('Waiting %d seconds for "%s"', timeout, success_regex.pattern) |
75 | 73 |
76 # NOTE This will continue looping until: | 74 # NOTE This will continue looping until: |
77 # - success_regex matches a line, in which case the match object is | 75 # - success_regex matches a line, in which case the match object is |
78 # returned. | 76 # returned. |
79 # - failure_regex matches a line, in which case None is returned | 77 # - failure_regex matches a line, in which case None is returned |
80 # - the timeout is hit, in which case a CommandTimeoutError is raised. | 78 # - the timeout is hit, in which case a CommandTimeoutError is raised. |
81 for l in self._adb.Logcat(filter_specs=self._filter_specs): | 79 for l in self._adb.Logcat(): |
82 m = success_regex.search(l) | 80 m = success_regex.search(l) |
83 if m: | 81 if m: |
84 return m | 82 return m |
85 if failure_regex and failure_regex.search(l): | 83 if failure_regex and failure_regex.search(l): |
86 return None | 84 return None |
87 | 85 |
88 def FindAll(self, message_regex, proc_id=None, thread_id=None, log_level=None, | 86 def FindAll(self, message_regex, proc_id=None, thread_id=None, log_level=None, |
89 component=None): | 87 component=None): |
90 """Finds all lines in the logcat that match the provided constraints. | 88 """Finds all lines in the logcat that match the provided constraints. |
91 | 89 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 self._adb.Logcat(clear=True) | 134 self._adb.Logcat(clear=True) |
137 | 135 |
138 def __enter__(self): | 136 def __enter__(self): |
139 """Starts the logcat monitor.""" | 137 """Starts the logcat monitor.""" |
140 self.Start() | 138 self.Start() |
141 return self | 139 return self |
142 | 140 |
143 def __exit__(self, exc_type, exc_val, exc_tb): | 141 def __exit__(self, exc_type, exc_val, exc_tb): |
144 """Stops the logcat monitor.""" | 142 """Stops the logcat monitor.""" |
145 pass | 143 pass |
OLD | NEW |