-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New feature: capture recent logs for testing #1148
Conversation
This is part of a bigger logging refactoring. Logs will not be disabled but sned to a capturer instead of sdtout.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #1148 +/- ##
===========================================
- Coverage 76.24% 76.12% -0.13%
===========================================
Files 173 173
Lines 11543 11551 +8
Branches 11543 11551 +8
===========================================
- Hits 8801 8793 -8
- Misses 2579 2590 +11
- Partials 163 168 +5 ☔ View full report in Codecov by Sentry. |
I finally moved the code to capture logs from production to testing code in a new PR. Superseded by #1149 @da2ce7, the new PR is what we have right now, but capturing logs in tests. I was planning to use tracing
The assertions can be written like this: #[tokio::test]
async fn should_blab_bla() {
logging::setup();
let span = tracing::info_span!("unique scope");
let _guard = span.enter();
// test ...
assert!(logs_contains_a_line_with(
&["unique scope", "ERROR", "tower_http", "response failed"]
));
} However, the span is not moved into the spawned threads when we run the test environments. Therefore, the "unique scope" identifier is not present in the logs, and we can not write assertions. It seems you can clone the span (see here at minute 40) or using |
d11ab32 test: capture logs in tests (Jose Celano) Pull request description: Relates to: - #1069 - #1148 This feature will be used in the future to write assertions about logs. It also changes when we show logs running tests. If you run tests with: ```console cargo test ``` logs won't be shown. If you want to see the logs you have to execute tests with: ```console cargo test -- --nocapture ``` ACKs for top commit: josecelano: ACK d11ab32 Tree-SHA512: d4a11d899b7c0bd005c5e3b518eec89487ec12eac9535fcb5dca8684f1ea4075e706d51178df9e67d01b359c0221d0926e77159797d9d9c53083f4b56a9ee904
Relates to: #1069
Context
I'm trying to capture logs in memory to write assertions in tests. I tried to use the tracing-test crate in this PR, but it's not working due to this bug.
So, I decided to copy some code from that crate because the crate forces you to disable your tracing initialization, and I wanted to keep our initialization to have better control.
The idea is the same; a log capturer captures the logs in addition to printing to stdout.
I initiate the capturer in the production code instead of doing it in the testing code with a macro.
Problems
tracing_init
function. I tried using twotracing_init
functions with attributes#[cfg(test)]
and#[cfg(not(test))]
, only enabling the capturer for testing, but it's not working.Future work
Right now, you can write asserts like this:
For example, for these tests. But there is no way to match assertings with log lines. We must introduce something like "scopes", or "labels". We need to add a UUID to the log lines when we write to logs with
error!
,info!
, etc. So we can search for lines containing that ID. Thetracing-test
uses scopes. It inserts the name of the test in the logs so it can filter later. I think we can add a UUID to the test environment, for example, to make it more explicit. Each test runs its own test env, and the test env adds the UUID to the logs. This way, we can identify logs for a test environment but not for a concrete test. Maybe we can use both approaches.Enable tracing output for tests only with
--nocapture
I have introduced another change in one of the first commits. All test environments were created with an ephemeral configuration with the tracing level set to OFF. The reason was to hide logs when you run the tests, to avoid mixing both outputs. I have changed the ephemeral configuration to error:
After that change,
cargo test
printed all the errors.I think the right way to disable the tracing output for testing is using the
with_test_writer
function in the builder:That configures the subscriber to show tracing output only when the option
--nocapture
is passed.If we discard this PR, we should pick at least that configuration.
Important
tracing_init
is called only once, but we don't control which one is the first call. I mean, if we have two tests running test environments, the first test that calls thetracing_init
will define the tracing level. Therefore, we have to ensure there are no tests that disable logs. If there is one and it's executed the first, all logs assert won't work.Alternatives
If we want to capture all logs, we could separate the tests for logs into a new group. Those tests only would have logs assertions. They would require the capturer to be enabled (like E2E tests in the Indes that require a running tracker). You could run the tests with:
TORRUST_TRACKER_CAPTURE_LOGS cargo test
Internally, that would enable the log capturer, which would otherwise be disabled.
TODO
Info
logging level.