reddycharan commented on a change in pull request #1391: Issue #570: 
EntryLogManagerForEntryLogPerLedger implementation
URL: https://github.com/apache/bookkeeper/pull/1391#discussion_r188808410
 
 

 ##########
 File path: 
bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/CreateNewLogTest.java
 ##########
 @@ -142,6 +151,237 @@ public void testCreateNewLogWithNoWritableLedgerDirs() 
throws Exception {
         assertTrue("Wrong log id", entryLogManager.getCurrentLogId() > 1);
     }
 
+    /*
+     * entryLogPerLedger is enabled and various scenarios of entrylogcreation 
are tested
+     */
+    @Test
+    public void testEntryLogPerLedgerCreationWithPreAllocation() throws 
Exception {
+        /*
+         * I wish I could shorten this testcase or split it into multiple 
testcases,
+         * but I want to cover a scenario and it requires multiple operations 
in
+         * sequence and validations along the way. Please bear with the length 
of this
+         * testcase, I added as many comments as I can to simplify it.
+         */
+
+        ServerConfiguration conf = 
TestBKConfiguration.newServerConfiguration();
+
+        // Creating a new configuration with a number of ledger directories.
+        conf.setLedgerDirNames(ledgerDirs);
+        conf.setIsForceGCAllowWhenNoSpace(true);
+        // preAllocation is Enabled
+        conf.setEntryLogFilePreAllocationEnabled(true);
+        conf.setEntryLogPerLedgerEnabled(true);
+        LedgerDirsManager ledgerDirsManager = new LedgerDirsManager(conf, 
conf.getLedgerDirs(),
+                new DiskChecker(conf.getDiskUsageThreshold(), 
conf.getDiskUsageWarnThreshold()));
+        EntryLogger entryLogger = new EntryLogger(conf, ledgerDirsManager);
+        EntryLoggerAllocator entryLoggerAllocator = 
entryLogger.entryLoggerAllocator;
+        EntryLogManagerForEntryLogPerLedger entryLogManager = 
(EntryLogManagerForEntryLogPerLedger) entryLogger
+                .getEntryLogManager();
+
+        /*
+         * no entrylog will be created during initialization
+         */
+        int expectedPreAllocatedLogID = -1;
+        Assert.assertEquals("PreallocatedlogId after initialization of 
Entrylogger",
+                expectedPreAllocatedLogID, 
entryLoggerAllocator.getPreallocatedLogId());
+
+        int numOfLedgers = 6;
+
+        for (long i = 0; i < numOfLedgers; i++) {
+            /* since we are starting creation of new ledgers, entrylogid will 
be ledgerid */
+            entryLogManager.createNewLog(i);
+        }
+
+        Thread.sleep(100);
+        /*
+         * preallocation is enabled so though entryLogId starts with 0, 
preallocatedLogId would be equal to numOfLedgers
+         */
+        expectedPreAllocatedLogID = numOfLedgers;
+        Assert.assertEquals("PreallocatedlogId after creation of logs for 
ledgers", expectedPreAllocatedLogID,
+                entryLoggerAllocator.getPreallocatedLogId());
+        Assert.assertEquals("Number of current ", numOfLedgers,
+                entryLogManager.getCopyOfCurrentLogs().size());
+        Assert.assertEquals("Number of LogChannels to flush", 0,
+                entryLogManager.getRotatedLogChannels().size());
+
+        // create dummy entrylog file with id - (expectedPreAllocatedLogID + 1)
+        String logFileName = Long.toHexString(expectedPreAllocatedLogID + 1) + 
".log";
+        File dir = ledgerDirsManager.pickRandomWritableDir();
+        LOG.info("Picked this directory: " + dir);
+        File newLogFile = new File(dir, logFileName);
+        newLogFile.createNewFile();
+
+        /*
+         * since there is already preexisting entrylog file with id -
+         * (expectedPreAllocatedLogIDDuringInitialization + 1), when new
+         * entrylog is created it should have
+         * (expectedPreAllocatedLogIDDuringInitialization + 2) id
+         */
+        long rotatedLedger = 1L;
+        entryLogManager.createNewLog(rotatedLedger);
+        Thread.sleep(100);
+        expectedPreAllocatedLogID = expectedPreAllocatedLogID + 2;
+        Assert.assertEquals("PreallocatedlogId ",
+                expectedPreAllocatedLogID, 
entryLoggerAllocator.getPreallocatedLogId());
+        Assert.assertEquals("Number of current ", numOfLedgers,
+                entryLogManager.getCopyOfCurrentLogs().size());
+        List<BufferedLogChannel> rotatedLogChannels = 
entryLogManager.getRotatedLogChannels();
+        Assert.assertEquals("Number of LogChannels rotated", 1, 
rotatedLogChannels.size());
+        Assert.assertEquals("Rotated logchannel logid", rotatedLedger, 
rotatedLogChannels.iterator().next().getLogId());
+        entryLogger.flush();
+        /*
+         * when flush is called all the rotatedlogchannels are flushed and
+         * removed from rotatedlogchannels list. But here since entrylogId - 0,
+         * is not yet rotated and flushed yet, getLeastUnflushedLogId will 
still
+         * return 0.
+         */
+        rotatedLogChannels = entryLogManager.getRotatedLogChannels();
+        Assert.assertEquals("Number of LogChannels rotated", 0, 
rotatedLogChannels.size());
+        Assert.assertEquals("Least UnflushedLoggerId", 0, 
entryLogger.getLeastUnflushedLogId());
+
+        entryLogManager.createNewLog(0L);
+        rotatedLogChannels = entryLogManager.getRotatedLogChannels();
+        Assert.assertEquals("Number of LogChannels rotated", 1, 
rotatedLogChannels.size());
+        Assert.assertEquals("Least UnflushedLoggerId", 0, 
entryLogger.getLeastUnflushedLogId());
+        entryLogger.flush();
+        /*
+         * since both entrylogids 0, 1 are rotated and flushed,
+         * leastunFlushedLogId should be 2
+         */
+        Assert.assertEquals("Least UnflushedLoggerId", 2, 
entryLogger.getLeastUnflushedLogId());
+        expectedPreAllocatedLogID = expectedPreAllocatedLogID + 1;
+
+        /*
+         * we should be able to get entryLogMetadata from all the active
+         * entrylogs and the logs which are moved toflush list. Since no entry
+         * is added, all the meta should be empty.
+         */
+        for (int i = 0; i <= expectedPreAllocatedLogID; i++) {
+            EntryLogMetadata meta = entryLogger.getEntryLogMetadata(i);
+            Assert.assertTrue("EntryLogMetadata should be empty", 
meta.isEmpty());
+            Assert.assertTrue("EntryLog usage should be 0", 
meta.getTotalSize() == 0);
+        }
+    }
+
+    /**
+     * In this testcase entryLogPerLedger is Enabled and entrylogs are created
+     * while ledgerdirs are getting full.
+     */
+    @Test
+    public void testEntryLogCreationWithFilledDirs() throws Exception {
+        ServerConfiguration conf = 
TestBKConfiguration.newServerConfiguration();
+
+        // Creating a new configuration with a number of ledger directories.
+        conf.setLedgerDirNames(ledgerDirs);
+        // forceGCAllowWhenNoSpace is disabled
+        conf.setIsForceGCAllowWhenNoSpace(false);
+        // pre-allocation is not enabled
+        conf.setEntryLogFilePreAllocationEnabled(false);
+        conf.setEntryLogPerLedgerEnabled(true);
+        LedgerDirsManager ledgerDirsManager = new LedgerDirsManager(conf, 
conf.getLedgerDirs(),
+                new DiskChecker(conf.getDiskUsageThreshold(), 
conf.getDiskUsageWarnThreshold()));
+        EntryLogger entryLogger = new EntryLogger(conf, ledgerDirsManager);
+        EntryLoggerAllocator entryLoggerAllocator = 
entryLogger.entryLoggerAllocator;
+        EntryLogManagerForEntryLogPerLedger entryLogManager = 
(EntryLogManagerForEntryLogPerLedger)
+                entryLogger.getEntryLogManager();
+
+        Thread.sleep(200);
+        int expectedPreAllocatedLogIDDuringInitialization = -1;
+        Assert.assertEquals("PreallocatedlogId after initialization of 
Entrylogger",
+                expectedPreAllocatedLogIDDuringInitialization, 
entryLoggerAllocator.getPreallocatedLogId());
+        Assert.assertEquals("Preallocation Future of this slot should be 
null", null,
+                entryLogger.entryLoggerAllocator.preallocation);
+
+        long ledgerId = 0L;
+
+        entryLogManager.createNewLog(ledgerId);
+        Thread.sleep(100);
+        /*
+         * pre-allocation is not enabled, so it would not preallocate for next 
entrylog
+         */
+        Assert.assertEquals("PreallocatedlogId after initialization of 
Entrylogger",
+                expectedPreAllocatedLogIDDuringInitialization + 1, 
entryLoggerAllocator.getPreallocatedLogId());
+
+        for (int i = 0; i < numDirs - 1; i++) {
+            ledgerDirsManager.addToFilledDirs(Bookie.getCurrentDirectory(new 
File(ledgerDirs[i])));
+        }
+
+        /*
+         * this is the only non-filled ledgerDir so it should be used for 
creating new entryLog
+         */
+        File nonFilledLedgerDir = Bookie.getCurrentDirectory(new 
File(ledgerDirs[numDirs - 1]));
+
+        entryLogManager.createNewLog(ledgerId);
+        BufferedLogChannel newLogChannel = 
entryLogManager.getCurrentLogForLedger(ledgerId);
+        Assert.assertEquals("Directory of newly created BufferedLogChannel 
file", nonFilledLedgerDir.getAbsolutePath(),
+                newLogChannel.getLogFile().getParentFile().getAbsolutePath());
+
+        ledgerDirsManager.addToFilledDirs(Bookie.getCurrentDirectory(new 
File(ledgerDirs[numDirs - 1])));
+
+        // new entrylog creation should succeed, though there is no writable 
ledgerDir
+        entryLogManager.createNewLog(ledgerId);
+    }
+
+    /*
+     * In this testcase it is validated if the entryLog is created in the
+     * ledgerDir with least number of current active entrylogs
+     */
+    @Test(timeout = 60000)
 
 Review comment:
   yes, will remove

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to