You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add possibility to skip container initialization without exception, when Docker not available #2833
In my Integration Tests we use testcontainers to provide services to the tests. (LDAP, Databases etc.)
On the CI runners docker is available on the host.
In my developer environment - there is no Docker available on the host. (Only in my developer-Vagrant-VM, not visible to test containers)
Problem statement
I am seeking for a possibility
During the development to disable testcontainers, but not the test, if docker is not available.
I would take care of providing the services, usually running in containers
Disabling the testcontainers should happen, depending on the settings in the environment, like ENV variable.
Because right now the only solution I dound is - to comment the @container statements, what gets checked in all the time.
Proposal of a solution
I suggest to introduce a flag at the @org.testcontainers.junit.jupiter.TestContainers annotation: skipContainersWithoutDocker=true
Reacted by RobotFramework(er), Michael Rodionov, MarieBezdekova1 and Yauhen
@Skipidar I see now. I think this is a very unusual setup with many assumptions, and IMO it does not make sense to add it as a general purpose flag.
To achieve what you want, you can create Startable wrappers that will check the env or the presence of Docker and either call originalContainer.start() or skip it and return already known host:port pairs
Also doesnt the "disabledWithoutDocker" do two things now?
disable the containers initialization
disable the TESTS
I think implicitely disabling the test - is not intuitive, I have not expected that. You also forgot about it I think :)
I would then suggest to split that, existing flag - in two flags
disableContainersWithoutDocker
disableTestsWithoutDocker
That would describe the behaviour in an explicit way and also solve my problem.
I would set it to disableContainersWithoutDocker=true, disableTestsWithoutDocker=false
Reacted by RobotFramework(er), Vladyslav Morozov and Laszlo Varga
but how would I use it? Where would I inject it into the testcontainers?
The Testcontainers Jupiter extension works on Startable level, and, when tests are started, calls Startable#start on each field. If you need custom logic (like skipping the containers), you can wrap them with your custom Startable.
Also doesnt the "disabledWithoutDocker" do two things now?
No, it does exactly one thing - skips the test completely if Docker is not found. It does not disable the containers initialization at all.
I think implicitely disabling the test - is not intuitive, I have not expected that
It is very explicit if you ask me. @Testcontainers is a test extension, and you disable the test without Docker. The Javadoc is pretty clear about this as well:
* Whether tests should be disabled (rather than failing) when Docker is not available.
disableContainersWithoutDocker makes little sense because the objects will remain initialized, just not started, and may lead to weird behaviour where someone attempts to call getHost() on them.
public class FixedHostPortGenericDisableableContainer<T extends FixedHostPortGenericDisableableContainer<T>> extends FixedHostPortGenericContainer<T> {
private boolean isActive;
public FixedHostPortGenericDisableableContainer(@NotNull String dockerImageName) {
super(dockerImageName);
}
@Override
public void start() {
if (isActive) {
super.start();
}
}
public FixedHostPortGenericDisableableContainer isActive(boolean isActive) {
this.isActive = isActive;
return this;
}
}
Usage
// set this environment variable to true to disable test containers
public static final String ENV_DISABLE_TEST_CONTAIENRS = "DISABLE_TEST_CONTAIENRS";
@Container
private static GenericContainer dynamoDb =
new FixedHostPortGenericDisableableContainer("amazon/dynamodb-local:1.11.477")
.isActive(StringUtils.isBlank(System.getenv(ENV_DISABLE_TEST_CONTAIENRS)))
.withFixedExposedPort(8001, 8000)
.withStartupAttempts(100);
I'm in a similar situation as @Skipidar I've introduced testcontainers into our build obviously to have a 1:1 reproduceable build on CI and locally. But some people do not like the idea of docker magic happening in the background when they build locally.
Is there a way to deactivate testcontainers via command-line similar to mvn verify -DskipTests ? i.e. -DskipTestcontainers
Alternatively, is @Skipidar's solution from above also applicable when Docker Compose Module w/ Junit5 is used?
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@Testcontainers
public class FhirBridgeApplicationTestIT {
private final Logger logger = LoggerFactory.getLogger(FhirBridgeApplicationTestIT.class);
@Container
public static DockerComposeContainer environment = new DockerComposeContainer(
new File("src/test/resources/ehrbase-compose.yml")).withExposedService("ehrdb", 5432)
.withExposedService("ehrbase", 8080)
.waitingFor("ehrbase", Wait.forListeningPort());
``
@bsideup We have the same issue when we want to use Testcontainers locally but during the CI/CD pipeline we want to use the service provided by the CI/CD platform. For example, we don't want to use Docker daemon within our CI pipeline due to security reasons and instead to use Codefresh Service that runs docker containers in more secured way.
Adding disabledWithoutDocker=true disables our test completely that extend Testcontainers abstract class and any @EnabledIf annotation doesn't help.
The better way is to give the ability to switch from Testcontainers by adding a new annotation would set it to disableContainersWithoutDocker=true, disableTestsWithoutDocker=false like @Skipidar suggested when Docker daemon is not presented.
We would appreciate if such ability will be added and this issue will be opened again.
Activity
bsideup commentedon Jun 4, 2020
Already implemented in #1530
alfrepo commentedon Jun 4, 2020
Hi @bsideup disabledWithoutDocker=true
disables THE TEST.
I still WANT TO RUN THE TEST, but skip the container intitialization.
bsideup commentedon Jun 4, 2020
@Skipidar I see now. I think this is a very unusual setup with many assumptions, and IMO it does not make sense to add it as a general purpose flag.
To achieve what you want, you can create
Startablewrappers that will check the env or the presence of Docker and either calloriginalContainer.start()or skip it and return already knownhost:portpairsalfrepo commentedon Jun 4, 2020
THnx @bsideup - have not understood your idea.
I would implement a Startable https://www.javadoc.io/doc/org.testcontainers/testcontainers/1.12.0/org/testcontainers/lifecycle/Startable.html wrapper,
but how would I use it? Where would I inject it into the testcontainers?
alfrepo commentedon Jun 4, 2020
Also doesnt the "disabledWithoutDocker" do two things now?
I think implicitely disabling the test - is not intuitive, I have not expected that. You also forgot about it I think :)
I would then suggest to split that, existing flag - in two flags
That would describe the behaviour in an explicit way and also solve my problem.
I would set it to
disableContainersWithoutDocker=true, disableTestsWithoutDocker=falsebsideup commentedon Jun 4, 2020
@Skipidar
The Testcontainers Jupiter extension works on
Startablelevel, and, when tests are started, callsStartable#starton each field. If you need custom logic (like skipping the containers), you can wrap them with your customStartable.Before:
After:
No, it does exactly one thing - skips the test completely if Docker is not found. It does not disable the containers initialization at all.
It is very explicit if you ask me.
@Testcontainersis a test extension, and you disable the test without Docker. The Javadoc is pretty clear about this as well:testcontainers-java/modules/junit-jupiter/src/main/java/org/testcontainers/junit/jupiter/Testcontainers.java
Line 64 in 0eb2dea
disableContainersWithoutDockermakes little sense because the objects will remain initialized, just not started, and may lead to weird behaviour where someone attempts to callgetHost()on them.alfrepo commentedon Jun 5, 2020
Thnx, this is how it looks like
Startable
Usage
bsideup commentedon Jun 5, 2020
@Skipidar glad to see that you got it solved.
FTR I would advice against any use of fixed ports (spoiler - not even because of the ports!):
https://bsideup.github.io/posts/testcontainers_fixed_ports/
wlad commentedon Sep 2, 2020
I'm in a similar situation as @Skipidar I've introduced testcontainers into our build obviously to have a 1:1 reproduceable build on CI and locally. But some people do not like the idea of docker magic happening in the background when they build locally.
Is there a way to deactivate testcontainers via command-line similar to
mvn verify -DskipTests? i.e.-DskipTestcontainersAlternatively, is @Skipidar's solution from above also applicable when Docker Compose Module w/ Junit5 is used?
PavelZeger commentedon Jun 9, 2022
@bsideup We have the same issue when we want to use Testcontainers locally but during the CI/CD pipeline we want to use the service provided by the CI/CD platform. For example, we don't want to use Docker daemon within our CI pipeline due to security reasons and instead to use
Codefresh Servicethat runs docker containers in more secured way.Adding
disabledWithoutDocker=truedisables our test completely that extend Testcontainers abstract class and any@EnabledIfannotation doesn't help.The better way is to give the ability to switch from Testcontainers by adding a new annotation would set it to
disableContainersWithoutDocker=true, disableTestsWithoutDocker=falselike @Skipidar suggested when Docker daemon is not presented.We would appreciate if such ability will be added and this issue will be opened again.
onlydara commentedon Jun 23, 2022
@PavelZeger Hi, Pavel, i have the same issue now. Did you solve it, or you can't do it without new annotations from Testcontainers?
PavelZeger commentedon Nov 18, 2022
@onlydara Try to use
DockerClientFactory.instance().isDockerAvailable();(thanks to @shelajev).