blob: f8a755ddd5e34adc4c03249a91475a125505234d [file] [log] [blame]
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import collections
import re
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
LogcatLine = collections.namedtuple('LogcatLine', ['pid', 'tag', 'message'])
def wait_for_logcat_log(message_tag, message_pattern,
process_id=None, timeout_seconds=30, host=None):
"""Wait for a line to show up in logcat.
@param message_tag: string "tag" of the line, as understood by logcat.
@param message_pattern: regular expression pattern that describes the
entire text of the message to look for (e.g. '.*' matches all
messages). This is in grep's regex language.
@param process_id: optional integer process id to match on.
@param timeout_seconds: number of seconds to wait for the log line.
@param host: host object to look for the log line on. Defaults to
our local host.
"""
run = host.run if host is not None else utils.run
# This needs to match a line like:
# I( 1303) [0302/210332:INFO:main.cc(113)] logged message (update_engine)
#
# where:
# I( 1303) means that this was logged at the INFO level by process 1303.
# (update_engine) suffix means that the log tag was "update_engine".
# '[0302/210332:INFO:main.cc(113)] logged message' is the message text.
process_id_pattern = '[0-9]+'
if process_id is not None:
process_id_pattern = str(process_id)
grep_pattern = r'^.\( *%s\) %s \(%s\)$' % (
process_id_pattern, message_pattern, message_tag)
# This super exciting command works as follows:
# 1) logcat streams logs to a subshell.
# 2) The subshell greps through the logs for a particular line.
# 3) After seeing the line, log and cause a SIGPIPE for logcat.
result = run('logcat --format=process | '
'(grep -m 1 -E "%s"; log -tautotest "Found log %s")' % (
grep_pattern, message_pattern),
timeout=timeout_seconds,
ignore_timeout=True)
if result is None:
raise error.TestFail('Timed out waiting for a log with message "%s"' %
message_pattern)
line = result.stdout.strip()
match = re.match(r'^.\( *(\d+)\) (.*) \(([^(]+)\)$', line)
if match:
return LogcatLine(pid=match.group(1),
message=match.group(2),
tag=match.group(3))
raise error.TestError('Failed to match logcat line "%s"' % line)