Skip to content

Commit e57f06b

Browse files
testSchedulerCloseWaitsForRunningMerge
1 parent e75c94c commit e57f06b

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

server/src/test/java/org/elasticsearch/index/engine/ThreadPoolMergeSchedulerTests.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,21 @@
3030
import java.io.IOException;
3131
import java.util.ArrayList;
3232
import java.util.List;
33+
import java.util.concurrent.CountDownLatch;
3334
import java.util.concurrent.Semaphore;
3435
import java.util.concurrent.ThreadPoolExecutor;
3536
import java.util.concurrent.atomic.AtomicBoolean;
3637
import java.util.concurrent.atomic.AtomicInteger;
3738

39+
import static org.hamcrest.Matchers.contains;
3840
import static org.hamcrest.Matchers.equalTo;
3941
import static org.hamcrest.Matchers.is;
4042
import static org.hamcrest.Matchers.lessThanOrEqualTo;
4143
import static org.mockito.ArgumentMatchers.any;
4244
import static org.mockito.Mockito.doAnswer;
4345
import static org.mockito.Mockito.mock;
4446
import static org.mockito.Mockito.verify;
47+
import static org.mockito.Mockito.verifyNoInteractions;
4548
import static org.mockito.Mockito.when;
4649

4750
public class ThreadPoolMergeSchedulerTests extends ESTestCase {
@@ -262,6 +265,72 @@ public void testMergesRunConcurrently() throws Exception {
262265
}
263266
}
264267

268+
public void testSchedulerCloseWaitsForRunningMerge() throws Exception {
269+
int mergeSchedulerMaxThreadCount = randomIntBetween(1, 3);
270+
int mergeExecutorThreadCount = randomIntBetween(1, 3);
271+
Settings settings = Settings.builder()
272+
.put(settingsWithMergeScheduler)
273+
.put(EsExecutors.NODE_PROCESSORS_SETTING.getKey(), mergeExecutorThreadCount)
274+
.put(MergeSchedulerConfig.MAX_THREAD_COUNT_SETTING.getKey(), mergeSchedulerMaxThreadCount)
275+
.build();
276+
try (TestThreadPool testThreadPool = new TestThreadPool("test", settings)) {
277+
ThreadPoolMergeExecutorService threadPoolMergeExecutorService = ThreadPoolMergeExecutorService
278+
.maybeCreateThreadPoolMergeExecutorService(testThreadPool, settings);
279+
assertNotNull(threadPoolMergeExecutorService);
280+
assertThat(threadPoolMergeExecutorService.getMaxConcurrentMerges(), equalTo(mergeExecutorThreadCount));
281+
ThreadPoolMergeScheduler threadPoolMergeScheduler = new ThreadPoolMergeScheduler(
282+
new ShardId("index", "_na_", 1),
283+
IndexSettingsModule.newIndexSettings("index", settings),
284+
threadPoolMergeExecutorService
285+
);
286+
CountDownLatch mergeDoneLatch = new CountDownLatch(1);
287+
MergeSource mergeSource = mock(MergeSource.class);
288+
OneMerge oneMerge = mock(OneMerge.class);
289+
when(oneMerge.getStoreMergeInfo()).thenReturn(getNewMergeInfo(randomLongBetween(1L, 10L)));
290+
when(oneMerge.getMergeProgress()).thenReturn(new MergePolicy.OneMergeProgress());
291+
when(mergeSource.getNextMerge()).thenReturn(oneMerge, (OneMerge) null);
292+
doAnswer(invocation -> {
293+
OneMerge merge = (OneMerge) invocation.getArguments()[0];
294+
assertFalse(merge.isAborted());
295+
// wait to be signalled before completing the merge
296+
mergeDoneLatch.await();
297+
return null;
298+
}).when(mergeSource).merge(any(OneMerge.class));
299+
threadPoolMergeScheduler.merge(mergeSource, randomFrom(MergeTrigger.values()));
300+
Thread t = new Thread(() -> {
301+
try {
302+
threadPoolMergeScheduler.close();
303+
} catch (IOException e) {
304+
fail(e);
305+
}
306+
});
307+
t.start();
308+
try {
309+
assertTrue(t.isAlive());
310+
// ensure the merge scheduler is effectively "closed"
311+
assertBusy(() -> {
312+
MergeSource mergeSource2 = mock(MergeSource.class);
313+
threadPoolMergeScheduler.merge(mergeSource2, randomFrom(MergeTrigger.values()));
314+
// when the merge scheduler is closed it won't pull in any new merges from the merge source
315+
verifyNoInteractions(mergeSource2);
316+
});
317+
// assert the merge still shows up as "running"
318+
assertThat(threadPoolMergeScheduler.getCurrentlyRunningMergeTasks().keySet(), contains(oneMerge));
319+
assertThat(threadPoolMergeScheduler.getBackloggedMergeTasks().size(), is(0));
320+
assertTrue(t.isAlive());
321+
// signal the merge to finish
322+
mergeDoneLatch.countDown();
323+
} finally {
324+
t.join();
325+
}
326+
assertBusy(() -> {
327+
assertThat(threadPoolMergeScheduler.getCurrentlyRunningMergeTasks().size(), is(0));
328+
assertThat(threadPoolMergeScheduler.getBackloggedMergeTasks().size(), is(0));
329+
assertTrue(threadPoolMergeExecutorService.allDone());
330+
});
331+
}
332+
}
333+
265334
public void testAutoIOThrottleForMergeTasksWhenSchedulerDisablesIt() throws Exception {
266335
// merge scheduler configured with auto IO throttle disabled
267336
Settings settings = Settings.builder()

0 commit comments

Comments
 (0)