From 502b12b3bedbd30626e2e2a85efc6f68806cedd1 Mon Sep 17 00:00:00 2001 From: Sergei Egorov Date: Sat, 24 Aug 2019 22:26:38 +0200 Subject: [PATCH] speed up port detection by running the checks as a single command --- .../internal/ExternalPortListeningCheck.java | 4 +- .../InternalCommandPortListeningCheck.java | 45 ++++++++++--------- .../wait/strategy/HostPortWaitStrategy.java | 4 +- ...InternalCommandPortListeningCheckTest.java | 10 ++--- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/core/src/main/java/org/testcontainers/containers/wait/internal/ExternalPortListeningCheck.java b/core/src/main/java/org/testcontainers/containers/wait/internal/ExternalPortListeningCheck.java index 3283880b569..2aae12bab8d 100644 --- a/core/src/main/java/org/testcontainers/containers/wait/internal/ExternalPortListeningCheck.java +++ b/core/src/main/java/org/testcontainers/containers/wait/internal/ExternalPortListeningCheck.java @@ -20,13 +20,13 @@ public class ExternalPortListeningCheck implements Callable { public Boolean call() { String address = containerState.getContainerIpAddress(); - for (Integer externalPort : externalLivenessCheckPorts) { + externalLivenessCheckPorts.parallelStream().forEach(externalPort -> { try { new Socket(address, externalPort).close(); } catch (IOException e) { throw new IllegalStateException("Socket not listening yet: " + externalPort); } - } + }); return true; } } diff --git a/core/src/main/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheck.java b/core/src/main/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheck.java index bad30fef653..43ed94bc84d 100644 --- a/core/src/main/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheck.java +++ b/core/src/main/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheck.java @@ -1,9 +1,13 @@ package org.testcontainers.containers.wait.internal; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.testcontainers.containers.Container.ExecResult; import org.testcontainers.containers.ExecInContainerPattern; import org.testcontainers.containers.wait.strategy.WaitStrategyTarget; +import java.time.Duration; +import java.time.Instant; import java.util.Set; import static java.lang.String.format; @@ -12,6 +16,7 @@ * Mechanism for testing that a socket is listening when run from the container being checked. */ @RequiredArgsConstructor +@Slf4j public class InternalCommandPortListeningCheck implements java.util.concurrent.Callable { private final WaitStrategyTarget waitStrategyTarget; @@ -19,30 +24,26 @@ public class InternalCommandPortListeningCheck implements java.util.concurrent.C @Override public Boolean call() { - for (Integer internalPort : internalPorts) { - tryPort(internalPort); + String command = "true"; + + for (int internalPort : internalPorts) { + command += " && "; + command += " ("; + command += format("cat /proc/net/tcp{,6} | awk '{print $2}' | grep -i :%x", internalPort); + command += " || "; + command += format("nc -vz -w 1 localhost %d", internalPort); + command += " || "; + command += format("/bin/bash -c ' externalLivenessCheckPorts = getLivenessCheckPorts(); if (externalLivenessCheckPorts.isEmpty()) { - log.debug("Liveness check ports of {} is empty. Not waiting.", waitStrategyTarget.getContainerInfo().getName()); + if (log.isDebugEnabled()) { + log.debug("Liveness check ports of {} is empty. Not waiting.", waitStrategyTarget.getContainerInfo().getName()); + } return; } diff --git a/core/src/test/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheckTest.java b/core/src/test/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheckTest.java index c1cd341943e..71a14c3c79e 100644 --- a/core/src/test/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheckTest.java +++ b/core/src/test/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheckTest.java @@ -6,7 +6,7 @@ import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; -import static org.rnorth.visibleassertions.VisibleAssertions.assertThrows; +import static org.rnorth.visibleassertions.VisibleAssertions.assertFalse; import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; public class InternalCommandPortListeningCheckTest { @@ -30,8 +30,8 @@ public void singleListening() { public void nonListening() { final InternalCommandPortListeningCheck check = new InternalCommandPortListeningCheck(nginx, ImmutableSet.of(8080, 1234)); - assertThrows("InternalCommandPortListeningCheck detects a non-listening port among many", - IllegalStateException.class, - (Runnable) check::call); + final Boolean result = check.call(); + + assertFalse("InternalCommandPortListeningCheck detects a non-listening port among many", result); } -} \ No newline at end of file +}