/// <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();
            }
        }