Skip to content

Commit 8c32686

Browse files
author
Sachin Kale
committed
Add more unit tests
Signed-off-by: Sachin Kale <[email protected]>
1 parent a077464 commit 8c32686

File tree

2 files changed

+144
-4
lines changed

2 files changed

+144
-4
lines changed

server/src/main/java/org/opensearch/index/translog/RemoteFsTranslog.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ public class RemoteFsTranslog extends Translog {
8181

8282
private final Logger logger;
8383
private final TranslogTransferManager translogTransferManager;
84+
// This tracker keeps track of local tranlog files that are uploaded to remote store.
85+
// Once tlog files are deleted from local, we remove them from tracker even if the files still exist in remote translog.
8486
private final FileTransferTracker fileTransferTracker;
8587
private final BooleanSupplier startedPrimarySupplier;
8688
private final RemoteTranslogTransferTracker remoteTranslogTransferTracker;

server/src/test/java/org/opensearch/index/translog/RemoteFsTranslogWithPinnedTimestampTests.java

Lines changed: 142 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
import java.io.IOException;
4646
import java.util.ArrayList;
47+
import java.util.HashMap;
4748
import java.util.HashSet;
4849
import java.util.List;
4950
import java.util.Map;
@@ -52,10 +53,13 @@
5253
import java.util.TreeSet;
5354
import java.util.concurrent.CountDownLatch;
5455
import java.util.function.Supplier;
56+
import java.util.stream.Collectors;
57+
import java.util.stream.LongStream;
5558

5659
import org.mockito.Mockito;
5760

5861
import static org.opensearch.index.translog.TranslogDeletionPolicies.createTranslogDeletionPolicy;
62+
import static org.opensearch.index.translog.transfer.TranslogTransferMetadata.METADATA_SEPARATOR;
5963
import static org.opensearch.indices.RemoteStoreSettings.CLUSTER_REMOTE_STORE_PINNED_TIMESTAMP_ENABLED;
6064
import static org.junit.Assert.fail;
6165
import static org.mockito.ArgumentMatchers.any;
@@ -304,6 +308,91 @@ public void testMetadataFileDeletion() throws Exception {
304308
assertBusy(() -> { assertEquals(1, blobStoreTransferService.listAll(getTranslogDirectory().add(METADATA_DIR)).size()); });
305309
}
306310

311+
public void testMetadataFileDeletionWithPinnedTimestamps() throws Exception {
312+
ArrayList<Translog.Operation> ops = new ArrayList<>();
313+
// Test deletion of metadata files
314+
int numDocs = randomIntBetween(16, 20);
315+
for (int i = 0; i < numDocs; i++) {
316+
addToTranslogAndListAndUpload(translog, ops, new Translog.Index(String.valueOf(i), i, primaryTerm.get(), new byte[] { 1 }));
317+
translog.setMinSeqNoToKeep(i);
318+
assertBusy(() -> assertTrue(translog.isRemoteGenerationDeletionPermitsAvailable()));
319+
translog.trimUnreferencedReaders();
320+
// This is just to make sure that each metadata is at least 1ms apart
321+
Thread.sleep(1);
322+
}
323+
324+
CountDownLatch latch = new CountDownLatch(1);
325+
blobStoreTransferService.listAllInSortedOrder(
326+
getTranslogDirectory().add(METADATA_DIR),
327+
"metadata",
328+
Integer.MAX_VALUE,
329+
new LatchedActionListener<>(new ActionListener<>() {
330+
@Override
331+
public void onResponse(List<BlobMetadata> blobMetadataList) {
332+
List<String> pinnedTimestampMatchingMetadataFiles = new ArrayList<>();
333+
List<Long> pinnedTimestamps = new ArrayList<>();
334+
for (BlobMetadata blobMetadata : blobMetadataList) {
335+
String metadataFilename = blobMetadata.name();
336+
if (randomBoolean()) {
337+
long timestamp = RemoteStoreUtils.invertLong(metadataFilename.split(METADATA_SEPARATOR)[3]);
338+
pinnedTimestamps.add(timestamp);
339+
pinnedTimestampMatchingMetadataFiles.add(metadataFilename);
340+
}
341+
}
342+
343+
doAnswer(invocationOnMock -> {
344+
ActionListener<List<BlobMetadata>> actionListener = invocationOnMock.getArgument(3);
345+
actionListener.onResponse(List.of(new PlainBlobMetadata("pinned_timestamp_123", 1000)));
346+
return null;
347+
}).when(pinnedTimestampBlobStoreTransferService).listAllInSortedOrder(any(), any(), eq(1), any());
348+
349+
Map<Long, List<String>> pinnedTimestampsMap = new HashMap<>();
350+
pinnedTimestamps.forEach(ts -> pinnedTimestampsMap.put(ts, new ArrayList<>()));
351+
352+
try {
353+
when(remoteStorePinnedTimestampsBlobStore.read(any())).thenReturn(
354+
new RemotePinnedTimestamps.PinnedTimestamps(pinnedTimestampsMap)
355+
);
356+
when(remoteStorePinnedTimestampsBlobStore.getBlobPathForUpload(any())).thenReturn(new BlobPath());
357+
358+
updatePinnedTimstampTask.run();
359+
RemoteStoreSettings.setPinnedTimestampsLookbackInterval(TimeValue.ZERO);
360+
translog.trimUnreferencedReaders();
361+
assertBusy(() -> assertTrue(translog.isRemoteGenerationDeletionPermitsAvailable()));
362+
363+
Set<String> metadataFilesAfterTrim = blobStoreTransferService.listAll(getTranslogDirectory().add(METADATA_DIR));
364+
Set<String> dataFilesAfterTrim = blobStoreTransferService.listAll(
365+
getTranslogDirectory().add(DATA_DIR).add(String.valueOf(primaryTerm.get()))
366+
);
367+
368+
// We check for number of pinned timestamp or +1 due to latest metadata.
369+
assertTrue(
370+
metadataFilesAfterTrim.size() == pinnedTimestamps.size()
371+
|| metadataFilesAfterTrim.size() == pinnedTimestamps.size() + 1
372+
);
373+
374+
for (String md : pinnedTimestampMatchingMetadataFiles) {
375+
assertTrue(metadataFilesAfterTrim.contains(md));
376+
Tuple<Long, Long> minMaXGen = TranslogTransferMetadata.getMinMaxTranslogGenerationFromFilename(md);
377+
for (long i = minMaXGen.v1(); i <= minMaXGen.v2(); i++) {
378+
assertTrue(dataFilesAfterTrim.contains(Translog.getFilename(i)));
379+
}
380+
}
381+
} catch (Exception e) {
382+
fail();
383+
}
384+
}
385+
386+
@Override
387+
public void onFailure(Exception e) {
388+
fail();
389+
}
390+
}, latch)
391+
);
392+
393+
latch.await();
394+
}
395+
307396
@Override
308397
public void testDrainSync() throws Exception {
309398
RemoteStoreSettings.setPinnedTimestampsLookbackInterval(TimeValue.ZERO);
@@ -452,10 +541,59 @@ ChannelFactory getChannelFactory() {
452541
}
453542
}
454543

455-
// getGenerationsToBeDeleted
456-
public void testGetGenerationsToBeDeleted() {
457-
// translog.readAndCacheGenerationForPinnedTimestamp
458-
// translog.getGenerationsToBeDeleted
544+
public void testGetGenerationsToBeDeletedEmptyMetadataFilesNotToBeDeleted() throws IOException {
545+
List<String> metadataFilesNotToBeDeleted = new ArrayList<>();
546+
List<String> metadataFilesToBeDeleted = List.of(
547+
// 4 to 7
548+
"metadata__9223372036438563903__9223372036854775800__9223370311919910398__31__9223372036854775803__1",
549+
// 17 to 37
550+
"metadata__9223372036438563903__9223372036854775770__9223370311919910398__31__9223372036854775790__1",
551+
// 27 to 42
552+
"metadata__9223372036438563903__9223372036854775765__9223370311919910403__31__9223372036854775780__1"
553+
);
554+
Set<Long> generations = translog.getGenerationsToBeDeleted(metadataFilesNotToBeDeleted, metadataFilesToBeDeleted, true);
555+
Set<Long> md1Generations = LongStream.rangeClosed(4, 7).boxed().collect(Collectors.toSet());
556+
Set<Long> md2Generations = LongStream.rangeClosed(17, 37).boxed().collect(Collectors.toSet());
557+
Set<Long> md3Generations = LongStream.rangeClosed(27, 42).boxed().collect(Collectors.toSet());
558+
assertTrue(generations.containsAll(md1Generations));
559+
assertTrue(generations.containsAll(md2Generations));
560+
assertTrue(generations.containsAll(md3Generations));
561+
562+
generations.removeAll(md1Generations);
563+
generations.removeAll(md2Generations);
564+
generations.removeAll(md3Generations);
565+
assertTrue(generations.isEmpty());
566+
}
567+
568+
public void testGetGenerationsToBeDeleted() throws IOException {
569+
List<String> metadataFilesNotToBeDeleted = List.of(
570+
// 1 to 4
571+
"metadata__9223372036438563903__9223372036854775803__9223370311919910398__31__9223372036854775806__1",
572+
// 26 to 30
573+
"metadata__9223372036438563903__9223372036854775777__9223370311919910398__31__9223372036854775781__1",
574+
// 42 to 100
575+
"metadata__9223372036438563903__9223372036854775707__9223370311919910403__31__9223372036854775765__1"
576+
);
577+
List<String> metadataFilesToBeDeleted = List.of(
578+
// 4 to 7
579+
"metadata__9223372036438563903__9223372036854775800__9223370311919910398__31__9223372036854775803__1",
580+
// 17 to 37
581+
"metadata__9223372036438563903__9223372036854775770__9223370311919910398__31__9223372036854775790__1",
582+
// 27 to 42
583+
"metadata__9223372036438563903__9223372036854775765__9223370311919910403__31__9223372036854775780__1"
584+
);
585+
Set<Long> generations = translog.getGenerationsToBeDeleted(metadataFilesNotToBeDeleted, metadataFilesToBeDeleted, true);
586+
Set<Long> md1Generations = LongStream.rangeClosed(5, 7).boxed().collect(Collectors.toSet());
587+
Set<Long> md2Generations = LongStream.rangeClosed(17, 25).boxed().collect(Collectors.toSet());
588+
Set<Long> md3Generations = LongStream.rangeClosed(31, 41).boxed().collect(Collectors.toSet());
589+
assertTrue(generations.containsAll(md1Generations));
590+
assertTrue(generations.containsAll(md2Generations));
591+
assertTrue(generations.containsAll(md3Generations));
592+
593+
generations.removeAll(md1Generations);
594+
generations.removeAll(md2Generations);
595+
generations.removeAll(md3Generations);
596+
assertTrue(generations.isEmpty());
459597
}
460598

461599
public void testGetMetadataFilesToBeDeletedNoExclusion() {

0 commit comments

Comments
 (0)