|
@@ -29,7 +29,13 @@ import static org.mockito.Mockito.reset;
|
|
import static org.mockito.Mockito.spy;
|
|
import static org.mockito.Mockito.spy;
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.verify;
|
|
|
|
|
|
|
|
+import java.io.BufferedReader;
|
|
|
|
+import java.io.DataInputStream;
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.io.FileInputStream;
|
|
|
|
+import java.io.InputStreamReader;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
|
+import java.io.PrintWriter;
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.Collections;
|
|
@@ -527,6 +533,22 @@ public class TestBlockManager {
|
|
return blockInfo;
|
|
return blockInfo;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private BlockInfo addCorruptBlockOnNodes(long blockId,
|
|
|
|
+ List<DatanodeDescriptor> nodes) throws IOException {
|
|
|
|
+ long inodeId = ++mockINodeId;
|
|
|
|
+ final INodeFile bc = TestINodeFile.createINodeFile(inodeId);
|
|
|
|
+
|
|
|
|
+ BlockInfo blockInfo = blockOnNodes(blockId, nodes);
|
|
|
|
+ blockInfo.setReplication((short) 3);
|
|
|
|
+ blockInfo.setBlockCollectionId(inodeId);
|
|
|
|
+ Mockito.doReturn(bc).when(fsn).getBlockCollection(inodeId);
|
|
|
|
+ bm.blocksMap.addBlockCollection(blockInfo, bc);
|
|
|
|
+ bm.markBlockReplicasAsCorrupt(blockInfo, blockInfo,
|
|
|
|
+ blockInfo.getGenerationStamp() + 1, blockInfo.getNumBytes(),
|
|
|
|
+ new DatanodeStorageInfo[]{nodes.get(0).getStorageInfos()[0]});
|
|
|
|
+ return blockInfo;
|
|
|
|
+ }
|
|
|
|
+
|
|
private DatanodeStorageInfo[] scheduleSingleReplication(BlockInfo block) {
|
|
private DatanodeStorageInfo[] scheduleSingleReplication(BlockInfo block) {
|
|
// list for priority 1
|
|
// list for priority 1
|
|
List<BlockInfo> list_p1 = new ArrayList<>();
|
|
List<BlockInfo> list_p1 = new ArrayList<>();
|
|
@@ -1129,4 +1151,40 @@ public class TestBlockManager {
|
|
cluster.shutdown();
|
|
cluster.shutdown();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testMetaSaveCorruptBlocks() throws Exception {
|
|
|
|
+ List<DatanodeStorageInfo> origStorages = getStorages(0, 1);
|
|
|
|
+ List<DatanodeDescriptor> origNodes = getNodes(origStorages);
|
|
|
|
+ addCorruptBlockOnNodes(0, origNodes);
|
|
|
|
+ File file = new File("test.log");
|
|
|
|
+ PrintWriter out = new PrintWriter(file);
|
|
|
|
+ bm.metaSave(out);
|
|
|
|
+ out.flush();
|
|
|
|
+ FileInputStream fstream = new FileInputStream(file);
|
|
|
|
+ DataInputStream in = new DataInputStream(fstream);
|
|
|
|
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
|
|
|
+ try {
|
|
|
|
+ for(int i =0;i<6;i++) {
|
|
|
|
+ reader.readLine();
|
|
|
|
+ }
|
|
|
|
+ String corruptBlocksLine = reader.readLine();
|
|
|
|
+ assertEquals("Unexpected text in metasave," +
|
|
|
|
+ "was expecting corrupt blocks section!", 0,
|
|
|
|
+ corruptBlocksLine.compareTo("Corrupt Blocks:"));
|
|
|
|
+ corruptBlocksLine = reader.readLine();
|
|
|
|
+ String regex = "Block=[0-9]+\\tNode=.*\\tStorageID=.*StorageState.*" +
|
|
|
|
+ "TotalReplicas=.*Reason=GENSTAMP_MISMATCH";
|
|
|
|
+ assertTrue("Unexpected corrupt block section in metasave!",
|
|
|
|
+ corruptBlocksLine.matches(regex));
|
|
|
|
+ corruptBlocksLine = reader.readLine();
|
|
|
|
+ regex = "Metasave: Number of datanodes.*";
|
|
|
|
+ assertTrue("Unexpected corrupt block section in metasave!",
|
|
|
|
+ corruptBlocksLine.matches(regex));
|
|
|
|
+ } finally {
|
|
|
|
+ if (reader != null)
|
|
|
|
+ reader.close();
|
|
|
|
+ file.delete();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|