Commit graph

17 commits

Author SHA1 Message Date
Nicki Křížek
ee782fb4b1 Separate LineReader functionality from WatchLog
The buffered reading of finished lines deserves its own class to make
its function clearer, rather than bundling it within the WatchLog class.

Co-Authored-By: Michał Kępień <michal@isc.org>
2025-07-18 11:32:41 +02:00
Nicki Křížek
3c8432d196 Refactor WatchLog for better readability
Various improvements for typing, naming, code deduplication and better
code organization to make the code easier to read.
2025-07-18 11:32:41 +02:00
Nicki Křížek
628b47dd30 Use custom WatchLog timeout exception
The TimeoutError is raised when system functions time out. Define a
custom WatchLogTimeout to improve clarity.
2025-07-18 11:32:41 +02:00
Nicki Křížek
0a839cd0bd Add wait_for_all() and wait_for_sequence() to WatchLog
Extend the WatchLog API with a couple of new matching options.

wait_for_sequence() can be used to check a specific sequence of lines
appears in the log file in the given order.

wait_for_all() ensure that all the provided patterns appear in the log
at least once.

Co-authored-by: Colin Vidal <colin@isc.org>
2025-07-18 11:32:41 +02:00
Nicki Křížek
365f8b6af6 Split up waiting for match to a separate WatchLog method
To allow re-use in upcoming functions, isolate the line matching logic
into a separate function. Use an instance-wide deadline attribute, which
is set by the calling function.
2025-07-18 11:32:41 +02:00
Nicki Křížek
2afb3755b2 Allow WatchLog.wait_for_line() to be called more than once
In some cases, it can be useful to be able to re-use the same WatchLog
to wait for another line.
2025-07-18 11:32:41 +02:00
Nicki Křížek
5840908ead Unify the WatchLog.wait_for_line/s() API
Rather than using two distinct functions for matching either one pattern
(wait_for_line()), or any of multiple patterns (wait_for_lines()), use a
single function that handles both in the same way.

Extend the wait_for_line() API:
1. To allow for usage of one or more FlexPatterns, i.e. either plain
   strings to be matched verbatim, or regular expressions. Both can be
   used interchangeably to provide the caller to write simple and
   readable test code, while allowing for increased complexity to allow
   special cases.
2. Always return the regex match, which allows the caller to identify
   which line was matched, as well as to extract any additional
   information, such as individual regex groups.
2025-07-18 11:32:41 +02:00
Nicki Křížek
f2679bff19 Set timeout for WatchLog per-instance rather than per-call
To simplify usage of multiple wait_for_*() calls, configure the timeout
value for the WatchLog instance, rather than specifying it for each
call.

This is a preparation/cleanup for implementing multiple wait_for_*()
calls in subsequent commits.
2025-07-18 11:32:41 +02:00
Nicki Křížek
67896ddde2 Abstract WatchLog line buffering to a separate function
Move the line buffering functionality into _readline() to improve the
readability of code. This also allows reading the file contents from
other functions, since the line buffer is now an attribute of the class.
2025-07-18 11:32:41 +02:00
Colin Vidal
9778068253 fix watchlog.py doctest
Fix some broken doctest in watchlog.py (no semantic error, but API
slightly changed and broke some output messags). Also add a test for a
missing failure case.
2025-07-18 11:32:40 +02:00
Nicki Křížek
23e6b49cc5 Indent multiline output in pytest logging
When multiline message is logged, indent all but the first line (which
will be preceeded by the LOG_FORMAT). This improves the clarity of logs,
as it's immediately clear which lines are regular log output, and which
ones are multiline debug output.

Adjust the isctest.run.cmd() stdout/stderr logging to this new format.
2025-06-27 16:31:49 +02:00
Nicki Křížek
069e4ef0f7 Use time.monotonic() for time measumeremts in pytest
For duration measurements, i.e. deadlines and timeouts, it's more
suitable to use monotonic time as it's guaranteed to only go forward,
unlike time.time() which can be affected by local clock settings.
2025-06-19 14:11:28 +02:00
Nicki Křížek
d7ace928b5
Initialize all environment variables when running isctest
Ensure all the variables are initialized when running the main function
of isctest module. This enables proper environment variables during test
script development when only conf.sh is sourced, rather than the script
being executed by the pytest runner.
2024-07-31 10:50:11 +02:00
Tom Krizek
673387c4d5
Move conftest log initialization to conftest.py
Initializing the conftest logging upon importing the isctest package
isn't practical when there are standalone pieces which can be used
outside of the testing framework, such as the asyncdnsserver module.
2024-03-20 09:22:36 +01:00
Michal Nowak
6dd1b3ab38
Add RegEx support to wait_for_line() and wait_for_lines() 2024-02-23 11:04:51 +01:00
Tom Krizek
c60975f108
Add utility logging functions to isctest.log
Unify the different loggers (conftest, module, test) into a single
interface. Remove the need to select the proper logger by automatically
selecting the most-specific logger currently available.

This also removes the need to use the logger/mlogger fixtures manually
and pass these around. This was especially annoying and unwieldy when
splitting the test cases into functions, because logger had to always be
passed around. Instead, it is now possible to use the
isctest.log.(debug,info,warning,error) functions.
2024-02-16 14:56:00 +01:00
Tom Krizek
52f9e6f557
Move watchlog module into isctest.log package
Preparation for further logging improvements - keep the watchlog
contents in a separate module inside isctest.log. Export the names in
the log package so the imports don't change for the users of these
classes.
2024-02-16 14:56:00 +01:00