callback) {
+ unsupported();
+ }
};
}
diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/GcLedgersTest.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/GcLedgersTest.java
index 422c4efc764..4f03f754a72 100644
--- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/GcLedgersTest.java
+++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/GcLedgersTest.java
@@ -53,9 +53,12 @@
import org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback;
import org.apache.bookkeeper.versioning.Version;
import org.junit.Test;
+import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.collect.Sets;
+
/**
* Test garbage collection ledgers in ledger manager
*/
@@ -300,4 +303,64 @@ public void clean(long ledgerId) {
assertEquals("Should have cleaned something", 1, cleaned.size());
assertEquals("Should have cleaned first ledger" + first, (long) first, (long) cleaned.get(0));
}
+
+ /**
+ * It verifies that GC doesn't delete ledgers which are not deleted and its metadata present into zookeeper even
+ * though ledgerManager derives active ledger as deleted.
+ *
+ *
+ * 1. Create list of ledgers
+ * 2. Mock ledgerManager that derives live ledgers as deleted ledgers
+ * 3. GC performs sanity before deleting ledger and doesn't delete if ledger metadata present
+ *
+ *
+ * @throws Exception
+ */
+ @Test(timeout = 120000)
+ public void testGCTryToDeleteActiveLedgers() throws Exception {
+ final SortedSet createdLedgers = Collections.synchronizedSortedSet(new TreeSet());
+ final List cleaned = new ArrayList();
+
+ final int numLedgers = 100;
+
+ createLedgers(numLedgers, createdLedgers);
+
+ LedgerManager ledgerManager = Mockito.spy(getLedgerManager());
+ LedgerRange range = new LedgerRange(Sets.newHashSet(createdLedgers.first()));
+ AtomicInteger noOfIterations = new AtomicInteger(1);
+
+ LedgerRangeIterator ledgerRangeIterator = new LedgerRangeIterator() {
+ @Override
+ public boolean hasNext() throws IOException {
+ return noOfIterations.get() > 0;
+ }
+
+ @Override
+ public LedgerRange next() throws IOException {
+ noOfIterations.decrementAndGet();
+ return range;
+ }
+ };
+
+ Mockito.doReturn(ledgerRangeIterator).when(ledgerManager).getLedgerRanges();
+
+ final GarbageCollector garbageCollector = new ScanAndCompareGarbageCollector(ledgerManager,
+ new MockLedgerStorage(), null, null, false, baseConf.getZkLedgersRootPath());
+ GarbageCollector.GarbageCleaner cleaner = new GarbageCollector.GarbageCleaner() {
+ @Override
+ public void clean(long ledgerId) {
+ LOG.info("Cleaned {}", ledgerId);
+ cleaned.add(ledgerId);
+ }
+ };
+
+ garbageCollector.gc(cleaner);
+ assertTrue("Should have cleaned nothing", cleaned.isEmpty());
+
+ long first = createdLedgers.first();
+ removeLedger(first);
+ garbageCollector.gc(cleaner);
+ assertEquals("Should have cleaned something", 1, cleaned.size());
+ assertEquals("Should have cleaned first ledger" + first, (long) first, (long) cleaned.get(0));
+ }
}