/// <summary> /// Test when a block's replica is removed from RBW folder in one of the /// datanode, namenode should ask to invalidate that corrupted block and /// schedule replication for one more replica for that under replicated block. /// </summary> /// <exception cref="System.IO.IOException"/> /// <exception cref="System.Exception"/> public virtual void TestBlockInvalidationWhenRBWReplicaMissedInDN() { // This test cannot pass on Windows due to file locking enforcement. It will // reject the attempt to delete the block file from the RBW folder. Assume.AssumeTrue(!Path.Windows); Configuration conf = new HdfsConfiguration(); conf.SetInt(DFSConfigKeys.DfsReplicationKey, 2); conf.SetLong(DFSConfigKeys.DfsBlockreportIntervalMsecKey, 300); conf.SetLong(DFSConfigKeys.DfsDatanodeDirectoryscanIntervalKey, 1); conf.SetLong(DFSConfigKeys.DfsHeartbeatIntervalKey, 1); MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(2).Build(); FSDataOutputStream @out = null; try { FSNamesystem namesystem = cluster.GetNamesystem(); FileSystem fs = cluster.GetFileSystem(); Path testPath = new Path("/tmp/TestRBWBlockInvalidation", "foo1"); @out = fs.Create(testPath, (short)2); @out.WriteBytes("HDFS-3157: " + testPath); @out.Hsync(); cluster.StartDataNodes(conf, 1, true, null, null, null); string bpid = namesystem.GetBlockPoolId(); ExtendedBlock blk = DFSTestUtil.GetFirstBlock(fs, testPath); Block block = blk.GetLocalBlock(); DataNode dn = cluster.GetDataNodes()[0]; // Delete partial block and its meta information from the RBW folder // of first datanode. FilePath blockFile = DataNodeTestUtils.GetBlockFile(dn, bpid, block); FilePath metaFile = DataNodeTestUtils.GetMetaFile(dn, bpid, block); NUnit.Framework.Assert.IsTrue("Could not delete the block file from the RBW folder" , blockFile.Delete()); NUnit.Framework.Assert.IsTrue("Could not delete the block meta file from the RBW folder" , metaFile.Delete()); @out.Close(); int liveReplicas = 0; while (true) { if ((liveReplicas = CountReplicas(namesystem, blk).LiveReplicas()) < 2) { // This confirms we have a corrupt replica Log.Info("Live Replicas after corruption: " + liveReplicas); break; } Sharpen.Thread.Sleep(100); } NUnit.Framework.Assert.AreEqual("There should be less than 2 replicas in the " + "liveReplicasMap", 1, liveReplicas); while (true) { if ((liveReplicas = CountReplicas(namesystem, blk).LiveReplicas()) > 1) { //Wait till the live replica count becomes equal to Replication Factor Log.Info("Live Replicas after Rereplication: " + liveReplicas); break; } Sharpen.Thread.Sleep(100); } NUnit.Framework.Assert.AreEqual("There should be two live replicas", 2, liveReplicas ); while (true) { Sharpen.Thread.Sleep(100); if (CountReplicas(namesystem, blk).CorruptReplicas() == 0) { Log.Info("Corrupt Replicas becomes 0"); break; } } } finally { if (@out != null) { @out.Close(); } cluster.Shutdown(); } }