|
@@ -32,11 +32,11 @@ import org.apache.lucene.index.Term;
|
|
|
import org.apache.lucene.store.BaseDirectoryWrapper;
|
|
|
import org.apache.lucene.store.Directory;
|
|
|
import org.apache.lucene.store.IOContext;
|
|
|
-import org.apache.lucene.util.SetOnce;
|
|
|
+import org.apache.lucene.util.BytesRef;
|
|
|
+import org.apache.lucene.util.BytesRefIterator;
|
|
|
import org.elasticsearch.ExceptionsHelper;
|
|
|
import org.elasticsearch.Version;
|
|
|
import org.elasticsearch.action.ActionListener;
|
|
|
-import org.elasticsearch.action.LatchedActionListener;
|
|
|
import org.elasticsearch.action.support.PlainActionFuture;
|
|
|
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
|
|
import org.elasticsearch.cluster.node.DiscoveryNode;
|
|
@@ -77,7 +77,6 @@ import org.elasticsearch.test.CorruptionUtils;
|
|
|
import org.elasticsearch.test.DummyShardLock;
|
|
|
import org.elasticsearch.test.ESTestCase;
|
|
|
import org.elasticsearch.test.IndexSettingsModule;
|
|
|
-import org.elasticsearch.threadpool.FixedExecutorBuilder;
|
|
|
import org.elasticsearch.threadpool.TestThreadPool;
|
|
|
import org.elasticsearch.threadpool.ThreadPool;
|
|
|
import org.junit.After;
|
|
@@ -94,11 +93,10 @@ import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.concurrent.CopyOnWriteArrayList;
|
|
|
-import java.util.concurrent.CountDownLatch;
|
|
|
-import java.util.concurrent.Executor;
|
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
|
+import java.util.concurrent.atomic.AtomicReference;
|
|
|
import java.util.function.IntSupplier;
|
|
|
import java.util.zip.CRC32;
|
|
|
|
|
@@ -107,7 +105,7 @@ import static java.util.Collections.emptySet;
|
|
|
import static org.hamcrest.Matchers.containsString;
|
|
|
import static org.hamcrest.Matchers.equalTo;
|
|
|
import static org.hamcrest.Matchers.hasSize;
|
|
|
-import static org.hamcrest.Matchers.instanceOf;
|
|
|
+import static org.hamcrest.core.IsNull.notNullValue;
|
|
|
import static org.mockito.Matchers.any;
|
|
|
import static org.mockito.Matchers.anyBoolean;
|
|
|
import static org.mockito.Matchers.anyObject;
|
|
@@ -123,19 +121,10 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
private final ClusterSettings service = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
|
|
|
|
|
|
private ThreadPool threadPool;
|
|
|
- private Executor recoveryExecutor;
|
|
|
|
|
|
@Before
|
|
|
public void setUpThreadPool() {
|
|
|
- if (randomBoolean()) {
|
|
|
- threadPool = new TestThreadPool(getTestName());
|
|
|
- recoveryExecutor = threadPool.generic();
|
|
|
- } else {
|
|
|
- // verify that both sending and receiving files can be completed with a single thread
|
|
|
- threadPool = new TestThreadPool(getTestName(),
|
|
|
- new FixedExecutorBuilder(Settings.EMPTY, "recovery_executor", between(1, 16), between(16, 128), "recovery_executor"));
|
|
|
- recoveryExecutor = threadPool.executor("recovery_executor");
|
|
|
- }
|
|
|
+ threadPool = new TestThreadPool(getTestName());
|
|
|
}
|
|
|
|
|
|
@After
|
|
@@ -144,7 +133,9 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
}
|
|
|
|
|
|
public void testSendFiles() throws Throwable {
|
|
|
- final RecoverySettings recoverySettings = new RecoverySettings(Settings.EMPTY, service);
|
|
|
+ Settings settings = Settings.builder().put("indices.recovery.concurrent_streams", 1).
|
|
|
+ put("indices.recovery.concurrent_small_file_streams", 1).build();
|
|
|
+ final RecoverySettings recoverySettings = new RecoverySettings(settings, service);
|
|
|
final StartRecoveryRequest request = getStartRecoveryRequest();
|
|
|
Store store = newStore(createTempDir());
|
|
|
Directory dir = store.directory();
|
|
@@ -165,22 +156,38 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
metas.add(md);
|
|
|
}
|
|
|
Store targetStore = newStore(createTempDir());
|
|
|
- MultiFileWriter multiFileWriter = new MultiFileWriter(targetStore, mock(RecoveryState.Index.class), "", logger, () -> {});
|
|
|
RecoveryTargetHandler target = new TestRecoveryTargetHandler() {
|
|
|
+ IndexOutputOutputStream out;
|
|
|
@Override
|
|
|
public void writeFileChunk(StoreFileMetaData md, long position, BytesReference content, boolean lastChunk,
|
|
|
int totalTranslogOps, ActionListener<Void> listener) {
|
|
|
- ActionListener.completeWith(listener, () -> {
|
|
|
- multiFileWriter.writeFileChunk(md, position, content, lastChunk);
|
|
|
- return null;
|
|
|
- });
|
|
|
+ try {
|
|
|
+ if (position == 0) {
|
|
|
+ out = new IndexOutputOutputStream(targetStore.createVerifyingOutput(md.name(), md, IOContext.DEFAULT)) {
|
|
|
+ @Override
|
|
|
+ public void close() throws IOException {
|
|
|
+ super.close();
|
|
|
+ targetStore.directory().sync(Collections.singleton(md.name())); // sync otherwise MDW will mess with it
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+ final BytesRefIterator iterator = content.iterator();
|
|
|
+ BytesRef scratch;
|
|
|
+ while ((scratch = iterator.next()) != null) {
|
|
|
+ out.write(scratch.bytes, scratch.offset, scratch.length);
|
|
|
+ }
|
|
|
+ if (lastChunk) {
|
|
|
+ out.close();
|
|
|
+ }
|
|
|
+ listener.onResponse(null);
|
|
|
+ } catch (Exception e) {
|
|
|
+ listener.onFailure(e);
|
|
|
+ }
|
|
|
}
|
|
|
};
|
|
|
- RecoverySourceHandler handler = new RecoverySourceHandler(null, new AsyncRecoveryTarget(target, recoveryExecutor),
|
|
|
- threadPool, request, Math.toIntExact(recoverySettings.getChunkSize().getBytes()), between(1, 5));
|
|
|
- PlainActionFuture<Void> sendFilesFuture = new PlainActionFuture<>();
|
|
|
- handler.sendFiles(store, metas.toArray(new StoreFileMetaData[0]), () -> 0, sendFilesFuture);
|
|
|
- sendFilesFuture.actionGet();
|
|
|
+ RecoverySourceHandler handler = new RecoverySourceHandler(null, target, request,
|
|
|
+ Math.toIntExact(recoverySettings.getChunkSize().getBytes()), between(1, 5));
|
|
|
+ handler.sendFiles(store, metas.toArray(new StoreFileMetaData[0]), () -> 0);
|
|
|
Store.MetadataSnapshot targetStoreMetadata = targetStore.getMetadata(null);
|
|
|
Store.RecoveryDiff recoveryDiff = targetStoreMetadata.recoveryDiff(metadata);
|
|
|
assertEquals(metas.size(), recoveryDiff.identical.size());
|
|
@@ -188,7 +195,7 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
assertEquals(0, recoveryDiff.missing.size());
|
|
|
IndexReader reader = DirectoryReader.open(targetStore.directory());
|
|
|
assertEquals(numDocs, reader.maxDoc());
|
|
|
- IOUtils.close(reader, store, multiFileWriter, targetStore);
|
|
|
+ IOUtils.close(reader, store, targetStore);
|
|
|
}
|
|
|
|
|
|
public StartRecoveryRequest getStartRecoveryRequest() throws IOException {
|
|
@@ -234,11 +241,10 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
RetentionLeases retentionLeases, long mappingVersion, ActionListener<Long> listener) {
|
|
|
shippedOps.addAll(operations);
|
|
|
checkpointOnTarget.set(randomLongBetween(checkpointOnTarget.get(), Long.MAX_VALUE));
|
|
|
- listener.onResponse(checkpointOnTarget.get());
|
|
|
- }
|
|
|
+ listener.onResponse(checkpointOnTarget.get()); }
|
|
|
};
|
|
|
- RecoverySourceHandler handler = new RecoverySourceHandler(shard, new AsyncRecoveryTarget(recoveryTarget, threadPool.generic()),
|
|
|
- threadPool, request, fileChunkSizeInBytes, between(1, 10));
|
|
|
+ RecoverySourceHandler handler = new RecoverySourceHandler(
|
|
|
+ shard, new AsyncRecoveryTarget(recoveryTarget, threadPool.generic()), request, fileChunkSizeInBytes, between(1, 10));
|
|
|
PlainActionFuture<RecoverySourceHandler.SendSnapshotResult> future = new PlainActionFuture<>();
|
|
|
handler.phase2(startingSeqNo, endingSeqNo, newTranslogSnapshot(operations, Collections.emptyList()),
|
|
|
randomNonNegativeLong(), randomNonNegativeLong(), RetentionLeases.EMPTY, randomNonNegativeLong(), future);
|
|
@@ -277,8 +283,8 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
- RecoverySourceHandler handler = new RecoverySourceHandler(shard, new AsyncRecoveryTarget(recoveryTarget, threadPool.generic()),
|
|
|
- threadPool, request, fileChunkSizeInBytes, between(1, 10));
|
|
|
+ RecoverySourceHandler handler = new RecoverySourceHandler(
|
|
|
+ shard, new AsyncRecoveryTarget(recoveryTarget, threadPool.generic()), request, fileChunkSizeInBytes, between(1, 10));
|
|
|
PlainActionFuture<RecoverySourceHandler.SendSnapshotResult> future = new PlainActionFuture<>();
|
|
|
final long startingSeqNo = randomLongBetween(0, ops.size() - 1L);
|
|
|
final long endingSeqNo = randomLongBetween(startingSeqNo, ops.size() - 1L);
|
|
@@ -337,36 +343,52 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
(p.getFileName().toString().equals("write.lock") ||
|
|
|
p.getFileName().toString().startsWith("extra")) == false));
|
|
|
Store targetStore = newStore(createTempDir(), false);
|
|
|
- MultiFileWriter multiFileWriter = new MultiFileWriter(targetStore, mock(RecoveryState.Index.class), "", logger, () -> {});
|
|
|
RecoveryTargetHandler target = new TestRecoveryTargetHandler() {
|
|
|
+ IndexOutputOutputStream out;
|
|
|
@Override
|
|
|
public void writeFileChunk(StoreFileMetaData md, long position, BytesReference content, boolean lastChunk,
|
|
|
int totalTranslogOps, ActionListener<Void> listener) {
|
|
|
- ActionListener.completeWith(listener, () -> {
|
|
|
- multiFileWriter.writeFileChunk(md, position, content, lastChunk);
|
|
|
- return null;
|
|
|
- });
|
|
|
+ try {
|
|
|
+ if (position == 0) {
|
|
|
+ out = new IndexOutputOutputStream(targetStore.createVerifyingOutput(md.name(), md, IOContext.DEFAULT)) {
|
|
|
+ @Override
|
|
|
+ public void close() throws IOException {
|
|
|
+ super.close();
|
|
|
+ targetStore.directory().sync(Collections.singleton(md.name())); // sync otherwise MDW will mess with it
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+ final BytesRefIterator iterator = content.iterator();
|
|
|
+ BytesRef scratch;
|
|
|
+ while ((scratch = iterator.next()) != null) {
|
|
|
+ out.write(scratch.bytes, scratch.offset, scratch.length);
|
|
|
+ }
|
|
|
+ if (lastChunk) {
|
|
|
+ out.close();
|
|
|
+ }
|
|
|
+ listener.onResponse(null);
|
|
|
+ } catch (Exception e) {
|
|
|
+ IOUtils.closeWhileHandlingException(out, () -> listener.onFailure(e));
|
|
|
+ }
|
|
|
}
|
|
|
};
|
|
|
- RecoverySourceHandler handler = new RecoverySourceHandler(null, new AsyncRecoveryTarget(target, recoveryExecutor), threadPool,
|
|
|
- request, Math.toIntExact(recoverySettings.getChunkSize().getBytes()), between(1, 8)) {
|
|
|
+ RecoverySourceHandler handler = new RecoverySourceHandler(null, target, request,
|
|
|
+ Math.toIntExact(recoverySettings.getChunkSize().getBytes()), between(1, 8)) {
|
|
|
@Override
|
|
|
protected void failEngine(IOException cause) {
|
|
|
assertFalse(failedEngine.get());
|
|
|
failedEngine.set(true);
|
|
|
}
|
|
|
};
|
|
|
- SetOnce<Exception> sendFilesError = new SetOnce<>();
|
|
|
- CountDownLatch latch = new CountDownLatch(1);
|
|
|
- handler.sendFiles(store, metas.toArray(new StoreFileMetaData[0]), () -> 0,
|
|
|
- new LatchedActionListener<>(ActionListener.wrap(r -> sendFilesError.set(null), e -> sendFilesError.set(e)), latch));
|
|
|
- latch.await();
|
|
|
- assertThat(sendFilesError.get(), instanceOf(IOException.class));
|
|
|
- assertNotNull(ExceptionsHelper.unwrapCorruption(sendFilesError.get()));
|
|
|
+
|
|
|
+ try {
|
|
|
+ handler.sendFiles(store, metas.toArray(new StoreFileMetaData[0]), () -> 0);
|
|
|
+ fail("corrupted index");
|
|
|
+ } catch (IOException ex) {
|
|
|
+ assertNotNull(ExceptionsHelper.unwrapCorruption(ex));
|
|
|
+ }
|
|
|
assertTrue(failedEngine.get());
|
|
|
- // ensure all chunk requests have been completed; otherwise some files on the target are left open.
|
|
|
- IOUtils.close(() -> terminate(threadPool), () -> threadPool = null);
|
|
|
- IOUtils.close(store, multiFileWriter, targetStore);
|
|
|
+ IOUtils.close(store, targetStore);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -405,24 +427,28 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
- RecoverySourceHandler handler = new RecoverySourceHandler(null, new AsyncRecoveryTarget(target, recoveryExecutor), threadPool,
|
|
|
- request, Math.toIntExact(recoverySettings.getChunkSize().getBytes()), between(1, 10)) {
|
|
|
+ RecoverySourceHandler handler = new RecoverySourceHandler(null, target, request,
|
|
|
+ Math.toIntExact(recoverySettings.getChunkSize().getBytes()), between(1, 10)) {
|
|
|
@Override
|
|
|
protected void failEngine(IOException cause) {
|
|
|
assertFalse(failedEngine.get());
|
|
|
failedEngine.set(true);
|
|
|
}
|
|
|
};
|
|
|
- PlainActionFuture<Void> sendFilesFuture = new PlainActionFuture<>();
|
|
|
- handler.sendFiles(store, metas.toArray(new StoreFileMetaData[0]), () -> 0, sendFilesFuture);
|
|
|
- Exception ex = expectThrows(Exception.class, sendFilesFuture::actionGet);
|
|
|
- final IOException unwrappedCorruption = ExceptionsHelper.unwrapCorruption(ex);
|
|
|
- if (throwCorruptedIndexException) {
|
|
|
- assertNotNull(unwrappedCorruption);
|
|
|
- assertEquals(ex.getMessage(), "[File corruption occurred on recovery but checksums are ok]");
|
|
|
- } else {
|
|
|
- assertNull(unwrappedCorruption);
|
|
|
- assertEquals(ex.getMessage(), "boom");
|
|
|
+ try {
|
|
|
+ handler.sendFiles(store, metas.toArray(new StoreFileMetaData[0]), () -> 0);
|
|
|
+ fail("exception index");
|
|
|
+ } catch (RuntimeException ex) {
|
|
|
+ final IOException unwrappedCorruption = ExceptionsHelper.unwrapCorruption(ex);
|
|
|
+ if (throwCorruptedIndexException) {
|
|
|
+ assertNotNull(unwrappedCorruption);
|
|
|
+ assertEquals(ex.getMessage(), "[File corruption occurred on recovery but checksums are ok]");
|
|
|
+ } else {
|
|
|
+ assertNull(unwrappedCorruption);
|
|
|
+ assertEquals(ex.getMessage(), "boom");
|
|
|
+ }
|
|
|
+ } catch (CorruptIndexException ex) {
|
|
|
+ fail("not expected here");
|
|
|
}
|
|
|
assertFalse(failedEngine.get());
|
|
|
IOUtils.close(store);
|
|
@@ -446,7 +472,6 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
final RecoverySourceHandler handler = new RecoverySourceHandler(
|
|
|
shard,
|
|
|
mock(RecoveryTargetHandler.class),
|
|
|
- threadPool,
|
|
|
request,
|
|
|
Math.toIntExact(recoverySettings.getChunkSize().getBytes()),
|
|
|
between(1, 8)) {
|
|
@@ -525,13 +550,19 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
};
|
|
|
final int maxConcurrentChunks = between(1, 8);
|
|
|
final int chunkSize = between(1, 32);
|
|
|
- final RecoverySourceHandler handler = new RecoverySourceHandler(shard, recoveryTarget, threadPool, getStartRecoveryRequest(),
|
|
|
+ final RecoverySourceHandler handler = new RecoverySourceHandler(shard, recoveryTarget, getStartRecoveryRequest(),
|
|
|
chunkSize, maxConcurrentChunks);
|
|
|
Store store = newStore(createTempDir(), false);
|
|
|
List<StoreFileMetaData> files = generateFiles(store, between(1, 10), () -> between(1, chunkSize * 20));
|
|
|
int totalChunks = files.stream().mapToInt(md -> ((int) md.length() + chunkSize - 1) / chunkSize).sum();
|
|
|
- PlainActionFuture<Void> sendFilesFuture = new PlainActionFuture<>();
|
|
|
- handler.sendFiles(store, files.toArray(new StoreFileMetaData[0]), () -> 0, sendFilesFuture);
|
|
|
+ Thread sender = new Thread(() -> {
|
|
|
+ try {
|
|
|
+ handler.sendFiles(store, files.toArray(new StoreFileMetaData[0]), () -> 0);
|
|
|
+ } catch (Exception ex) {
|
|
|
+ throw new AssertionError(ex);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ sender.start();
|
|
|
assertBusy(() -> {
|
|
|
assertThat(sentChunks.get(), equalTo(Math.min(totalChunks, maxConcurrentChunks)));
|
|
|
assertThat(unrepliedChunks, hasSize(sentChunks.get()));
|
|
@@ -563,11 +594,13 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
assertThat(unrepliedChunks, hasSize(expectedUnrepliedChunks));
|
|
|
});
|
|
|
}
|
|
|
- sendFilesFuture.actionGet();
|
|
|
+ sender.join();
|
|
|
store.close();
|
|
|
}
|
|
|
|
|
|
public void testSendFileChunksStopOnError() throws Exception {
|
|
|
+ final IndexShard shard = mock(IndexShard.class);
|
|
|
+ when(shard.state()).thenReturn(IndexShardState.STARTED);
|
|
|
final List<FileChunkResponse> unrepliedChunks = new CopyOnWriteArrayList<>();
|
|
|
final AtomicInteger sentChunks = new AtomicInteger();
|
|
|
final TestRecoveryTargetHandler recoveryTarget = new TestRecoveryTargetHandler() {
|
|
@@ -583,23 +616,23 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
};
|
|
|
final int maxConcurrentChunks = between(1, 4);
|
|
|
final int chunkSize = between(1, 16);
|
|
|
- final RecoverySourceHandler handler = new RecoverySourceHandler(null, new AsyncRecoveryTarget(recoveryTarget, recoveryExecutor),
|
|
|
- threadPool, getStartRecoveryRequest(), chunkSize, maxConcurrentChunks);
|
|
|
+ final RecoverySourceHandler handler = new RecoverySourceHandler(shard, recoveryTarget, getStartRecoveryRequest(),
|
|
|
+ chunkSize, maxConcurrentChunks);
|
|
|
Store store = newStore(createTempDir(), false);
|
|
|
List<StoreFileMetaData> files = generateFiles(store, between(1, 10), () -> between(1, chunkSize * 20));
|
|
|
int totalChunks = files.stream().mapToInt(md -> ((int) md.length() + chunkSize - 1) / chunkSize).sum();
|
|
|
- SetOnce<Exception> sendFilesError = new SetOnce<>();
|
|
|
- CountDownLatch sendFilesLatch = new CountDownLatch(1);
|
|
|
- handler.sendFiles(store, files.toArray(new StoreFileMetaData[0]), () -> 0,
|
|
|
- new LatchedActionListener<>(ActionListener.wrap(r -> sendFilesError.set(null), e -> sendFilesError.set(e)), sendFilesLatch));
|
|
|
+ AtomicReference<Exception> error = new AtomicReference<>();
|
|
|
+ Thread sender = new Thread(() -> {
|
|
|
+ try {
|
|
|
+ handler.sendFiles(store, files.toArray(new StoreFileMetaData[0]), () -> 0);
|
|
|
+ } catch (Exception ex) {
|
|
|
+ error.set(ex);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ sender.start();
|
|
|
assertBusy(() -> assertThat(sentChunks.get(), equalTo(Math.min(totalChunks, maxConcurrentChunks))));
|
|
|
List<FileChunkResponse> failedChunks = randomSubsetOf(between(1, unrepliedChunks.size()), unrepliedChunks);
|
|
|
- CountDownLatch replyLatch = new CountDownLatch(failedChunks.size());
|
|
|
- failedChunks.forEach(c -> {
|
|
|
- c.listener.onFailure(new IllegalStateException("test chunk exception"));
|
|
|
- replyLatch.countDown();
|
|
|
- });
|
|
|
- replyLatch.await();
|
|
|
+ failedChunks.forEach(c -> c.listener.onFailure(new RuntimeException("test chunk exception")));
|
|
|
unrepliedChunks.removeAll(failedChunks);
|
|
|
unrepliedChunks.forEach(c -> {
|
|
|
if (randomBoolean()) {
|
|
@@ -608,10 +641,12 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
c.listener.onResponse(null);
|
|
|
}
|
|
|
});
|
|
|
- sendFilesLatch.await();
|
|
|
- assertThat(sendFilesError.get(), instanceOf(IllegalStateException.class));
|
|
|
- assertThat(sendFilesError.get().getMessage(), containsString("test chunk exception"));
|
|
|
+ assertBusy(() -> {
|
|
|
+ assertThat(error.get(), notNullValue());
|
|
|
+ assertThat(error.get().getMessage(), containsString("test chunk exception"));
|
|
|
+ });
|
|
|
assertThat("no more chunks should be sent", sentChunks.get(), equalTo(Math.min(totalChunks, maxConcurrentChunks)));
|
|
|
+ sender.join();
|
|
|
store.close();
|
|
|
}
|
|
|
|
|
@@ -619,7 +654,7 @@ public class RecoverySourceHandlerTests extends ESTestCase {
|
|
|
IndexShard shard = mock(IndexShard.class);
|
|
|
when(shard.state()).thenReturn(IndexShardState.STARTED);
|
|
|
RecoverySourceHandler handler = new RecoverySourceHandler(
|
|
|
- shard, new TestRecoveryTargetHandler(), threadPool, getStartRecoveryRequest(), between(1, 16), between(1, 4));
|
|
|
+ shard, new TestRecoveryTargetHandler(), getStartRecoveryRequest(), between(1, 16), between(1, 4));
|
|
|
|
|
|
String syncId = UUIDs.randomBase64UUID();
|
|
|
int numDocs = between(0, 1000);
|