From 4021f14bfac845857eb171aca00d455afedcd8f6 Mon Sep 17 00:00:00 2001 From: Yan Zhao Date: Wed, 30 Nov 2022 09:34:43 +0800 Subject: [PATCH] Enhance simple test (#3675) ### Motivation Fixes #3670 --- .../commands/client/SimpleTestCommand.java | 50 +++++++++++++------ .../client/SimpleTestCommandTest.java | 46 +++++++++++++++-- 2 files changed, 75 insertions(+), 21 deletions(-) diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommand.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommand.java index c083a515ed1..ca94cac4a73 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommand.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommand.java @@ -24,11 +24,16 @@ import com.google.common.collect.ImmutableMap; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Random; import java.util.concurrent.TimeUnit; import lombok.Setter; import lombok.experimental.Accessors; import org.apache.bookkeeper.client.api.BookKeeper; import org.apache.bookkeeper.client.api.DigestType; +import org.apache.bookkeeper.client.api.LedgerEntries; +import org.apache.bookkeeper.client.api.LedgerEntry; +import org.apache.bookkeeper.client.api.ReadHandle; import org.apache.bookkeeper.client.api.WriteHandle; import org.apache.bookkeeper.tools.cli.commands.client.SimpleTestCommand.Flags; import org.apache.bookkeeper.tools.cli.helpers.ClientCommand; @@ -43,7 +48,7 @@ public class SimpleTestCommand extends ClientCommand { private static final String NAME = "simpletest"; - private static final String DESC = "Simple test to create a ledger and write entries to it."; + private static final String DESC = "Simple test to create a ledger and write entries to it, then read it."; private static final Logger LOG = LoggerFactory.getLogger(SimpleTestCommand.class); /** @@ -61,8 +66,6 @@ public static class Flags extends CliFlags { private int ackQuorumSize = 2; @Parameter(names = { "-n", "--num-entries" }, description = "Entries to write (default 100)") private int numEntries = 100; - @Parameter(names = { "-c", "--clean-up" }, description = "Clean up ledger created after simple test") - private boolean cleanup = false; } public SimpleTestCommand() { @@ -78,19 +81,23 @@ public SimpleTestCommand(Flags flags) { } @Override - @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE") + @SuppressFBWarnings({"RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE", "DMI_RANDOM_USED_ONLY_ONCE"}) protected void run(BookKeeper bk, Flags flags) throws Exception { byte[] data = new byte[100]; // test data - - try (WriteHandle wh = result(bk.newCreateLedgerOp() - .withEnsembleSize(flags.ensembleSize) - .withWriteQuorumSize(flags.writeQuorumSize) - .withAckQuorumSize(flags.ackQuorumSize) - .withDigestType(DigestType.CRC32C) - .withCustomMetadata(ImmutableMap.of("Bookie", NAME.getBytes(StandardCharsets.UTF_8))) - .withPassword(new byte[0]) - .execute())) { - + Random random = new Random(0); + for (int i = 0; i < data.length; i++) { + data[i] = (byte) (random.nextInt(26) + 65); + } + WriteHandle wh = null; + try { + wh = result(bk.newCreateLedgerOp() + .withEnsembleSize(flags.ensembleSize) + .withWriteQuorumSize(flags.writeQuorumSize) + .withAckQuorumSize(flags.ackQuorumSize) + .withDigestType(DigestType.CRC32C) + .withCustomMetadata(ImmutableMap.of("Bookie", NAME.getBytes(StandardCharsets.UTF_8))) + .withPassword(new byte[0]) + .execute()); LOG.info("Ledger ID: {}", wh.getId()); long lastReport = System.nanoTime(); for (int i = 0; i < flags.numEntries; i++) { @@ -102,8 +109,19 @@ protected void run(BookKeeper bk, Flags flags) throws Exception { } } LOG.info("{} entries written to ledger {}", flags.numEntries, wh.getId()); - if (flags.cleanup) { - LOG.info("Cleaning up the ledger {}", wh.getId()); + + try (ReadHandle rh = result(bk.newOpenLedgerOp().withLedgerId(wh.getId()).withDigestType(DigestType.CRC32C) + .withPassword(new byte[0]).execute())) { + LedgerEntries ledgerEntries = rh.read(0, flags.numEntries); + for (LedgerEntry ledgerEntry : ledgerEntries) { + if (!Arrays.equals(ledgerEntry.getEntryBytes(), data)) { + LOG.error("Read test failed, the reading data is not equals writing data."); + } + } + } + } finally { + if (wh != null) { + wh.close(); result(bk.newDeleteLedgerOp().withLedgerId(wh.getId()).execute()); } } diff --git a/tools/ledger/src/test/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommandTest.java b/tools/ledger/src/test/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommandTest.java index d7c80279ee9..b06f0a62c3a 100644 --- a/tools/ledger/src/test/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommandTest.java +++ b/tools/ledger/src/test/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommandTest.java @@ -28,15 +28,25 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Map; +import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicLong; import org.apache.bookkeeper.client.api.CreateBuilder; import org.apache.bookkeeper.client.api.DeleteBuilder; import org.apache.bookkeeper.client.api.DigestType; +import org.apache.bookkeeper.client.api.LedgerEntry; +import org.apache.bookkeeper.client.api.OpenBuilder; +import org.apache.bookkeeper.client.api.ReadHandle; import org.apache.bookkeeper.client.api.WriteHandle; +import org.apache.bookkeeper.client.impl.LedgerEntriesImpl; +import org.apache.bookkeeper.client.impl.LedgerEntryImpl; import org.apache.bookkeeper.common.concurrent.FutureUtils; import org.apache.bookkeeper.tools.cli.helpers.ClientCommandTestBase; import org.junit.Test; @@ -53,8 +63,7 @@ public void testCommandShortArgs() throws Exception { "-e", "5", "-w", "3", "-a", "3", - "-n", "10", - "-c"); + "-n", "10"); } @Test @@ -63,8 +72,7 @@ public void testCommandLongArgs() throws Exception { "--ensemble-size", "5", "--write-quorum-size", "3", "--ack-quorum-size", "3", - "--num-entries", "10", - "-c"); + "--num-entries", "10"); } @SuppressWarnings("unchecked") @@ -83,6 +91,29 @@ public void testCommand(String... args) throws Exception { when(createBuilder.execute()).thenReturn(CompletableFuture.completedFuture(wh)); when(mockBk.newCreateLedgerOp()).thenReturn(createBuilder); + List entries = new ArrayList<>(); + byte[] data = new byte[100]; // test data + Random random = new Random(0); + for (int i = 0; i < data.length; i++) { + data[i] = (byte) (random.nextInt(26) + 65); + } + for (int i = 0; i < 10; i++) { + ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.heapBuffer(100); + buffer.writeBytes(data); + entries.add(LedgerEntryImpl.create(counter.get(), i, data.length, buffer)); + } + + LedgerEntriesImpl ledgerEntries = LedgerEntriesImpl.create(entries); + + ReadHandle rh = mock(ReadHandle.class); + when(rh.read(anyLong(), anyLong())).thenReturn(ledgerEntries); + OpenBuilder openBuilder = mock(OpenBuilder.class); + when(openBuilder.withLedgerId(anyLong())).thenReturn(openBuilder); + when(openBuilder.withDigestType(any())).thenReturn(openBuilder); + when(openBuilder.withPassword(any())).thenReturn(openBuilder); + when(openBuilder.execute()).thenReturn(CompletableFuture.completedFuture(rh)); + when(mockBk.newOpenLedgerOp()).thenReturn(openBuilder); + DeleteBuilder deleteBuilder = mock(DeleteBuilder.class); when(deleteBuilder.withLedgerId(anyLong())).thenReturn(deleteBuilder); when(deleteBuilder.execute()).thenReturn(CompletableFuture.completedFuture(null)); @@ -103,11 +134,16 @@ public void testCommand(String... args) throws Exception { verify(createBuilder, times(1)).withPassword(eq(new byte[0])); verify(createBuilder, times(1)).execute(); + verify(openBuilder, times(1)).withLedgerId(eq(0L)); + verify(openBuilder, times(1)).execute(); + verify(deleteBuilder, times(1)).withLedgerId(eq(0L)); verify(deleteBuilder, times(1)).execute(); // verify appends - verify(wh, times(10)).append(eq(new byte[100])); + verify(wh, times(10)).append(eq(data)); + + verify(rh, times(1)).read(anyLong(), anyLong()); } }