/** * 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.hadoop.hdfs.server.namenode.snapshot; import com.google.common.collect.Lists; import org.apache.hadoop.hdfs.protocol.Block; import org.apache.hadoop.hdfs.protocol.BlockStoragePolicy; import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfo; import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfoContiguous; import org.apache.hadoop.hdfs.server.blockmanagement.BlockStoragePolicySuite; import org.apache.hadoop.hdfs.server.namenode.INode; import org.apache.hadoop.hdfs.server.namenode.INodeFile; import org.apache.hadoop.hdfs.server.namenode.QuotaCounts; import org.junit.Assert; import org.junit.Test; import org.mockito.internal.util.reflection.Whitebox; import java.util.ArrayList; import static org.apache.hadoop.fs.StorageType.DISK; import static org.apache.hadoop.fs.StorageType.SSD; import static org.mockito.Mockito.anyByte; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class TestFileWithSnapshotFeature { private static final int BLOCK_SIZE = 1024; private static final short REPL_3 = 3; private static final short REPL_1 = 1; @Test public void testUpdateQuotaAndCollectBlocks() { FileDiffList diffs = new FileDiffList(); FileWithSnapshotFeature sf = new FileWithSnapshotFeature(diffs); FileDiff diff = mock(FileDiff.class); BlockStoragePolicySuite bsps = mock(BlockStoragePolicySuite.class); BlockStoragePolicy bsp = mock(BlockStoragePolicy.class); BlockInfo[] blocks = new BlockInfo[] { new BlockInfoContiguous(new Block(1, BLOCK_SIZE, 1), REPL_1) }; // No snapshot INodeFile file = mock(INodeFile.class); when(file.getFileWithSnapshotFeature()).thenReturn(sf); when(file.getBlocks()).thenReturn(blocks); when(file.getStoragePolicyID()).thenReturn((byte) 1); when(bsps.getPolicy(anyByte())).thenReturn(bsp); INode.BlocksMapUpdateInfo collectedBlocks = mock( INode.BlocksMapUpdateInfo.class); ArrayList<INode> removedINodes = new ArrayList<>(); INode.ReclaimContext ctx = new INode.ReclaimContext( bsps, collectedBlocks, removedINodes, null); sf.updateQuotaAndCollectBlocks(ctx, file, diff); QuotaCounts counts = ctx.quotaDelta().getCountsCopy(); Assert.assertEquals(0, counts.getStorageSpace()); Assert.assertTrue(counts.getTypeSpaces().allLessOrEqual(0)); // INode only exists in the snapshot INodeFile snapshotINode = mock(INodeFile.class); when(file.getPreferredBlockReplication()).thenReturn(REPL_1); Whitebox.setInternalState(snapshotINode, "header", (long) REPL_3 << 48); Whitebox.setInternalState(diff, "snapshotINode", snapshotINode); when(diff.getSnapshotINode()).thenReturn(snapshotINode); when(bsp.chooseStorageTypes(REPL_1)) .thenReturn(Lists.newArrayList(SSD)); when(bsp.chooseStorageTypes(REPL_3)) .thenReturn(Lists.newArrayList(DISK)); sf.updateQuotaAndCollectBlocks(ctx, file, diff); counts = ctx.quotaDelta().getCountsCopy(); Assert.assertEquals((REPL_3 - REPL_1) * BLOCK_SIZE, counts.getStorageSpace()); Assert.assertEquals(BLOCK_SIZE, counts.getTypeSpaces().get(DISK)); Assert.assertEquals(-BLOCK_SIZE, counts.getTypeSpaces().get(SSD)); } }