This is an automated email from the ASF dual-hosted git repository. szetszwo pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push: new 72ffc27a9d HDDS-13340. Fix minor items identified during reconciliation branch merge process. (#8705) 72ffc27a9d is described below commit 72ffc27a9dc9223112e591c2bddc38b6e19308d2 Author: Ethan Rose <33912936+erros...@users.noreply.github.com> AuthorDate: Sat Jul 5 08:01:32 2025 -0400 HDDS-13340. Fix minor items identified during reconciliation branch merge process. (#8705) --- .../checksum/ContainerChecksumTreeManager.java | 7 +- .../container/checksum/ContainerDiffReport.java | 41 ++++++-- .../checksum/ContainerMerkleTreeMetrics.java | 33 ++++++ .../common/impl/BlockDeletingService.java | 5 +- .../checksum/ContainerMerkleTreeTestUtils.java | 113 ++++++++++----------- .../checksum/TestContainerChecksumTreeManager.java | 77 ++++++++------ .../common/BlockDeletingServiceTestImpl.java | 3 +- .../container/common/TestBlockDeletingService.java | 4 +- .../impl/TestContainerDeletionChoosingPolicy.java | 3 +- 9 files changed, 179 insertions(+), 107 deletions(-) diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerChecksumTreeManager.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerChecksumTreeManager.java index ec799ade31..b52d0667c7 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerChecksumTreeManager.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerChecksumTreeManager.java @@ -201,9 +201,12 @@ public ContainerDiffReport diff(ContainerProtos.ContainerChecksumInfo thisChecks // Update Container Diff metrics based on the diff report. if (report.needsRepair()) { metrics.incrementRepairContainerDiffs(); - return report; + metrics.incrementCorruptChunksIdentified(report.getNumCorruptChunks()); + metrics.incrementMissingBlocksIdentified(report.getNumMissingBlocks()); + metrics.incrementMissingChunksIdentified(report.getNumMissingChunks()); + } else { + metrics.incrementNoRepairContainerDiffs(); } - metrics.incrementNoRepairContainerDiffs(); return report; } diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerDiffReport.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerDiffReport.java index 709cc33ce4..6de3057b00 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerDiffReport.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerDiffReport.java @@ -38,26 +38,46 @@ public ContainerDiffReport() { this.corruptChunks = new HashMap<>(); } + /** + * @param missingBlockMerkleTree The block merkle tree of the block to report as missing. + */ public void addMissingBlock(ContainerProtos.BlockMerkleTree missingBlockMerkleTree) { this.missingBlocks.add(missingBlockMerkleTree); } + /** + * @param blockId The ID of the block with missing chunks identified. + * @param missingChunkMerkleTree The chunk within this block to report as missing. + */ public void addMissingChunk(long blockId, ContainerProtos.ChunkMerkleTree missingChunkMerkleTree) { this.missingChunks.computeIfAbsent(blockId, any -> new ArrayList<>()).add(missingChunkMerkleTree); } + /** + * @param blockId The ID of the block with missing chunks identified. + * @param corruptChunk The chunk within this block to report as corrupt. + */ public void addCorruptChunk(long blockId, ContainerProtos.ChunkMerkleTree corruptChunk) { this.corruptChunks.computeIfAbsent(blockId, any -> new ArrayList<>()).add(corruptChunk); } + /** + * @return A list of BlockMerkleTree objects that were reported as missing. + */ public List<ContainerProtos.BlockMerkleTree> getMissingBlocks() { return missingBlocks; } + /** + * @return A map of block IDs to lists of missing ChunkMerkleTree objects within those blocks. + */ public Map<Long, List<ContainerProtos.ChunkMerkleTree>> getMissingChunks() { return missingChunks; } + /** + * @return A map of block IDs to lists of corrupt ChunkMerkleTree objects within those blocks. + */ public Map<Long, List<ContainerProtos.ChunkMerkleTree>> getCorruptChunks() { return corruptChunks; } @@ -71,14 +91,23 @@ public boolean needsRepair() { return !missingBlocks.isEmpty() || !missingChunks.isEmpty() || !corruptChunks.isEmpty(); } - // TODO: HDDS-11763 - Add metrics for missing blocks, missing chunks, corrupt chunks. + public long getNumCorruptChunks() { + return corruptChunks.values().stream().mapToInt(List::size).sum(); + } + + public long getNumMissingChunks() { + return missingChunks.values().stream().mapToInt(List::size).sum(); + } + + public long getNumMissingBlocks() { + return missingBlocks.size(); + } + @Override public String toString() { return "ContainerDiffReport:" + - " MissingBlocks= " + missingBlocks.size() + " blocks" + - ", MissingChunks= " + missingChunks.values().stream().mapToInt(List::size).sum() - + " chunks from " + missingChunks.size() + " blocks" + - ", CorruptChunks= " + corruptChunks.values().stream().mapToInt(List::size).sum() - + " chunks from " + corruptChunks.size() + " blocks"; + " Missing Blocks: " + getNumMissingBlocks() + + " Missing Chunks: " + getNumMissingChunks() + " chunks from " + missingChunks.size() + " blocks" + + " Corrupt Chunks: " + getNumCorruptChunks() + " chunks from " + corruptChunks.size() + " blocks"; } } diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeMetrics.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeMetrics.java index 63154cddd5..ec5a9503ca 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeMetrics.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeMetrics.java @@ -45,6 +45,15 @@ public class ContainerMerkleTreeMetrics { @Metric(about = "Number of container diff that requires repair") private MutableCounterLong numRepairContainerDiff; + @Metric(about = "Number of missing blocks identified during container reconciliation") + private MutableCounterLong numMissingBlocksIdentified; + + @Metric(about = "Number of missing chunks identified during container reconciliation") + private MutableCounterLong numMissingChunksIdentified; + + @Metric(about = "Number of corrupt chunks identified during container reconciliation") + private MutableCounterLong numCorruptChunksIdentified; + @Metric(about = "Merkle tree write latency") private MutableRate merkleTreeWriteLatencyNS; @@ -92,6 +101,18 @@ public void incrementRepairContainerDiffs() { this.numRepairContainerDiff.incr(); } + public void incrementMissingBlocksIdentified(long value) { + this.numMissingBlocksIdentified.incr(value); + } + + public void incrementMissingChunksIdentified(long value) { + this.numMissingChunksIdentified.incr(value); + } + + public void incrementCorruptChunksIdentified(long value) { + this.numCorruptChunksIdentified.incr(value); + } + public MutableRate getWriteContainerMerkleTreeLatencyNS() { return this.merkleTreeWriteLatencyNS; } @@ -119,4 +140,16 @@ public long getRepairContainerDiffs() { public long getMerkleTreeDiffFailure() { return this.numMerkleTreeDiffFailure.value(); } + + public long getMissingBlocksIdentified() { + return this.numMissingBlocksIdentified.value(); + } + + public long getMissingChunksIdentified() { + return this.numMissingChunksIdentified.value(); + } + + public long getCorruptChunksIdentified() { + return this.numCorruptChunksIdentified.value(); + } } diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/BlockDeletingService.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/BlockDeletingService.java index 47930ba598..1d136cd4b8 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/BlockDeletingService.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/BlockDeletingService.java @@ -78,10 +78,9 @@ public class BlockDeletingService extends BackgroundService { @VisibleForTesting public BlockDeletingService( OzoneContainer ozoneContainer, long serviceInterval, long serviceTimeout, - TimeUnit timeUnit, int workerSize, ConfigurationSource conf - ) { + TimeUnit timeUnit, int workerSize, ConfigurationSource conf, ContainerChecksumTreeManager checksumTreeManager) { this(ozoneContainer, serviceInterval, serviceTimeout, timeUnit, workerSize, - conf, "", new ContainerChecksumTreeManager(conf), null); + conf, "", checksumTreeManager, null); } @SuppressWarnings("checkstyle:parameternumber") diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeTestUtils.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeTestUtils.java index c83ed95ed5..730c2c8b65 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeTestUtils.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeTestUtils.java @@ -30,12 +30,9 @@ import java.nio.file.Files; import java.util.Arrays; import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; -import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.conf.ConfigurationSource; @@ -174,84 +171,80 @@ public static ContainerMerkleTreeWriter buildTestTree(ConfigurationSource conf, } /** - * Introduces missing blocks by removing random blocks from the tree. + * Introduces missing blocks by removing blocks sequentially from the tree. */ private static void introduceMissingBlocks(ContainerProtos.ContainerMerkleTree.Builder treeBuilder, - int numMissingBlocks, - ContainerDiffReport diff) { - // Set to track unique blocks selected for mismatches - Set<Integer> selectedBlocks = new HashSet<>(); + int numMissingBlocks, ContainerDiffReport diff) { Random random = new Random(); - for (int i = 0; i < numMissingBlocks; i++) { - int randomBlockIndex; - do { - randomBlockIndex = random.nextInt(treeBuilder.getBlockMerkleTreeCount()); - } while (selectedBlocks.contains(randomBlockIndex)); - selectedBlocks.add(randomBlockIndex); - ContainerProtos.BlockMerkleTree blockMerkleTree = treeBuilder.getBlockMerkleTree(randomBlockIndex); + for (int blockIndex = 0; blockIndex < numMissingBlocks; blockIndex++) { + ContainerProtos.BlockMerkleTree blockMerkleTree = treeBuilder.getBlockMerkleTree(blockIndex); diff.addMissingBlock(blockMerkleTree); - treeBuilder.removeBlockMerkleTree(randomBlockIndex); + treeBuilder.removeBlockMerkleTree(blockIndex); treeBuilder.setDataChecksum(random.nextLong()); } } /** - * Introduces missing chunks by removing random chunks from selected blocks. + * Introduces missing chunks by removing the first chunk from each block. If more chunks must be removed, + * it will resume removing the next chunk from each block until numMissingChunks have been removed. */ private static void introduceMissingChunks(ContainerProtos.ContainerMerkleTree.Builder treeBuilder, - int numMissingChunks, - ContainerDiffReport diff) { - // Set to track unique blocks selected for mismatches + int numMissingChunks, ContainerDiffReport diff) { Random random = new Random(); - for (int i = 0; i < numMissingChunks; i++) { - int randomBlockIndex = random.nextInt(treeBuilder.getBlockMerkleTreeCount()); - - // Work on the chosen block to remove a random chunk - ContainerProtos.BlockMerkleTree.Builder blockBuilder = treeBuilder.getBlockMerkleTreeBuilder(randomBlockIndex); - if (blockBuilder.getChunkMerkleTreeCount() > 0) { - int randomChunkIndex = random.nextInt(blockBuilder.getChunkMerkleTreeCount()); - ContainerProtos.ChunkMerkleTree chunkMerkleTree = blockBuilder.getChunkMerkleTree(randomChunkIndex); - diff.addMissingChunk(blockBuilder.getBlockID(), chunkMerkleTree); - blockBuilder.removeChunkMerkleTree(randomChunkIndex); - blockBuilder.setDataChecksum(random.nextLong()); - treeBuilder.setDataChecksum(random.nextLong()); + + int numChunksRemoved = 0; + boolean hasChunks = true; + while (numChunksRemoved < numMissingChunks && hasChunks) { + hasChunks = false; + for (int blockIndex = 0; blockIndex < treeBuilder.getBlockMerkleTreeCount() && + numChunksRemoved < numMissingChunks; blockIndex++) { + ContainerProtos.BlockMerkleTree.Builder blockBuilder = treeBuilder.getBlockMerkleTreeBuilder(blockIndex); + if (blockBuilder.getChunkMerkleTreeCount() > 0) { + ContainerProtos.ChunkMerkleTree chunkMerkleTree = blockBuilder.getChunkMerkleTree(0); + diff.addMissingChunk(blockBuilder.getBlockID(), chunkMerkleTree); + blockBuilder.removeChunkMerkleTree(0); + blockBuilder.setDataChecksum(random.nextLong()); + treeBuilder.setDataChecksum(random.nextLong()); + hasChunks = true; + numChunksRemoved++; + } } } + // Make sure we removed the expected number of chunks. + assertTrue(hasChunks); } /** - * Introduces corrupt chunks by altering the checksum and setting them as unhealthy, - * ensuring each chunk in a block is only selected once for corruption. + * Introduces corrupt chunks by corrupting the first chunk from each block. If more chunks must be corrupted, + * it will resume corrupting the next chunk from each block until numCorruptChunks have been corrupted. */ private static void introduceCorruptChunks(ContainerProtos.ContainerMerkleTree.Builder treeBuilder, - int numCorruptChunks, - ContainerDiffReport diff) { - Map<Integer, Set<Integer>> corruptedChunksByBlock = new HashMap<>(); + int numCorruptChunks, ContainerDiffReport diff) { Random random = new Random(); - - for (int i = 0; i < numCorruptChunks; i++) { - // Select a random block - int randomBlockIndex = random.nextInt(treeBuilder.getBlockMerkleTreeCount()); - ContainerProtos.BlockMerkleTree.Builder blockBuilder = treeBuilder.getBlockMerkleTreeBuilder(randomBlockIndex); - - // Ensure each chunk in the block is only corrupted once - Set<Integer> corruptedChunks = corruptedChunksByBlock.computeIfAbsent(randomBlockIndex, k -> new HashSet<>()); - if (corruptedChunks.size() < blockBuilder.getChunkMerkleTreeCount()) { - int randomChunkIndex; - do { - randomChunkIndex = random.nextInt(blockBuilder.getChunkMerkleTreeCount()); - } while (corruptedChunks.contains(randomChunkIndex)); - corruptedChunks.add(randomChunkIndex); - - // Corrupt the selected chunk - ContainerProtos.ChunkMerkleTree.Builder chunkBuilder = blockBuilder.getChunkMerkleTreeBuilder(randomChunkIndex); - diff.addCorruptChunk(blockBuilder.getBlockID(), chunkBuilder.build()); - chunkBuilder.setDataChecksum(chunkBuilder.getDataChecksum() + random.nextInt(1000) + 1); - chunkBuilder.setChecksumMatches(false); - blockBuilder.setDataChecksum(random.nextLong()); - treeBuilder.setDataChecksum(random.nextLong()); + boolean hasChunks = true; + int numChunksCorrupted = 0; + int chunkIndex = 0; + + while (numChunksCorrupted < numCorruptChunks && hasChunks) { + hasChunks = false; + for (int blockIndex = 0; blockIndex < treeBuilder.getBlockMerkleTreeCount() && + numChunksCorrupted < numCorruptChunks; blockIndex++) { + ContainerProtos.BlockMerkleTree.Builder blockBuilder = treeBuilder.getBlockMerkleTreeBuilder(blockIndex); + if (chunkIndex < blockBuilder.getChunkMerkleTreeCount()) { + ContainerProtos.ChunkMerkleTree.Builder chunkBuilder = blockBuilder.getChunkMerkleTreeBuilder(chunkIndex); + diff.addCorruptChunk(blockBuilder.getBlockID(), chunkBuilder.build()); + chunkBuilder.setDataChecksum(random.nextLong()); + chunkBuilder.setChecksumMatches(false); + blockBuilder.setDataChecksum(random.nextLong()); + treeBuilder.setDataChecksum(random.nextLong()); + hasChunks = true; + numChunksCorrupted++; + } } + chunkIndex++; } + // Make sure we corrupted the expected number of chunks. + assertTrue(hasChunks); } public static void assertContainerDiffMatch(ContainerDiffReport expectedDiff, @@ -267,7 +260,7 @@ public static void assertContainerDiffMatch(ContainerDiffReport expectedDiff, List<ContainerProtos.BlockMerkleTree> expectedMissingBlocks = expectedDiff.getMissingBlocks().stream().sorted( Comparator.comparing(ContainerProtos.BlockMerkleTree::getBlockID)).collect(Collectors.toList()); - List<ContainerProtos.BlockMerkleTree> actualMissingBlocks = expectedDiff.getMissingBlocks().stream().sorted( + List<ContainerProtos.BlockMerkleTree> actualMissingBlocks = actualDiff.getMissingBlocks().stream().sorted( Comparator.comparing(ContainerProtos.BlockMerkleTree::getBlockID)).collect(Collectors.toList()); for (int i = 0; i < expectedMissingBlocks.size(); i++) { ContainerProtos.BlockMerkleTree expectedBlockMerkleTree = expectedMissingBlocks.get(i); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/TestContainerChecksumTreeManager.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/TestContainerChecksumTreeManager.java index 9206b99e9a..36b705c992 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/TestContainerChecksumTreeManager.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/TestContainerChecksumTreeManager.java @@ -48,6 +48,7 @@ import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos; import org.apache.hadoop.hdds.scm.container.common.helpers.StorageContainerException; import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -67,7 +68,6 @@ class TestContainerChecksumTreeManager { private KeyValueContainerData container; private File checksumFile; private ContainerChecksumTreeManager checksumManager; - private ContainerMerkleTreeMetrics metrics; private ConfigurationSource config; /** @@ -100,17 +100,24 @@ public void init() { when(container.getMetadataPath()).thenReturn(testDir.getAbsolutePath()); checksumFile = new File(testDir, CONTAINER_ID + ".tree"); checksumManager = new ContainerChecksumTreeManager(new OzoneConfiguration()); - metrics = checksumManager.getMetrics(); config = new OzoneConfiguration(); } + @AfterEach + public void cleanup() throws IOException { + // Unregister metrics for the next test run. + if (checksumManager != null) { + checksumManager.stop(); + } + } + @Test public void testWriteEmptyTreeToFile() throws Exception { - assertEquals(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); - assertEquals(metrics.getCreateMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getCreateMerkleTreeLatencyNS().lastStat().total(), 0); checksumManager.writeContainerDataTree(container, new ContainerMerkleTreeWriter()); - assertTrue(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); - assertTrue(metrics.getCreateMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getCreateMerkleTreeLatencyNS().lastStat().total() > 0); ContainerProtos.ContainerChecksumInfo checksumInfo = readChecksumFile(container); @@ -123,9 +130,9 @@ public void testWriteEmptyTreeToFile() throws Exception { @Test public void testWriteEmptyBlockListToFile() throws Exception { - assertEquals(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); checksumManager.markBlocksAsDeleted(container, Collections.emptySet()); - assertTrue(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); ContainerProtos.ContainerChecksumInfo checksumInfo = readChecksumFile(container); @@ -138,14 +145,14 @@ public void testWriteEmptyBlockListToFile() throws Exception { @Test public void testWriteOnlyTreeToFile() throws Exception { - assertEquals(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); - assertEquals(metrics.getCreateMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getCreateMerkleTreeLatencyNS().lastStat().total(), 0); ContainerMerkleTreeWriter tree = buildTestTree(config); checksumManager.writeContainerDataTree(container, tree); - assertTrue(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); ContainerProtos.ContainerChecksumInfo checksumInfo = readChecksumFile(container); - assertTrue(metrics.getCreateMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getCreateMerkleTreeLatencyNS().lastStat().total() > 0); assertEquals(CONTAINER_ID, checksumInfo.getContainerID()); assertTrue(checksumInfo.getDeletedBlocksList().isEmpty()); // TestContainerMerkleTree verifies that going from ContainerMerkleTree to its proto is consistent. @@ -155,10 +162,10 @@ public void testWriteOnlyTreeToFile() throws Exception { @Test public void testWriteOnlyDeletedBlocksToFile() throws Exception { - assertEquals(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); List<Long> expectedBlocksToDelete = Arrays.asList(1L, 2L, 3L); checksumManager.markBlocksAsDeleted(container, new ArrayList<>(expectedBlocksToDelete)); - assertTrue(metrics.getWriteContainerMerkleTreeLatencyNS().changed()); + assertTrue(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().changed()); ContainerProtos.ContainerChecksumInfo checksumInfo = readChecksumFile(container); @@ -197,19 +204,19 @@ public void testWriteBlocksOutOfOrder() throws Exception { @Test public void testDeletedBlocksPreservedOnTreeWrite() throws Exception { - assertEquals(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); - assertEquals(metrics.getCreateMerkleTreeLatencyNS().lastStat().total(), 0); - assertEquals(metrics.getReadContainerMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getCreateMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getReadContainerMerkleTreeLatencyNS().lastStat().total(), 0); List<Long> expectedBlocksToDelete = Arrays.asList(1L, 2L, 3L); checksumManager.markBlocksAsDeleted(container, new ArrayList<>(expectedBlocksToDelete)); ContainerMerkleTreeWriter tree = buildTestTree(config); checksumManager.writeContainerDataTree(container, tree); - assertTrue(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); - assertTrue(metrics.getReadContainerMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getReadContainerMerkleTreeLatencyNS().lastStat().total() > 0); ContainerProtos.ContainerChecksumInfo checksumInfo = readChecksumFile(container); - assertTrue(metrics.getCreateMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getCreateMerkleTreeLatencyNS().lastStat().total() > 0); assertEquals(CONTAINER_ID, checksumInfo.getContainerID()); assertEquals(expectedBlocksToDelete, getDeletedBlockIDs(checksumInfo)); assertTreesSortedAndMatch(tree.toProto(), checksumInfo.getContainerMerkleTree()); @@ -217,19 +224,19 @@ public void testDeletedBlocksPreservedOnTreeWrite() throws Exception { @Test public void testTreePreservedOnDeletedBlocksWrite() throws Exception { - assertEquals(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); - assertEquals(metrics.getCreateMerkleTreeLatencyNS().lastStat().total(), 0); - assertEquals(metrics.getReadContainerMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getCreateMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getReadContainerMerkleTreeLatencyNS().lastStat().total(), 0); ContainerMerkleTreeWriter tree = buildTestTree(config); checksumManager.writeContainerDataTree(container, tree); List<Long> expectedBlocksToDelete = Arrays.asList(1L, 2L, 3L); checksumManager.markBlocksAsDeleted(container, new ArrayList<>(expectedBlocksToDelete)); - assertTrue(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); - assertTrue(metrics.getReadContainerMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getReadContainerMerkleTreeLatencyNS().lastStat().total() > 0); ContainerProtos.ContainerChecksumInfo checksumInfo = readChecksumFile(container); - assertTrue(metrics.getCreateMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getCreateMerkleTreeLatencyNS().lastStat().total() > 0); assertEquals(CONTAINER_ID, checksumInfo.getContainerID()); assertEquals(expectedBlocksToDelete, getDeletedBlockIDs(checksumInfo)); assertTreesSortedAndMatch(tree.toProto(), checksumInfo.getContainerMerkleTree()); @@ -237,12 +244,12 @@ public void testTreePreservedOnDeletedBlocksWrite() throws Exception { @Test public void testReadContainerMerkleTreeMetric() throws Exception { - assertEquals(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); - assertEquals(metrics.getReadContainerMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total(), 0); + assertEquals(checksumManager.getMetrics().getReadContainerMerkleTreeLatencyNS().lastStat().total(), 0); ContainerMerkleTreeWriter tree = buildTestTree(config); checksumManager.writeContainerDataTree(container, tree); - assertTrue(metrics.getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); - assertTrue(metrics.getReadContainerMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getWriteContainerMerkleTreeLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getReadContainerMerkleTreeLatencyNS().lastStat().total() > 0); } /** @@ -363,9 +370,12 @@ public void testContainerDiffWithMismatches(int numMissingBlock, int numMissingC .setContainerMerkleTree(peerMerkleTree.toProto()).build(); Optional<ContainerProtos.ContainerChecksumInfo> checksumInfo = checksumManager.read(container); ContainerDiffReport diff = checksumManager.diff(checksumInfo.get(), peerChecksumInfo); - assertTrue(metrics.getMerkleTreeDiffLatencyNS().lastStat().total() > 0); + assertTrue(checksumManager.getMetrics().getMerkleTreeDiffLatencyNS().lastStat().total() > 0); assertContainerDiffMatch(expectedDiff, diff); - assertEquals(checksumManager.getMetrics().getRepairContainerDiffs(), 1); + assertEquals(1, checksumManager.getMetrics().getRepairContainerDiffs()); + assertEquals(numMissingBlock, checksumManager.getMetrics().getMissingBlocksIdentified()); + assertEquals(numMissingChunk, checksumManager.getMetrics().getMissingChunksIdentified()); + assertEquals(numCorruptChunk, checksumManager.getMetrics().getCorruptChunksIdentified()); } /** @@ -389,6 +399,9 @@ public void testPeerWithMismatchesHasNoDiff(int numMissingBlock, int numMissingC ContainerDiffReport diff = checksumManager.diff(checksumInfo.get(), peerChecksumInfo); assertFalse(diff.needsRepair()); assertEquals(checksumManager.getMetrics().getNoRepairContainerDiffs(), 1); + assertEquals(0, checksumManager.getMetrics().getMissingBlocksIdentified()); + assertEquals(0, checksumManager.getMetrics().getMissingChunksIdentified()); + assertEquals(0, checksumManager.getMetrics().getCorruptChunksIdentified()); } @Test diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/BlockDeletingServiceTestImpl.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/BlockDeletingServiceTestImpl.java index d8be345a69..8e41ab686a 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/BlockDeletingServiceTestImpl.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/BlockDeletingServiceTestImpl.java @@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.apache.hadoop.hdds.conf.ConfigurationSource; +import org.apache.hadoop.ozone.container.checksum.ContainerChecksumTreeManager; import org.apache.hadoop.ozone.container.common.impl.BlockDeletingService; import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer; @@ -43,7 +44,7 @@ class BlockDeletingServiceTestImpl extends BlockDeletingService { BlockDeletingServiceTestImpl(OzoneContainer container, int serviceInterval, ConfigurationSource conf) { super(container, serviceInterval, SERVICE_TIMEOUT_IN_MILLISECONDS, - TimeUnit.MILLISECONDS, 10, conf); + TimeUnit.MILLISECONDS, 10, conf, new ContainerChecksumTreeManager(conf)); } @VisibleForTesting diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestBlockDeletingService.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestBlockDeletingService.java index 3e7f209acf..7614dc4f8d 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestBlockDeletingService.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/TestBlockDeletingService.java @@ -479,7 +479,7 @@ public void testPendingDeleteBlockReset(ContainerTestVersionInfo versionInfo) OzoneContainer ozoneContainer = mockDependencies(containerSet, keyValueHandler); BlockDeletingService svc = new BlockDeletingService(ozoneContainer, - 1_000_000, 1_000_000, TimeUnit.SECONDS, 1, conf); + 1_000_000, 1_000_000, TimeUnit.SECONDS, 1, conf, new ContainerChecksumTreeManager(conf)); // On the first run, the container with incorrect metadata should consume // the block deletion limit, and the correct container with fewer pending @@ -813,7 +813,7 @@ public void testBlockDeletionTimeout(ContainerTestVersionInfo versionInfo) mockDependencies(containerSet, keyValueHandler); BlockDeletingService svc = new BlockDeletingService(ozoneContainer, TimeUnit.MILLISECONDS.toNanos(1000), timeout, TimeUnit.NANOSECONDS, - 10, conf); + 10, conf, new ContainerChecksumTreeManager(conf)); svc.start(); LogCapturer log = LogCapturer.captureLogs(BackgroundService.class); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerDeletionChoosingPolicy.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerDeletionChoosingPolicy.java index bd2e1237dd..0c7ede894b 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerDeletionChoosingPolicy.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerDeletionChoosingPolicy.java @@ -40,6 +40,7 @@ import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.scm.ScmConfigKeys; import org.apache.hadoop.ozone.container.ContainerTestHelper; +import org.apache.hadoop.ozone.container.checksum.ContainerChecksumTreeManager; import org.apache.hadoop.ozone.container.common.impl.BlockDeletingService.ContainerBlockInfo; import org.apache.hadoop.ozone.container.common.interfaces.ContainerDeletionChoosingPolicy; import org.apache.hadoop.ozone.container.keyvalue.ContainerLayoutTestInfo; @@ -218,7 +219,7 @@ private BlockDeletingService getBlockDeletingService() { when(ozoneContainer.getWriteChannel()).thenReturn(null); blockDeletingService = new BlockDeletingService(ozoneContainer, SERVICE_INTERVAL_IN_MILLISECONDS, SERVICE_TIMEOUT_IN_MILLISECONDS, - TimeUnit.MILLISECONDS, 10, conf); + TimeUnit.MILLISECONDS, 10, conf, new ContainerChecksumTreeManager(conf)); return blockDeletingService; } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@ozone.apache.org For additional commands, e-mail: commits-h...@ozone.apache.org