Skip to content

Commit 6e5fbe6

Browse files
Nateckerteddumelendez
andauthored
Avoid usage of the non monotonic clock System.currentTimeMillis() in favor of System.nanoTime() (#6392)
Co-authored-by: Eddú Meléndez Gonzales <[email protected]>
1 parent 8c3cce2 commit 6e5fbe6

File tree

5 files changed

+27
-20
lines changed

5 files changed

+27
-20
lines changed

core/src/main/java/org/testcontainers/containers/output/WaitingConsumer.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public LinkedBlockingDeque<OutputFrame> getFrames() {
4242
* @param predicate a predicate to test against each frame
4343
*/
4444
public void waitUntil(Predicate<OutputFrame> predicate) throws TimeoutException {
45-
// ~2.9 million centuries ought to be enough for anyone
45+
// ~2.9 thousands centuries ought to be enough for anyone
4646
waitUntil(predicate, Long.MAX_VALUE, 1);
4747
}
4848

@@ -73,14 +73,18 @@ public void waitUntil(Predicate<OutputFrame> predicate, int limit, TimeUnit limi
7373
*/
7474
public void waitUntil(Predicate<OutputFrame> predicate, long limit, TimeUnit limitUnit, int times)
7575
throws TimeoutException {
76-
long expiry = limitUnit.toMillis(limit) + System.currentTimeMillis();
76+
long timeoutLimitInNanos = limitUnit.toNanos(limit);
7777

78-
waitUntil(predicate, expiry, times);
78+
waitUntil(predicate, timeoutLimitInNanos, times);
7979
}
8080

81-
private void waitUntil(Predicate<OutputFrame> predicate, long expiry, int times) throws TimeoutException {
81+
private void waitUntil(Predicate<OutputFrame> predicate, long timeoutLimitInNanos, int times)
82+
throws TimeoutException {
8283
int numberOfMatches = 0;
83-
while (System.currentTimeMillis() < expiry) {
84+
85+
final long startTime = System.nanoTime();
86+
87+
while (System.nanoTime() - startTime < timeoutLimitInNanos) {
8488
try {
8589
final OutputFrame frame = frames.pollLast(100, TimeUnit.MILLISECONDS);
8690

@@ -128,13 +132,13 @@ public void waitUntilEnd() {
128132
* @param limitUnit maximum time to wait (units)
129133
*/
130134
public void waitUntilEnd(long limit, TimeUnit limitUnit) throws TimeoutException {
131-
long expiry = limitUnit.toMillis(limit) + System.currentTimeMillis();
135+
long expiry = limitUnit.toNanos(limit) + System.nanoTime();
132136

133137
waitUntilEnd(expiry);
134138
}
135139

136140
private void waitUntilEnd(Long expiry) throws TimeoutException {
137-
while (System.currentTimeMillis() < expiry) {
141+
while (System.nanoTime() < expiry) {
138142
try {
139143
OutputFrame frame = frames.pollLast(100, TimeUnit.MILLISECONDS);
140144

core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ protected static void writeStringToFile(File contentFolder, String filename, Str
333333
@Test
334334
@Ignore //TODO investigate intermittent failures
335335
public void failFastWhenContainerHaltsImmediately() {
336-
long startingTimeMs = System.currentTimeMillis();
336+
long startingTimeNano = System.nanoTime();
337337
final GenericContainer failsImmediately = new GenericContainer<>(TestImages.ALPINE_IMAGE)
338338
.withCommand("/bin/sh", "-c", "return false")
339339
.withMinimumRunningDuration(Duration.ofMillis(100));
@@ -345,11 +345,11 @@ public void failFastWhenContainerHaltsImmediately() {
345345

346346
// Check how long it took, to verify that we ARE bailing out early.
347347
// Want to strike a balance here; too short and this test will fail intermittently
348-
// on slow systems and/or due to GC variation, too long and we won't properly test
348+
// on slow systems and/or due to GC variation, too long, and we won't properly test
349349
// what we're intending to test.
350350
int allowedSecondsToFailure = GenericContainer.CONTAINER_RUNNING_TIMEOUT_SEC / 2;
351-
long completedTimeMs = System.currentTimeMillis();
352-
assertThat(completedTimeMs - startingTimeMs < 1000L * allowedSecondsToFailure)
351+
long completedTimeNano = System.nanoTime();
352+
assertThat(completedTimeNano - startingTimeNano < TimeUnit.SECONDS.toNanos(allowedSecondsToFailure))
353353
.as("container should not take long to start up")
354354
.isTrue();
355355
} finally {

modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.nio.charset.StandardCharsets;
2828
import java.util.LinkedList;
2929
import java.util.List;
30+
import java.util.concurrent.TimeUnit;
3031

3132
import javax.script.ScriptException;
3233

@@ -273,7 +274,7 @@ public static void executeDatabaseScript(
273274
LOGGER.info("Executing database script from " + scriptPath);
274275
}
275276

276-
long startTime = System.currentTimeMillis();
277+
long startTime = System.nanoTime();
277278
List<String> statements = new LinkedList<>();
278279

279280
if (separator == null) {
@@ -306,7 +307,7 @@ public static void executeDatabaseScript(
306307
closeableDelegate.execute(statements, scriptPath, continueOnError, ignoreFailedDrops);
307308
}
308309

309-
long elapsedTime = System.currentTimeMillis() - startTime;
310+
long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime);
310311
if (LOGGER.isInfoEnabled()) {
311312
LOGGER.info("Executed database script from " + scriptPath + " in " + elapsedTime + " ms.");
312313
}

modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.Map;
2222
import java.util.Properties;
2323
import java.util.concurrent.Future;
24+
import java.util.concurrent.TimeUnit;
2425
import java.util.stream.Collectors;
2526

2627
/**
@@ -148,10 +149,10 @@ protected void waitUntilContainerStarted() {
148149
);
149150

150151
// Repeatedly try and open a connection to the DB and execute a test query
151-
long start = System.currentTimeMillis();
152+
long start = System.nanoTime();
152153

153154
Exception lastConnectionException = null;
154-
while (System.currentTimeMillis() < start + (1000 * startupTimeoutSeconds)) {
155+
while ((System.nanoTime() - start) < TimeUnit.SECONDS.toNanos(startupTimeoutSeconds)) {
155156
if (!isRunning()) {
156157
Thread.sleep(100L);
157158
} else {
@@ -238,9 +239,9 @@ public Connection createConnection(String queryString, Properties info)
238239

239240
SQLException lastException = null;
240241
try {
241-
long start = System.currentTimeMillis();
242+
long start = System.nanoTime();
242243
// give up if we hit the time limit or the container stops running for some reason
243-
while (System.currentTimeMillis() < start + (1000 * connectTimeoutSeconds) && isRunning()) {
244+
while ((System.nanoTime() - start < TimeUnit.SECONDS.toNanos(connectTimeoutSeconds)) && isRunning()) {
244245
try {
245246
logger()
246247
.debug(

modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import java.io.IOException;
1212
import java.time.Duration;
13+
import java.util.concurrent.TimeUnit;
1314

1415
import static org.assertj.core.api.Assertions.assertThat;
1516
import static org.assertj.core.api.Assertions.catchThrowable;
@@ -181,10 +182,10 @@ private void checkCallWithLatency(
181182
int expectedMinLatency,
182183
long expectedMaxLatency
183184
) {
184-
final long start = System.currentTimeMillis();
185+
final long start = System.nanoTime();
185186
String s = jedis.get("somekey");
186-
final long end = System.currentTimeMillis();
187-
final long duration = end - start;
187+
final long end = System.nanoTime();
188+
final long duration = TimeUnit.NANOSECONDS.toMillis(end - start);
188189

189190
assertThat(s).as(String.format("access to the container %s works OK", description)).isEqualTo("somevalue");
190191
assertThat(duration >= expectedMinLatency)

0 commit comments

Comments
 (0)