Class LeakPresenceExtension

java.lang.Object
io.netty.util.test.LeakPresenceExtension
All Implemented Interfaces:
org.junit.jupiter.api.extension.AfterAllCallback, org.junit.jupiter.api.extension.AfterEachCallback, org.junit.jupiter.api.extension.BeforeAllCallback, org.junit.jupiter.api.extension.BeforeEachCallback, org.junit.jupiter.api.extension.ExecutionCondition, org.junit.jupiter.api.extension.Extension

public final class LeakPresenceExtension extends Object implements org.junit.jupiter.api.extension.ExecutionCondition, org.junit.jupiter.api.extension.BeforeAllCallback, org.junit.jupiter.api.extension.BeforeEachCallback, org.junit.jupiter.api.extension.AfterEachCallback, org.junit.jupiter.api.extension.AfterAllCallback
Junit 5 extension for leak detection using LeakPresenceDetector.

Leak presence is checked at the class level. Any resource must be closed at the end of the test class, by the time AfterAll has been called. Method-level detection is not possible because some tests retain resources between methods on the same class, notably parameterized tests that allocate different buffers before running the test methods with those buffers.

This extension supports parallel test execution, but has to make some assumptions about the thread lifecycle. The resource scope for the class is created in BeforeAll, and then saved in a thread local on each BeforeEach. This appears to work well with junit's default parallelism, despite the use of a fork-join pool that can transfer tasks between threads, but it may lead to problems if tests make use of fork-join machinery themselves.

The ThreadLocal holding the scope is inheritable, so that e.g. event loops created in a test are assigned to the test resource scope.

  • Field Details

    • LEAK_PRESENCE_DETECTION_DISABLED_PROPERTY

      static final String LEAK_PRESENCE_DETECTION_DISABLED_PROPERTY
      See Also:
    • SCOPE_KEY

      private static final Object SCOPE_KEY
    • PREVIOUS_SCOPE_KEY

      private static final Object PREVIOUS_SCOPE_KEY
  • Constructor Details

    • LeakPresenceExtension

      public LeakPresenceExtension()
  • Method Details

    • evaluateExecutionCondition

      public org.junit.jupiter.api.extension.ConditionEvaluationResult evaluateExecutionCondition(org.junit.jupiter.api.extension.ExtensionContext context)
      Specified by:
      evaluateExecutionCondition in interface org.junit.jupiter.api.extension.ExecutionCondition
    • beforeAll

      public void beforeAll(org.junit.jupiter.api.extension.ExtensionContext context)
      Specified by:
      beforeAll in interface org.junit.jupiter.api.extension.BeforeAllCallback
    • beforeEach

      public void beforeEach(org.junit.jupiter.api.extension.ExtensionContext context)
      Specified by:
      beforeEach in interface org.junit.jupiter.api.extension.BeforeEachCallback
    • afterEach

      public void afterEach(org.junit.jupiter.api.extension.ExtensionContext context)
      Specified by:
      afterEach in interface org.junit.jupiter.api.extension.AfterEachCallback
    • afterAll

      public void afterAll(org.junit.jupiter.api.extension.ExtensionContext context) throws InterruptedException
      Specified by:
      afterAll in interface org.junit.jupiter.api.extension.AfterAllCallback
      Throws:
      InterruptedException
    • isOwnedBy

      private static boolean isOwnedBy(Class<?> testClass, Class<?> owner)
      Accept the class that created the shared scope and any of its @Nested classes. JUnit models nested test classes as separate Class objects and separate ExtensionContexts, not as subclasses of the outer test class. That means a simple assignability check would reject legitimate nested usage and cause the nested class to fail in beforeAll even though it should reuse the outer scope.