public virtual void TestCorruptBlockRereplicatedAcrossRacks() { Configuration conf = GetConf(); short ReplicationFactor = 2; int fileLen = 512; Path filePath = new Path("/testFile"); // Datanodes are spread across two racks string[] racks = new string[] { "/rack1", "/rack1", "/rack2", "/rack2" }; MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(racks.Length ).Racks(racks).Build(); FSNamesystem ns = cluster.GetNameNode().GetNamesystem(); try { // Create a file with one block with a replication factor of 2 FileSystem fs = cluster.GetFileSystem(); DFSTestUtil.CreateFile(fs, filePath, fileLen, ReplicationFactor, 1L); string fileContent = DFSTestUtil.ReadFile(fs, filePath); ExtendedBlock b = DFSTestUtil.GetFirstBlock(fs, filePath); DFSTestUtil.WaitForReplication(cluster, b, 2, ReplicationFactor, 0); // Corrupt a replica of the block int dnToCorrupt = DFSTestUtil.FirstDnWithBlock(cluster, b); NUnit.Framework.Assert.IsTrue(cluster.CorruptReplica(dnToCorrupt, b)); // Restart the datanode so blocks are re-scanned, and the corrupt // block is detected. cluster.RestartDataNode(dnToCorrupt); // Wait for the namenode to notice the corrupt replica DFSTestUtil.WaitCorruptReplicas(fs, ns, filePath, b, 1); // The rack policy is still respected DFSTestUtil.WaitForReplication(cluster, b, 2, ReplicationFactor, 0); // Ensure all replicas are valid (the corrupt replica may not // have been cleaned up yet). for (int i = 0; i < racks.Length; i++) { string blockContent = cluster.ReadBlockOnDataNode(i, b); if (blockContent != null && i != dnToCorrupt) { NUnit.Framework.Assert.AreEqual("Corrupt replica", fileContent, blockContent); } } } finally { cluster.Shutdown(); } }