Skip to content

Commit 3f3033b

Browse files
matrivbleskes
authored andcommitted
[Tests] Make testEngineGCDeletesSetting deterministic (#38942)
`InternalEngine.resolveDocVersion()` uses `relativeTimeInMillis()` from `ThreadPool` so it needs, the cached time to be advanced. Add a check to ensure that and decrease the `thread_pool.estimated_time_interval` to 1msec to prevent long running times for the test. Fixes: #38874 Co-authored-by: Boaz Leskes <[email protected]>
1 parent f0ff5fe commit 3f3033b

File tree

3 files changed

+49
-9
lines changed

3 files changed

+49
-9
lines changed

server/src/main/java/org/elasticsearch/threadpool/ThreadPool.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ public Collection<ExecutorBuilder> builders() {
162162
}
163163

164164
public static Setting<TimeValue> ESTIMATED_TIME_INTERVAL_SETTING =
165-
Setting.timeSetting("thread_pool.estimated_time_interval", TimeValue.timeValueMillis(200), Setting.Property.NodeScope);
165+
Setting.timeSetting("thread_pool.estimated_time_interval",
166+
TimeValue.timeValueMillis(200), TimeValue.ZERO, Setting.Property.NodeScope);
166167

167168
public ThreadPool(final Settings settings, final ExecutorBuilder<?>... customBuilders) {
168169
assert Node.NODE_NAME_SETTING.exists(settings);
@@ -552,22 +553,36 @@ static class CachedTimeThread extends Thread {
552553
/**
553554
* Return the current time used for relative calculations. This is
554555
* {@link System#nanoTime()} truncated to milliseconds.
556+
* <p>
557+
* If {@link ThreadPool#ESTIMATED_TIME_INTERVAL_SETTING} is set to 0
558+
* then the cache is disabled and the method calls {@link System#nanoTime()}
559+
* whenever called. Typically used for testing.
555560
*/
556561
long relativeTimeInMillis() {
557-
return relativeMillis;
562+
if (0 < interval) {
563+
return relativeMillis;
564+
}
565+
return TimeValue.nsecToMSec(System.nanoTime());
558566
}
559567

560568
/**
561569
* Return the current epoch time, used to find absolute time. This is
562570
* a cached version of {@link System#currentTimeMillis()}.
571+
* <p>
572+
* If {@link ThreadPool#ESTIMATED_TIME_INTERVAL_SETTING} is set to 0
573+
* then the cache is disabled and the method calls {@link System#currentTimeMillis()}
574+
* whenever called. Typically used for testing.
563575
*/
564576
long absoluteTimeInMillis() {
565-
return absoluteMillis;
577+
if (0 < interval) {
578+
return absoluteMillis;
579+
}
580+
return System.currentTimeMillis();
566581
}
567582

568583
@Override
569584
public void run() {
570-
while (running) {
585+
while (running && 0 < interval) {
571586
relativeMillis = TimeValue.nsecToMSec(System.nanoTime());
572587
absoluteMillis = System.currentTimeMillis();
573588
try {

server/src/test/java/org/elasticsearch/indices/settings/UpdateSettingsIT.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.elasticsearch.indices.IndicesService;
3232
import org.elasticsearch.plugins.Plugin;
3333
import org.elasticsearch.test.ESIntegTestCase;
34+
import org.elasticsearch.threadpool.ThreadPool;
3435

3536
import java.util.Arrays;
3637
import java.util.Collection;
@@ -46,6 +47,7 @@
4647
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertThrows;
4748
import static org.hamcrest.Matchers.containsString;
4849
import static org.hamcrest.Matchers.equalTo;
50+
import static org.hamcrest.Matchers.greaterThan;
4951
import static org.hamcrest.Matchers.nullValue;
5052

5153
public class UpdateSettingsIT extends ESIntegTestCase {
@@ -125,6 +127,16 @@ public List<Setting<?>> getSettings() {
125127
}
126128
}
127129

130+
/**
131+
* Needed by {@link UpdateSettingsIT#testEngineGCDeletesSetting()}
132+
*/
133+
@Override
134+
protected Settings nodeSettings(int nodeOrdinal) {
135+
return Settings.builder().put(super.nodeSettings(nodeOrdinal))
136+
.put("thread_pool.estimated_time_interval", 0)
137+
.build();
138+
}
139+
128140
public void testUpdateDependentClusterSettings() {
129141
IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () ->
130142
client().admin().cluster().prepareUpdateSettings().setPersistentSettings(Settings.builder()
@@ -434,7 +446,7 @@ public void testOpenCloseUpdateSettings() throws Exception {
434446
assertThat(getSettingsResponse.getSetting("test", "index.final"), nullValue());
435447
}
436448

437-
public void testEngineGCDeletesSetting() throws InterruptedException {
449+
public void testEngineGCDeletesSetting() throws Exception {
438450
createIndex("test");
439451
client().prepareIndex("test", "type", "1").setSource("f", 1).get(); // set version to 1
440452
client().prepareDelete("test", "type", "1").get(); // sets version to 2
@@ -443,11 +455,16 @@ public void testEngineGCDeletesSetting() throws InterruptedException {
443455
client().admin().indices().prepareUpdateSettings("test").setSettings(Settings.builder().put("index.gc_deletes", 0)).get();
444456

445457
client().prepareDelete("test", "type", "1").get(); // sets version to 4
446-
Thread.sleep(300); // wait for cache time to change TODO: this needs to be solved better. To be discussed.
447-
// delete is should not be in cache
448-
assertThrows(client().prepareIndex("test", "type", "1").setSource("f", 3)
449-
.setVersion(4), VersionConflictEngineException.class);
450458

459+
// Make sure the time has advanced for InternalEngine#resolveDocVersion()
460+
for (ThreadPool threadPool : internalCluster().getInstances(ThreadPool.class)) {
461+
long startTime = threadPool.relativeTimeInMillis();
462+
assertBusy(() -> assertThat(threadPool.relativeTimeInMillis(), greaterThan(startTime)));
463+
}
464+
465+
// delete is should not be in cache
466+
assertThrows(
467+
client().prepareIndex("test", "type", "1").setSource("f", 3).setVersion(4), VersionConflictEngineException.class);
451468
}
452469

453470
public void testUpdateSettingsWithBlocks() {

server/src/test/java/org/elasticsearch/threadpool/ThreadPoolTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919

2020
package org.elasticsearch.threadpool;
2121

22+
import org.elasticsearch.common.settings.Settings;
2223
import org.elasticsearch.test.ESTestCase;
2324

25+
import static org.elasticsearch.threadpool.ThreadPool.ESTIMATED_TIME_INTERVAL_SETTING;
2426
import static org.hamcrest.CoreMatchers.equalTo;
2527

2628
public class ThreadPoolTests extends ESTestCase {
@@ -59,4 +61,10 @@ public void testAbsoluteTime() throws Exception {
5961
threadPool.close();
6062
}
6163
}
64+
65+
public void testEstimatedTimeIntervalSettingAcceptsOnlyZeroAndPositiveTime() {
66+
Settings settings = Settings.builder().put("thread_pool.estimated_time_interval", -1).build();
67+
Exception e = expectThrows(IllegalArgumentException.class, () -> ESTIMATED_TIME_INTERVAL_SETTING.get(settings));
68+
assertEquals("failed to parse value [-1] for setting [thread_pool.estimated_time_interval], must be >= [0ms]", e.getMessage());
69+
}
6270
}

0 commit comments

Comments
 (0)