From c65fb6b45ef3a93ce94d2d3104907b67685fc79e Mon Sep 17 00:00:00 2001 From: Nateckert Date: Wed, 4 Jan 2023 17:53:50 +0100 Subject: [PATCH 1/4] Avoid usage of System.currentTimeMillis() --- .../containers/output/WaitingConsumer.java | 8 ++++---- .../testcontainers/junit/GenericContainerRuleTest.java | 8 ++++---- .../main/java/org/testcontainers/ext/ScriptUtils.java | 5 +++-- .../testcontainers/containers/JdbcDatabaseContainer.java | 9 +++++---- .../org/testcontainers/containers/ToxiproxyTest.java | 7 ++++--- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java b/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java index e9b34692319..63a86e0200b 100644 --- a/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java +++ b/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java @@ -73,14 +73,14 @@ public void waitUntil(Predicate predicate, int limit, TimeUnit limi */ public void waitUntil(Predicate predicate, long limit, TimeUnit limitUnit, int times) throws TimeoutException { - long expiry = limitUnit.toMillis(limit) + System.currentTimeMillis(); + long expiry = limitUnit.toNanos(limit) + System.nanoTime(); waitUntil(predicate, expiry, times); } private void waitUntil(Predicate predicate, long expiry, int times) throws TimeoutException { int numberOfMatches = 0; - while (System.currentTimeMillis() < expiry) { + while (System.nanoTime() < expiry) { try { OutputFrame frame = frames.pollLast(100, TimeUnit.MILLISECONDS); @@ -129,13 +129,13 @@ public void waitUntilEnd() { * @param limitUnit maximum time to wait (units) */ public void waitUntilEnd(long limit, TimeUnit limitUnit) throws TimeoutException { - long expiry = limitUnit.toMillis(limit) + System.currentTimeMillis(); + long expiry = limitUnit.toNanos(limit) + System.nanoTime(); waitUntilEnd(expiry); } private void waitUntilEnd(Long expiry) throws TimeoutException { - while (System.currentTimeMillis() < expiry) { + while (System.nanoTime() < expiry) { try { OutputFrame frame = frames.pollLast(100, TimeUnit.MILLISECONDS); diff --git a/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java b/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java index a3628a9302f..f9dce94efb9 100644 --- a/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java +++ b/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java @@ -330,7 +330,7 @@ protected static void writeStringToFile(File contentFolder, String filename, Str @Test @Ignore //TODO investigate intermittent failures public void failFastWhenContainerHaltsImmediately() { - long startingTimeMs = System.currentTimeMillis(); + long startingTimeNano = System.nanoTime(); final GenericContainer failsImmediately = new GenericContainer<>(TestImages.ALPINE_IMAGE) .withCommand("/bin/sh", "-c", "return false") .withMinimumRunningDuration(Duration.ofMillis(100)); @@ -342,11 +342,11 @@ public void failFastWhenContainerHaltsImmediately() { // Check how long it took, to verify that we ARE bailing out early. // Want to strike a balance here; too short and this test will fail intermittently - // on slow systems and/or due to GC variation, too long and we won't properly test + // on slow systems and/or due to GC variation, too long, and we won't properly test // what we're intending to test. int allowedSecondsToFailure = GenericContainer.CONTAINER_RUNNING_TIMEOUT_SEC / 2; - long completedTimeMs = System.currentTimeMillis(); - assertThat(completedTimeMs - startingTimeMs < 1000L * allowedSecondsToFailure) + long completedTimeNano = System.nanoTime(); + assertThat(completedTimeNano - startingTimeNano < TimeUnit.SECONDS.toNanos(allowedSecondsToFailure)) .as("container should not take long to start up") .isTrue(); } finally { diff --git a/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java b/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java index eca4989c70e..fc297e94309 100644 --- a/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java +++ b/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java @@ -16,6 +16,7 @@ package org.testcontainers.ext; +import java.util.concurrent.TimeUnit; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -424,7 +425,7 @@ public static void executeDatabaseScript( LOGGER.info("Executing database script from " + scriptPath); } - long startTime = System.currentTimeMillis(); + long startTime = System.nanoTime(); List statements = new LinkedList<>(); if (separator == null) { @@ -448,7 +449,7 @@ public static void executeDatabaseScript( closeableDelegate.execute(statements, scriptPath, continueOnError, ignoreFailedDrops); } - long elapsedTime = System.currentTimeMillis() - startTime; + long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime); if (LOGGER.isInfoEnabled()) { LOGGER.info("Executed database script from " + scriptPath + " in " + elapsedTime + " ms."); } diff --git a/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java b/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java index 88c418e73cb..f73d630f859 100644 --- a/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java +++ b/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java @@ -1,6 +1,7 @@ package org.testcontainers.containers; import com.github.dockerjava.api.command.InspectContainerResponse; +import java.util.concurrent.TimeUnit; import lombok.NonNull; import lombok.SneakyThrows; import org.apache.commons.lang3.StringUtils; @@ -149,10 +150,10 @@ protected void waitUntilContainerStarted() { ); // Repeatedly try and open a connection to the DB and execute a test query - long start = System.currentTimeMillis(); + long start = System.nanoTime(); Exception lastConnectionException = null; - while (System.currentTimeMillis() < start + (1000 * startupTimeoutSeconds)) { + while ((System.nanoTime() - start) < TimeUnit.SECONDS.toNanos(startupTimeoutSeconds)) { if (!isRunning()) { Thread.sleep(100L); } else { @@ -239,9 +240,9 @@ public Connection createConnection(String queryString, Properties info) SQLException lastException = null; try { - long start = System.currentTimeMillis(); + long start = System.nanoTime(); // give up if we hit the time limit or the container stops running for some reason - while (System.currentTimeMillis() < start + (1000 * connectTimeoutSeconds) && isRunning()) { + while ((System.nanoTime() - start < TimeUnit.SECONDS.toNanos(connectTimeoutSeconds)) && isRunning()) { try { logger() .debug( diff --git a/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java b/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java index f1010758fba..5c1b376decf 100644 --- a/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java +++ b/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java @@ -3,6 +3,7 @@ import eu.rekawek.toxiproxy.Proxy; import eu.rekawek.toxiproxy.ToxiproxyClient; import eu.rekawek.toxiproxy.model.ToxicDirection; +import java.util.concurrent.TimeUnit; import org.junit.Rule; import org.junit.Test; import redis.clients.jedis.Jedis; @@ -181,10 +182,10 @@ private void checkCallWithLatency( int expectedMinLatency, long expectedMaxLatency ) { - final long start = System.currentTimeMillis(); + final long start = System.nanoTime(); String s = jedis.get("somekey"); - final long end = System.currentTimeMillis(); - final long duration = end - start; + final long end = System.nanoTime(); + final long duration = TimeUnit.NANOSECONDS.toMillis(end - start); assertThat(s).as(String.format("access to the container %s works OK", description)).isEqualTo("somevalue"); assertThat(duration >= expectedMinLatency) From c5b9cacd2d692e1436300352c92ac79bc439c889 Mon Sep 17 00:00:00 2001 From: Nateckert Date: Fri, 6 Jan 2023 21:43:57 +0100 Subject: [PATCH 2/4] Fix formatting --- .../src/main/java/org/testcontainers/ext/ScriptUtils.java | 2 +- .../org/testcontainers/containers/JdbcDatabaseContainer.java | 4 ++-- .../java/org/testcontainers/containers/ToxiproxyTest.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java b/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java index fc297e94309..94a5f1a6d75 100644 --- a/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java +++ b/modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java @@ -16,7 +16,6 @@ package org.testcontainers.ext; -import java.util.concurrent.TimeUnit; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -28,6 +27,7 @@ import java.nio.charset.StandardCharsets; import java.util.LinkedList; import java.util.List; +import java.util.concurrent.TimeUnit; import javax.script.ScriptException; diff --git a/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java b/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java index f73d630f859..f4d99f19802 100644 --- a/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java +++ b/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java @@ -1,7 +1,6 @@ package org.testcontainers.containers; import com.github.dockerjava.api.command.InspectContainerResponse; -import java.util.concurrent.TimeUnit; import lombok.NonNull; import lombok.SneakyThrows; import org.apache.commons.lang3.StringUtils; @@ -21,6 +20,7 @@ import java.util.Map; import java.util.Properties; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** @@ -153,7 +153,7 @@ protected void waitUntilContainerStarted() { long start = System.nanoTime(); Exception lastConnectionException = null; - while ((System.nanoTime() - start) < TimeUnit.SECONDS.toNanos(startupTimeoutSeconds)) { + while ((System.nanoTime() - start) < TimeUnit.SECONDS.toNanos(startupTimeoutSeconds)) { if (!isRunning()) { Thread.sleep(100L); } else { diff --git a/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java b/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java index 5c1b376decf..34068e5e49e 100644 --- a/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java +++ b/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java @@ -3,7 +3,6 @@ import eu.rekawek.toxiproxy.Proxy; import eu.rekawek.toxiproxy.ToxiproxyClient; import eu.rekawek.toxiproxy.model.ToxicDirection; -import java.util.concurrent.TimeUnit; import org.junit.Rule; import org.junit.Test; import redis.clients.jedis.Jedis; @@ -11,6 +10,7 @@ import java.io.IOException; import java.time.Duration; +import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; From a81a8afdfb00e7a234bc4acd022d0a956e272a96 Mon Sep 17 00:00:00 2001 From: Nateckert Date: Fri, 3 Feb 2023 16:24:52 +0100 Subject: [PATCH 3/4] Fix time comparison to deal with overflow --- .../containers/output/WaitingConsumer.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java b/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java index 63a86e0200b..e5376be9143 100644 --- a/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java +++ b/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java @@ -42,7 +42,7 @@ public LinkedBlockingDeque getFrames() { * @param predicate a predicate to test against each frame */ public void waitUntil(Predicate predicate) throws TimeoutException { - // ~2.9 million centuries ought to be enough for anyone + // ~2.9 thousands centuries ought to be enough for anyone waitUntil(predicate, Long.MAX_VALUE, 1); } @@ -73,14 +73,17 @@ public void waitUntil(Predicate predicate, int limit, TimeUnit limi */ public void waitUntil(Predicate predicate, long limit, TimeUnit limitUnit, int times) throws TimeoutException { - long expiry = limitUnit.toNanos(limit) + System.nanoTime(); + long timeoutLimitInNanos = limitUnit.toNanos(limit) ; - waitUntil(predicate, expiry, times); + waitUntil(predicate, timeoutLimitInNanos, times); } - private void waitUntil(Predicate predicate, long expiry, int times) throws TimeoutException { + private void waitUntil(Predicate predicate, long timeoutLimitInNanos, int times) throws TimeoutException { int numberOfMatches = 0; - while (System.nanoTime() < expiry) { + + final long startTime = System.nanoTime(); + + while (System.nanoTime() - startTime < timeoutLimitInNanos) { try { OutputFrame frame = frames.pollLast(100, TimeUnit.MILLISECONDS); From 5d04f0cb0b6d62a65718677864bdf994388c9f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Thu, 14 Mar 2024 16:58:18 -0600 Subject: [PATCH 4/4] Fix format --- .../testcontainers/containers/output/WaitingConsumer.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java b/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java index 8d364705bcd..e79c234058e 100644 --- a/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java +++ b/core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java @@ -73,12 +73,13 @@ public void waitUntil(Predicate predicate, int limit, TimeUnit limi */ public void waitUntil(Predicate predicate, long limit, TimeUnit limitUnit, int times) throws TimeoutException { - long timeoutLimitInNanos = limitUnit.toNanos(limit) ; + long timeoutLimitInNanos = limitUnit.toNanos(limit); waitUntil(predicate, timeoutLimitInNanos, times); } - private void waitUntil(Predicate predicate, long timeoutLimitInNanos, int times) throws TimeoutException { + private void waitUntil(Predicate predicate, long timeoutLimitInNanos, int times) + throws TimeoutException { int numberOfMatches = 0; final long startTime = System.nanoTime();