1

I have a couple of integration in this fashion:

@SpringBootTest
@ExtendWith(SpringExtension.class)
@AutoConfigureMockMvc
@ActiveProfiles({"test", "test-batch"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class HierarchyIntegrationTest {

@Test
@DirtiesContext
void hierarchy_test_a() {
//test code here.
}

@Test
@DirtiesContext
void hierarchy_test_b() {
//test code here.
}

@Test
@DirtiesContext
void hierarchy_test_c() {
//test code here.
}


}

And

@SpringBootTest
@ExtendWith(SpringExtension.class)
@AutoConfigureMockMvc
@ActiveProfiles("test")
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class TicketPriceIntegrationTest {

    @Test
    @DirtiesContext
    void ticket_test_a() {
    //test code here.
    }

    @Test
    @DirtiesContext
    void ticket_test_b() {
    //test code here.
    }

    @Test
    @DirtiesContext
    void ticket_test_c() {
    //test code here.
    }

}

Now how can I verify that @DirtiesContext is not working ?

It is because all my integration tests use Hikari to connect to the database:

On each new integration I see the number of the Hikari connection pool going up, like so:

00:47:02.450 [INFO ] c.z.h.HikariDataSource - HikariPool-20 - Shutdown initiated...
00:47:03.061 [INFO ] c.z.h.HikariDataSource - HikariPool-20 - Shutdown completed.

00:47:02.450 [INFO ] c.z.h.HikariDataSource - HikariPool-21 - Shutdown initiated...
00:47:03.061 [INFO ] c.z.h.HikariDataSource - HikariPool-21 - Shutdown completed.

00:47:02.450 [INFO ] c.z.h.HikariDataSource - HikariPool-22 - Shutdown initiated...
00:47:03.061 [INFO ] c.z.h.HikariDataSource - HikariPool-22 - Shutdown completed.

Each new test should be mutually exclusive of each other.

@DirtiesContext should have taken care of that, but it seems the previous beans are not being discarded.

Hence I am ending up with a memory leak.

 00:50:36.597 [ERROR] o.s.t.c.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@550625bf] to prepare test instance [com.item.integration.IntegrationTest@5b59e4c6]
    java.lang.OutOfMemoryError: Java heap space

I am using :

Spring Boot 2.5.4
JUnit5 (Jupiter)

How can I solve this ?

Thanks

ng.newbie
  • 2,807
  • 3
  • 23
  • 57

1 Answers1

2

The Hikari poolName is incrementing through a JVM System property, this is why you can see it after each ApplicationContext destruction. This destruction effectively recreates ALL the beans of your Context.

Source from HikariConfig.class:

            synchronized(System.getProperties()) {
                String next = String.valueOf(Integer.getInteger("com.zaxxer.hikari.pool_number", 0) + 1);
                System.setProperty("com.zaxxer.hikari.pool_number", next);
                return "HikariPool-" + next;
            }

The memory problem is something else, you can try to increase the heap size of the JVM..

Mickaël B.
  • 325
  • 4
  • 14
  • How can I get a heap dump ? Using the `-XX:+HeapDumpOnOutOfMemoryError` is generating no heap dump files – ng.newbie Feb 02 '22 at 17:42
  • What do you exactly mean by : `This destruction effectively recreates ALL the beans of your Context.` ? – ng.newbie Feb 02 '22 at 17:43
  • 1
    My query is if there is a HikariPool-27 created then are there 26 pools created and kept in the application context ? I don't have that many pools in my application, I just have 2. – ng.newbie Feb 02 '22 at 17:46
  • I mean that you don't have to worry about, the destruction of the beans of your context, they are properly destroyed and recreated. No, in your case, the connection pool are destroyed, but if you have others SpringTest classes configured with a custom context (ex: @MockBean, custom profile..), Spring will try to cache the context to be reused later. In this case, you can have many connection pools alive (which may be your problem but i can't tell https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#spring-testing-annotation-dirtiescontext) – Mickaël B. Feb 03 '22 at 08:46
  • Can you tell me how I can collect the Heap dump from the OOM in Gradle ? I am unable to do it. – ng.newbie Feb 03 '22 at 08:50
  • 1
    Hey, can I tell Spring not to cache the application context ? – ng.newbie Feb 03 '22 at 08:52
  • Yes, you can force spring to cache only one context with spring.test.context.cache.maxSize=1 (which may be redundant if you use DirtiesContext on all your classes). But it's another problem, you can accept my solution if you found I was helpful, and creates another thread for your different problem. – Mickaël B. Feb 03 '22 at 10:17