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 java.lang.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.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    private static final class 
    Prevent junit from closing the ResourceScope automatically.
    static final class 
     
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    (package private) static final java.lang.String
     
    private static final java.lang.Object
     
    private static final java.lang.Object
     
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    afterAll(org.junit.jupiter.api.extension.ExtensionContext context)
     
    void
    afterEach(org.junit.jupiter.api.extension.ExtensionContext context)
     
    void
    beforeAll(org.junit.jupiter.api.extension.ExtensionContext context)
     
    void
    beforeEach(org.junit.jupiter.api.extension.ExtensionContext context)
     
    org.junit.jupiter.api.extension.ConditionEvaluationResult
    evaluateExecutionCondition(org.junit.jupiter.api.extension.ExtensionContext context)
     
    private static boolean
    isOwnedBy(java.lang.Class<?> testClass, java.lang.Class<?> owner)
    Accept the class that created the shared scope and any of its @Nested classes.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • LEAK_PRESENCE_DETECTION_DISABLED_PROPERTY

      static final java.lang.String LEAK_PRESENCE_DETECTION_DISABLED_PROPERTY
      See Also:
    • SCOPE_KEY

      private static final java.lang.Object SCOPE_KEY
    • PREVIOUS_SCOPE_KEY

      private static final java.lang.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 java.lang.InterruptedException
      Specified by:
      afterAll in interface org.junit.jupiter.api.extension.AfterAllCallback
      Throws:
      java.lang.InterruptedException
    • isOwnedBy

      private static boolean isOwnedBy(java.lang.Class<?> testClass, java.lang.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.