Skip to content

Add zaptest option to suppress logging after test completion #1526

@theunrepentantgeek

Description

@theunrepentantgeek

Is your feature request related to a problem? Please describe.

When using zaptest to provide logging during tests, I'm seeing a small number of test flakes due to logs emitted after the test completes - when zaptest calls t.Log(), it panic, failing the test.

Describe the solution you'd like

I'd like to add an option to "mute" a test logger after test completion, avoiding the panic and eliminating the flake.

As per CONTRIBUTING.md, I'm raising this issue first - but I'm happy to contribute the code if you're happy with the idea.

Proposed api design:

log := zaptest.NewLogger(w, zaptest.MuteAfterTestCompletion())
  • Opt-in to preserve current behaviour (in case anyone is depending on it in their tests), but avoiding the issues we're seeing.

  • Check for the prefix "Log in goroutine after" (see below) so we don't suppress any other panic that occurs

Describe alternatives you've considered

My errant/extra log calls are coming from subsidary goroutines that don't always shut down in time. We've done a number of things to reduce the flakes, including some guard rails like this:

if !testing {
	x.log.Info("...")
}

Unfortunately, this itself has a race condition and thus does not eliminate all flakes. It's also ugly to have this in production code.

I'm considering writing a wrapper around zaptest that will do the same thing as this feature, but that would only benefit my project. Contributing the idea back to zaptest would allow others to benefit.

Is this a breaking change?

No. Without the new option MuteAFterTestCompletion() existing behaviour would be preserved.

Additional context

Why check for a prefix? The panics themselves originate from this code in the standard Go library (testing.go):

n := c.destination()
if n == nil {
	// The test and all its parents are done. The log cannot be output.
	panic("Log in goroutine after " + c.name + " has completed: " + s)
}

If a different panic occurred while calling t.Log(), that wouldn't be something to suppress.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions