You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bookkeeper.apache.org by si...@apache.org on 2018/01/24 18:49:00 UTC
[bookkeeper] branch master updated: ISSUE #1041: Adding new
testcases
This is an automated email from the ASF dual-hosted git repository.
sijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git
The following commit(s) were added to refs/heads/master by this push:
new 0ffac5a ISSUE #1041: Adding new testcases
0ffac5a is described below
commit 0ffac5ac9f7c573eab93a43dae86c1a78e1b61de
Author: cguttapalem <cg...@salesforce.com>
AuthorDate: Wed Jan 24 10:48:53 2018 -0800
ISSUE #1041: Adding new testcases
Descriptions of the changes in this PR:
- New Testclass for ZeroBuffer
- New testcases for missing testcoverage in
SortedLedgerStorage, EntryMemTable and LedgerHandleAdv
Master Issue: #1041
Author: cguttapalem <cg...@salesforce.com>
Author: Charan Reddy Guttapalem <cg...@salesforce.com>
Reviewers: Sijie Guo <si...@apache.org>
This closes #1042 from reddycharan/missingtestcases, closes #1041
---
.../bookkeeper/client/BookieWriteLedgerTest.java | 182 +++++++++++++++++++++
.../org/apache/bookkeeper/util/TestZeroBuffer.java | 118 +++++++++++++
2 files changed, 300 insertions(+)
diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieWriteLedgerTest.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieWriteLedgerTest.java
index d3746f4..bae15b8 100644
--- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieWriteLedgerTest.java
+++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieWriteLedgerTest.java
@@ -35,13 +35,16 @@ import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import org.apache.bookkeeper.client.AsyncCallback.AddCallback;
+import org.apache.bookkeeper.client.BKException.BKLedgerClosedException;
import org.apache.bookkeeper.client.BookKeeper.DigestType;
import org.apache.bookkeeper.meta.LongHierarchicalLedgerManagerFactory;
import org.apache.bookkeeper.net.BookieSocketAddress;
import org.apache.bookkeeper.test.BookKeeperClusterTestCase;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
@@ -94,6 +97,11 @@ public class BookieWriteLedgerTest extends
String ledgerManagerFactory = "org.apache.bookkeeper.meta.HierarchicalLedgerManagerFactory";
// set ledger manager
baseConf.setLedgerManagerFactoryClassName(ledgerManagerFactory);
+ /*
+ * 'testLedgerCreateAdvWithLedgerIdInLoop2' testcase relies on skipListSizeLimit,
+ * so setting it to some small value for making that testcase lite.
+ */
+ baseConf.setSkipListSizeLimit(4 * 1024 * 1024);
baseClientConf.setLedgerManagerFactoryClassName(ledgerManagerFactory);
}
@@ -344,6 +352,88 @@ public class BookieWriteLedgerTest extends
}
/*
+ * Verify the functionality of Advanced Ledger which accepts ledgerId as
+ * input and returns LedgerHandleAdv. LedgerHandleAdv takes entryId for
+ * addEntry, and let user manage entryId allocation.
+ * This testcase is mainly added for covering missing code coverage branches
+ * in LedgerHandleAdv
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testLedgerHandleAdvFunctionality() throws Exception {
+ // Create a ledger
+ long ledgerId = 0xABCDEF;
+ lh = bkc.createLedgerAdv(ledgerId, 5, 3, 2, digestType, ledgerPassword, null);
+ numEntriesToWrite = 3;
+
+ ByteBuffer entry = ByteBuffer.allocate(4);
+ entry.putInt(rng.nextInt(maxInt));
+ entry.position(0);
+ entries1.add(entry.array());
+ lh.addEntry(0, entry.array());
+
+ // here asyncAddEntry(final long entryId, final byte[] data, final
+ // AddCallback cb, final Object ctx) method is
+ // called which is not covered in any other testcase
+ entry = ByteBuffer.allocate(4);
+ entry.putInt(rng.nextInt(maxInt));
+ entry.position(0);
+ entries1.add(entry.array());
+ CountDownLatch latch = new CountDownLatch(1);
+ final int[] returnedRC = new int[1];
+ lh.asyncAddEntry(1, entry.array(), new AddCallback() {
+ @Override
+ public void addComplete(int rc, LedgerHandle lh, long entryId, Object ctx) {
+ CountDownLatch latch = (CountDownLatch) ctx;
+ returnedRC[0] = rc;
+ latch.countDown();
+ }
+ }, latch);
+ latch.await();
+ assertTrue("Returned code is expected to be OK", returnedRC[0] == BKException.Code.OK);
+
+ // here addEntry is called with incorrect offset and length
+ entry = ByteBuffer.allocate(4);
+ entry.putInt(rng.nextInt(maxInt));
+ entry.position(0);
+ try {
+ lh.addEntry(2, entry.array(), -3, 9);
+ fail("AddEntry is called with negative offset and incorrect length,"
+ + "so it is expected to throw RuntimeException/IndexOutOfBoundsException");
+ } catch (RuntimeException exception) {
+ // expected RuntimeException/IndexOutOfBoundsException
+ }
+
+ // here addEntry is called with corrected offset and length and it is
+ // supposed to succeed
+ entry = ByteBuffer.allocate(4);
+ entry.putInt(rng.nextInt(maxInt));
+ entry.position(0);
+ entries1.add(entry.array());
+ lh.addEntry(2, entry.array());
+
+ // LedgerHandle is closed for write
+ lh.close();
+
+ // here addEntry is called even after the close of the LedgerHandle, so
+ // it is expected to throw exception
+ entry = ByteBuffer.allocate(4);
+ entry.putInt(rng.nextInt(maxInt));
+ entry.position(0);
+ entries1.add(entry.array());
+ try {
+ lh.addEntry(3, entry.array());
+ fail("AddEntry is called after the close of LedgerHandle,"
+ + "so it is expected to throw BKLedgerClosedException");
+ } catch (BKLedgerClosedException exception) {
+ }
+
+ readEntries(lh, entries1);
+ bkc.deleteLedger(ledgerId);
+ }
+
+ /**
* In a loop create/write/delete the ledger with same ledgerId through
* the functionality of Advanced Ledger which accepts ledgerId as input.
*
@@ -393,6 +483,79 @@ public class BookieWriteLedgerTest extends
}
/**
+ * In a loop create/write/read/delete the ledger with ledgerId through the
+ * functionality of Advanced Ledger which accepts ledgerId as input.
+ * In this testcase (other testcases don't cover these conditions, hence new
+ * testcase is added), we create entries which are greater than
+ * SKIP_LIST_MAX_ALLOC_ENTRY size and tried to addEntries so that the total
+ * length of data written in this testcase is much greater than
+ * SKIP_LIST_SIZE_LIMIT, so that entries will be flushed from EntryMemTable
+ * to persistent storage
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testLedgerCreateAdvWithLedgerIdInLoop2() throws Exception {
+
+ assertTrue("Here we are expecting Bookies are configured to use SortedLedgerStorage",
+ baseConf.getSortedLedgerStorageEnabled());
+
+ long ledgerId;
+ int ledgerCount = 10;
+
+ List<List<byte[]>> entryList = new ArrayList<List<byte[]>>();
+ LedgerHandle[] lhArray = new LedgerHandle[ledgerCount];
+ long skipListSizeLimit = baseConf.getSkipListSizeLimit();
+ int skipListArenaMaxAllocSize = baseConf.getSkipListArenaMaxAllocSize();
+
+ List<byte[]> tmpEntry;
+ for (int lc = 0; lc < ledgerCount; lc++) {
+ tmpEntry = new ArrayList<byte[]>();
+
+ ledgerId = rng.nextLong();
+ ledgerId &= Long.MAX_VALUE;
+ if (!baseConf.getLedgerManagerFactoryClass().equals(LongHierarchicalLedgerManagerFactory.class)) {
+ // since LongHierarchicalLedgerManager supports ledgerIds of
+ // decimal length upto 19 digits but other
+ // LedgerManagers only upto 10 decimals
+ ledgerId %= 9999999999L;
+ }
+
+ LOG.debug("Iteration: {} LedgerId: {}", lc, ledgerId);
+ lh = bkc.createLedgerAdv(ledgerId, 5, 3, 2, digestType, ledgerPassword, null);
+ lhArray[lc] = lh;
+
+ long ledgerLength = 0;
+ int i = 0;
+ while (ledgerLength < ((4 * skipListSizeLimit) / ledgerCount)) {
+ int length;
+ if (rng.nextBoolean()) {
+ length = Math.abs(rng.nextInt()) % (skipListArenaMaxAllocSize);
+ } else {
+ // here we want length to be random no. in the range of skipListArenaMaxAllocSize and
+ // 4*skipListArenaMaxAllocSize
+ length = (Math.abs(rng.nextInt()) % (skipListArenaMaxAllocSize * 3)) + skipListArenaMaxAllocSize;
+ }
+ byte[] data = new byte[length];
+ rng.nextBytes(data);
+ tmpEntry.add(data);
+ lh.addEntry(i, data);
+ ledgerLength += length;
+ i++;
+ }
+ entryList.add(tmpEntry);
+ }
+ for (int lc = 0; lc < ledgerCount; lc++) {
+ // Read and verify
+ long lid = lhArray[lc].getId();
+ LOG.debug("readEntries for lc: {} ledgerId: {} ", lc, lhArray[lc].getId());
+ readEntriesAndValidateDataArray(lhArray[lc], entryList.get(lc));
+ lhArray[lc].close();
+ bkc.deleteLedger(lid);
+ }
+ }
+
+ /**
* Verify asynchronous writing when few bookie failures in last ensemble.
*/
@Test
@@ -801,6 +964,25 @@ public class BookieWriteLedgerTest extends
}
}
+ private void readEntriesAndValidateDataArray(LedgerHandle lh, List<byte[]> entries)
+ throws InterruptedException, BKException {
+ ls = lh.readEntries(0, entries.size() - 1);
+ int index = 0;
+ while (ls.hasMoreElements()) {
+ byte[] originalData = entries.get(index++);
+ byte[] receivedData = ls.nextElement().getEntry();
+ LOG.debug("Length of originalData: {}", originalData.length);
+ LOG.debug("Length of receivedData: {}", receivedData.length);
+ assertEquals(
+ String.format("LedgerID: %d EntryID: %d OriginalDataLength: %d ReceivedDataLength: %d", lh.getId(),
+ (index - 1), originalData.length, receivedData.length),
+ originalData.length, receivedData.length);
+ Assert.assertArrayEquals(
+ String.format("Checking LedgerID: %d EntryID: %d for equality", lh.getId(), (index - 1)),
+ originalData, receivedData);
+ }
+ }
+
@Override
public void addComplete(int rc, LedgerHandle lh, long entryId, Object ctx) {
SyncObj x = (SyncObj) ctx;
diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/util/TestZeroBuffer.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/util/TestZeroBuffer.java
new file mode 100644
index 0000000..cf22416
--- /dev/null
+++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/util/TestZeroBuffer.java
@@ -0,0 +1,118 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.bookkeeper.util;
+
+import java.nio.ByteBuffer;
+import java.util.Random;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Testcases for ZeroBuffer.
+ */
+public class TestZeroBuffer {
+
+ @Test
+ public void testPut() {
+ ByteBuffer testBuffer;
+ byte[] testBufferArray;
+ Random rand = new Random();
+
+ // Test1 - trying ZeroBuffer.put on small sized TestBuffer
+ testBuffer = ByteBuffer.allocate(5);
+ testBufferArray = testBuffer.array();
+ testBufferArray[4] = 7;
+ Assert.assertFalse("Test1 - It is supposed to contain non-zero byte", isFilledWithZeros(testBufferArray, 0, 5));
+ ZeroBuffer.put(testBuffer);
+ Assert.assertTrue("Test1 - After calling, ZeroBuffer.put There aren't supposed to be non-zero bytes",
+ isFilledWithZeros(testBufferArray, 0, 5));
+
+ // Test2 - trying ZeroBuffer.put on 64*1024 sized TestBuffer
+ testBuffer = ByteBuffer.allocate(64 * 1024);
+ testBufferArray = testBuffer.array();
+ rand.nextBytes(testBufferArray);
+ Assert.assertFalse("Test2 - It is supposed to contain random non-zero bytes",
+ isFilledWithZeros(testBufferArray, 0, 64 * 1024));
+ ZeroBuffer.put(testBuffer);
+ Assert.assertTrue("Test2 - After calling, ZeroBuffer.put There aren't supposed to be non-zero bytes",
+ isFilledWithZeros(testBufferArray, 0, 64 * 1024));
+
+ // Test3 - trying ZeroBuffer.put on portion (64*1024) of large sized
+ // TestBuffer (256*1024)
+ testBuffer = ByteBuffer.allocate(256 * 1024);
+ testBufferArray = testBuffer.array();
+ rand.nextBytes(testBufferArray);
+ Assert.assertFalse("Test3 - It is supposed to contain random non-zero bytes",
+ isFilledWithZeros(testBufferArray, 64 * 1024, 64 * 1024));
+ testBuffer.position(64 * 1024);
+ ZeroBuffer.put(testBuffer, 64 * 1024);
+ Assert.assertTrue(
+ "Test3 - After calling, ZeroBuffer.put There aren't supposed to be non-zero bytes "
+ + "in the particular section", isFilledWithZeros(testBufferArray, 64 * 1024, 64 * 1024));
+ Assert.assertFalse("Test3 - After calling, ZeroBuffer.put other sections shouldnt be touched",
+ isFilledWithZeros(testBufferArray, 0, 64 * 1024));
+ Assert.assertFalse("Test3 - After calling, ZeroBuffer.put other sections shouldnt be touched",
+ isFilledWithZeros(testBufferArray, 128 * 1024, 128 * 1024));
+ }
+
+ @Test
+ public void testReadOnlyBuffer() {
+ ByteBuffer testReadOnlyBuffer;
+ byte[] testBufferArray;
+
+ // Test1 - trying ZeroBuffer.readOnlyBuffer for small size
+ testReadOnlyBuffer = ZeroBuffer.readOnlyBuffer(5);
+ Assert.assertTrue(
+ "Test1 - ReadOnlyBuffer should have remaining 5 bytes but it has " + testReadOnlyBuffer.remaining(),
+ testReadOnlyBuffer.remaining() == 5);
+ testBufferArray = new byte[5];
+ testReadOnlyBuffer.get(testBufferArray);
+ Assert.assertTrue("Test1 - supposed to contain only zero bytes", isFilledWithZeros(testBufferArray, 0, 5));
+
+ // Test2 - trying ZeroBuffer.readOnlyBuffer for 64*1024
+ testReadOnlyBuffer = ZeroBuffer.readOnlyBuffer(64 * 1024);
+ Assert.assertTrue("Test2 - ReadOnlyBuffer should have remaining 64*1024 bytes but it has "
+ + testReadOnlyBuffer.remaining(), testReadOnlyBuffer.remaining() == 64 * 1024);
+ testBufferArray = new byte[64 * 1024];
+ testReadOnlyBuffer.get(testBufferArray);
+ Assert.assertTrue("Test2 - supposed to contain only zero bytes",
+ isFilledWithZeros(testBufferArray, 0, 64 * 1024));
+
+ // Test3 - trying ZeroBuffer.readOnlyBuffer for > 64*1024
+ testReadOnlyBuffer = ZeroBuffer.readOnlyBuffer(128 * 1024);
+ Assert.assertTrue("Test3 - ReadOnlyBuffer should have remaining 128*1024 bytes but it has "
+ + testReadOnlyBuffer.remaining(), testReadOnlyBuffer.remaining() == 128 * 1024);
+ testBufferArray = new byte[128 * 1024];
+ testReadOnlyBuffer.get(testBufferArray);
+ Assert.assertTrue("Test3 - supposed to contain only zero bytes",
+ isFilledWithZeros(testBufferArray, 0, 128 * 1024));
+ }
+
+ boolean isFilledWithZeros(byte[] byteArray, int start, int length) {
+ for (int i = start; i < (start + length); i++) {
+ if (byteArray[i] != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
--
To stop receiving notification emails like this one, please contact
sijie@apache.org.