kunit: tool: print parsed test results fully incrementally
With the parser rework [1] and run_kernel() rework [2], this allows the parser to print out test results incrementally. Currently, that's held up by the fact that the LineStream eagerly pre-fetches the next line when you call pop(). This blocks parse_test_result() from returning until the line *after* the "ok 1 - test name" line is also printed. One can see this with the following example: $ (echo -e 'TAP version 14\n1..3\nok 1 - fake test'; sleep 2; echo -e 'ok 2 - fake test 2'; sleep 3; echo -e 'ok 3 - fake test 3') | ./tools/testing/kunit/kunit.py parse Before this patch [1]: there's a pause before 'fake test' is printed. After this patch: 'fake test' is printed out immediately. This patch also adds * a unit test to verify LineStream's behavior directly * a test case to ensure that it's lazily calling the generator * an explicit exception for when users go beyond EOF [1] https://lore.kernel.org/linux-kselftest/20211006170049.106852-1-dlatypov@google.com/ [2] https://lore.kernel.org/linux-kselftest/20211005011340.2826268-1-dlatypov@google.com/ Signed-off-by: Daniel Latypov <dlatypov@google.com> Reviewed-by: David Gow <davidgow@google.com> Reviewed-by: Brendan Higgins <brendanhiggins@google.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
This commit is contained in:
committed by
Shuah Khan
parent
44b7da5fcd
commit
142189f09c
@@ -168,42 +168,51 @@ class TestCounts:
|
||||
class LineStream:
|
||||
"""
|
||||
A class to represent the lines of kernel output.
|
||||
Provides a peek()/pop() interface over an iterator of
|
||||
Provides a lazy peek()/pop() interface over an iterator of
|
||||
(line#, text).
|
||||
"""
|
||||
_lines: Iterator[Tuple[int, str]]
|
||||
_next: Tuple[int, str]
|
||||
_need_next: bool
|
||||
_done: bool
|
||||
|
||||
def __init__(self, lines: Iterator[Tuple[int, str]]):
|
||||
"""Creates a new LineStream that wraps the given iterator."""
|
||||
self._lines = lines
|
||||
self._done = False
|
||||
self._need_next = True
|
||||
self._next = (0, '')
|
||||
self._get_next()
|
||||
|
||||
def _get_next(self) -> None:
|
||||
"""Advances the LineSteam to the next line."""
|
||||
"""Advances the LineSteam to the next line, if necessary."""
|
||||
if not self._need_next:
|
||||
return
|
||||
try:
|
||||
self._next = next(self._lines)
|
||||
except StopIteration:
|
||||
self._done = True
|
||||
finally:
|
||||
self._need_next = False
|
||||
|
||||
def peek(self) -> str:
|
||||
"""Returns the current line, without advancing the LineStream.
|
||||
"""
|
||||
self._get_next()
|
||||
return self._next[1]
|
||||
|
||||
def pop(self) -> str:
|
||||
"""Returns the current line and advances the LineStream to
|
||||
the next line.
|
||||
"""
|
||||
n = self._next
|
||||
self._get_next()
|
||||
return n[1]
|
||||
s = self.peek()
|
||||
if self._done:
|
||||
raise ValueError(f'LineStream: going past EOF, last line was {s}')
|
||||
self._need_next = True
|
||||
return s
|
||||
|
||||
def __bool__(self) -> bool:
|
||||
"""Returns True if stream has more lines."""
|
||||
self._get_next()
|
||||
return not self._done
|
||||
|
||||
# Only used by kunit_tool_test.py.
|
||||
@@ -216,6 +225,7 @@ class LineStream:
|
||||
|
||||
def line_number(self) -> int:
|
||||
"""Returns the line number of the current line."""
|
||||
self._get_next()
|
||||
return self._next[0]
|
||||
|
||||
# Parsing helper methods:
|
||||
|
||||
Reference in New Issue
Block a user