diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleBeanPostProcessor.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleBeanPostProcessor.java index 519d5de0d6a..7d23eb65367 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleBeanPostProcessor.java +++ b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleBeanPostProcessor.java @@ -29,6 +29,7 @@ import org.apache.commons.logging.LogFactory; import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.GenericContainer; import org.testcontainers.lifecycle.Startable; +import org.testcontainers.utility.TestcontainersConfiguration; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanCreationException; @@ -55,6 +56,7 @@ import org.springframework.core.log.LogMessage; * * @author Phillip Webb * @author Stephane Nicoll + * @author Scott Frederick * @see TestcontainersLifecycleApplicationContextInitializer */ @Order(Ordered.LOWEST_PRECEDENCE) @@ -183,7 +185,8 @@ class TestcontainersLifecycleBeanPostProcessor } private boolean isReusedContainer(Object bean) { - return (bean instanceof GenericContainer container) && container.isShouldBeReused(); + return (bean instanceof GenericContainer container) && container.isShouldBeReused() + && TestcontainersConfiguration.getInstance().environmentSupportsReuse(); } enum Startables { diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleApplicationContextInitializerTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleApplicationContextInitializerTests.java index a00c0da51de..68b5c46c415 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleApplicationContextInitializerTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/lifecycle/TestcontainersLifecycleApplicationContextInitializerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,11 @@ package org.springframework.boot.testcontainers.lifecycle; import java.util.Map; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.lifecycle.Startable; +import org.testcontainers.utility.TestcontainersConfiguration; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.support.AbstractBeanFactory; @@ -43,9 +45,15 @@ import static org.mockito.Mockito.times; * * @author Stephane Nicoll * @author Phillip Webb + * @author Scott Frederick */ class TestcontainersLifecycleApplicationContextInitializerTests { + @BeforeEach + void setUp() { + TestcontainersConfiguration.getInstance().updateUserConfig("testcontainers.reuse.enable", "false"); + } + @Test void whenStartableBeanInvokesStartOnRefresh() { Startable container = mock(Startable.class); @@ -67,7 +75,8 @@ class TestcontainersLifecycleApplicationContextInitializerTests { } @Test - void whenReusableContainerBeanInvokesStartButNotClose() { + void whenReusableContainerAndReuseEnabledBeanInvokesStartButNotClose() { + TestcontainersConfiguration.getInstance().updateUserConfig("testcontainers.reuse.enable", "true"); GenericContainer container = mock(GenericContainer.class); given(container.isShouldBeReused()).willReturn(true); AnnotationConfigApplicationContext applicationContext = createApplicationContext(container); @@ -79,7 +88,20 @@ class TestcontainersLifecycleApplicationContextInitializerTests { } @Test - void whenReusableContainerBeanFromConfigurationInvokesStartButNotClose() { + void whenReusableContainerButReuseNotEnabledBeanInvokesStartAndClose() { + GenericContainer container = mock(GenericContainer.class); + given(container.isShouldBeReused()).willReturn(true); + AnnotationConfigApplicationContext applicationContext = createApplicationContext(container); + then(container).shouldHaveNoInteractions(); + applicationContext.refresh(); + then(container).should().start(); + applicationContext.close(); + then(container).should(times(1)).close(); + } + + @Test + void whenReusableContainerAndReuseEnabledBeanFromConfigurationInvokesStartButNotClose() { + TestcontainersConfiguration.getInstance().updateUserConfig("testcontainers.reuse.enable", "true"); AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); new TestcontainersLifecycleApplicationContextInitializer().initialize(applicationContext); applicationContext.register(ReusableContainerConfiguration.class); @@ -90,6 +112,18 @@ class TestcontainersLifecycleApplicationContextInitializerTests { then(container).should(never()).close(); } + @Test + void whenReusableContainerButReuseNotEnabledBeanFromConfigurationInvokesStartAndClose() { + AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); + new TestcontainersLifecycleApplicationContextInitializer().initialize(applicationContext); + applicationContext.register(ReusableContainerConfiguration.class); + applicationContext.refresh(); + GenericContainer container = applicationContext.getBean(GenericContainer.class); + then(container).should().start(); + applicationContext.close(); + then(container).should(times(1)).close(); + } + @Test void doesNotInitializeSameContextMoreThanOnce() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();