|
@@ -61,6 +61,7 @@ import java.util.Map;
|
|
|
import java.util.Random;
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
import java.util.concurrent.ConcurrentMap;
|
|
|
+import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
@@ -132,6 +133,8 @@ public class MockRepository extends FsRepository {
|
|
|
|
|
|
private volatile boolean blockOnReadIndexMeta;
|
|
|
|
|
|
+ private final AtomicBoolean blockOnceOnReadSnapshotInfo = new AtomicBoolean(false);
|
|
|
+
|
|
|
/**
|
|
|
* Writes to the blob {@code index.latest} at the repository root will fail with an {@link IOException} if {@code true}.
|
|
|
*/
|
|
@@ -206,6 +209,7 @@ public class MockRepository extends FsRepository {
|
|
|
blockOnDeleteIndexN = false;
|
|
|
blockOnWriteShardLevelMeta = false;
|
|
|
blockOnReadIndexMeta = false;
|
|
|
+ blockOnceOnReadSnapshotInfo.set(false);
|
|
|
this.notifyAll();
|
|
|
}
|
|
|
|
|
@@ -247,6 +251,16 @@ public class MockRepository extends FsRepository {
|
|
|
this.failReadsAfterUnblock = failReadsAfterUnblock;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Enable blocking a single read of {@link org.elasticsearch.snapshots.SnapshotInfo} in case the repo is already blocked on another
|
|
|
+ * file. This allows testing very specific timing issues where a read of {@code SnapshotInfo} is much slower than another concurrent
|
|
|
+ * repository operation. See {@link #blockExecution()} for the exact mechanics of why we need a secondary block defined here.
|
|
|
+ * TODO: clean this up to not require a second block set
|
|
|
+ */
|
|
|
+ public void setBlockOnceOnReadSnapshotInfoIfAlreadyBlocked() {
|
|
|
+ blockOnceOnReadSnapshotInfo.set(true);
|
|
|
+ }
|
|
|
+
|
|
|
public boolean blocked() {
|
|
|
return blocked;
|
|
|
}
|
|
@@ -396,7 +410,10 @@ public class MockRepository extends FsRepository {
|
|
|
|
|
|
@Override
|
|
|
public InputStream readBlob(String name) throws IOException {
|
|
|
- if (blockOnReadIndexMeta && name.startsWith(BlobStoreRepository.METADATA_PREFIX) && path().equals(basePath()) == false) {
|
|
|
+ if (blockOnReadIndexMeta && name.startsWith(BlobStoreRepository.METADATA_PREFIX) && path().equals(basePath()) == false) {
|
|
|
+ blockExecutionAndMaybeWait(name);
|
|
|
+ } else if (path().equals(basePath()) && name.startsWith(BlobStoreRepository.SNAPSHOT_PREFIX)
|
|
|
+ && blockOnceOnReadSnapshotInfo.compareAndSet(true, false)) {
|
|
|
blockExecutionAndMaybeWait(name);
|
|
|
} else {
|
|
|
maybeReadErrorAfterBlock(name);
|