Skip to content

Commit d975f93

Browse files
Use stricter timer in DeadHostStateTests (#38301)
With this commit we add a monotonically strict timer to ensure time is advancing even if the timer is called in a tight loop in tests. We also relax a condition in a similar test so it only checks that time is not moving backwards. Closes #33747
1 parent 85b4bfe commit d975f93

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

client/rest/src/test/java/org/elasticsearch/client/DeadHostStateTests.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020
package org.elasticsearch.client;
2121

2222
import java.util.concurrent.TimeUnit;
23+
import java.util.concurrent.atomic.AtomicLong;
2324

2425
import org.elasticsearch.client.DeadHostState.TimeSupplier;
2526

2627
import static org.hamcrest.MatcherAssert.assertThat;
2728
import static org.hamcrest.Matchers.equalTo;
2829
import static org.hamcrest.Matchers.greaterThan;
30+
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
2931
import static org.hamcrest.Matchers.is;
3032
import static org.hamcrest.Matchers.lessThan;
3133
import static org.junit.Assert.assertEquals;
@@ -36,10 +38,9 @@ public class DeadHostStateTests extends RestClientTestCase {
3638
private static long[] EXPECTED_TIMEOUTS_SECONDS = new long[]{60, 84, 120, 169, 240, 339, 480, 678, 960, 1357, 1800};
3739

3840
public void testInitialDeadHostStateDefaultTimeSupplier() {
39-
assumeFalse("https://github.com/elastic/elasticsearch/issues/33747", System.getProperty("os.name").startsWith("Windows"));
4041
DeadHostState deadHostState = new DeadHostState(DeadHostState.TimeSupplier.DEFAULT);
4142
long currentTime = System.nanoTime();
42-
assertThat(deadHostState.getDeadUntilNanos(), greaterThan(currentTime));
43+
assertThat(deadHostState.getDeadUntilNanos(), greaterThanOrEqualTo(currentTime));
4344
assertThat(deadHostState.getFailedAttempts(), equalTo(1));
4445
}
4546

@@ -54,13 +55,13 @@ public void testDeadHostStateFromPreviousDefaultTimeSupplier() {
5455
}
5556
}
5657

57-
public void testCompareToDefaultTimeSupplier() {
58-
assumeFalse("https://github.com/elastic/elasticsearch/issues/33747", System.getProperty("os.name").startsWith("Windows"));
58+
public void testCompareToTimeSupplier() {
5959
int numObjects = randomIntBetween(EXPECTED_TIMEOUTS_SECONDS.length, 30);
6060
DeadHostState[] deadHostStates = new DeadHostState[numObjects];
6161
for (int i = 0; i < numObjects; i++) {
6262
if (i == 0) {
63-
deadHostStates[i] = new DeadHostState(DeadHostState.TimeSupplier.DEFAULT);
63+
// this test requires a strictly increasing timer
64+
deadHostStates[i] = new DeadHostState(new StrictMonotonicTimeSupplier());
6465
} else {
6566
deadHostStates[i] = new DeadHostState(deadHostStates[i - 1]);
6667
}
@@ -136,4 +137,23 @@ public String toString() {
136137
return "configured[" + nanoTime + "]";
137138
}
138139
}
140+
141+
/**
142+
* Simulates a monotonically strict increasing time (i.e. the value increases on every call to <code>#nanoTime()</code>). This ensures
143+
* that even if we call this time supplier in a very tight loop we always notice time moving forward. This does not happen for real
144+
* timer implementations (e.g. on Linux <code>clock_gettime</code> provides microsecond resolution).
145+
*/
146+
static class StrictMonotonicTimeSupplier implements DeadHostState.TimeSupplier {
147+
private final AtomicLong time = new AtomicLong(0);
148+
149+
@Override
150+
public long nanoTime() {
151+
return time.incrementAndGet();
152+
}
153+
154+
@Override
155+
public String toString() {
156+
return "strict monotonic[" + time.get() + "]";
157+
}
158+
}
139159
}

0 commit comments

Comments
 (0)