// expected
        /// <summary>
        /// Make sure a retry call does not hang because of the exception thrown in the
        /// first call.
        /// </summary>
        /// <exception cref="System.Exception"/>
        public virtual void TestUpdatePipelineWithFailOver()
        {
            cluster.Shutdown();
            nnRpc      = null;
            filesystem = null;
            cluster    = new MiniDFSCluster.Builder(conf).NnTopology(MiniDFSNNTopology.SimpleHATopology
                                                                         ()).NumDataNodes(1).Build();
            cluster.WaitActive();
            NamenodeProtocols ns0      = cluster.GetNameNodeRpc(0);
            ExtendedBlock     oldBlock = new ExtendedBlock();
            ExtendedBlock     newBlock = new ExtendedBlock();

            DatanodeID[] newNodes    = new DatanodeID[2];
            string[]     newStorages = new string[2];
            NewCall();
            try
            {
                ns0.UpdatePipeline("testClient", oldBlock, newBlock, newNodes, newStorages);
                NUnit.Framework.Assert.Fail("Expect StandbyException from the updatePipeline call"
                                            );
            }
            catch (StandbyException e)
            {
                // expected, since in the beginning both nn are in standby state
                GenericTestUtils.AssertExceptionContains(HAServiceProtocol.HAServiceState.Standby
                                                         .ToString(), e);
            }
            cluster.TransitionToActive(0);
            try
            {
                ns0.UpdatePipeline("testClient", oldBlock, newBlock, newNodes, newStorages);
            }
            catch (IOException)
            {
            }
        }
        public virtual void TestUpdatePipelineAfterDelete()
        {
            Configuration  conf    = new HdfsConfiguration();
            Path           file    = new Path("/test-file");
            MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).Build();

            try
            {
                FileSystem        fs       = cluster.GetFileSystem();
                NamenodeProtocols namenode = cluster.GetNameNodeRpc();
                DFSOutputStream   @out     = null;
                try
                {
                    // Create a file and make sure a block is allocated for it.
                    @out = (DFSOutputStream)(fs.Create(file).GetWrappedStream());
                    @out.Write(1);
                    @out.Hflush();
                    // Create a snapshot that includes the file.
                    SnapshotTestHelper.CreateSnapshot((DistributedFileSystem)fs, new Path("/"), "s1");
                    // Grab the block info of this file for later use.
                    FSDataInputStream @in      = null;
                    ExtendedBlock     oldBlock = null;
                    try
                    {
                        @in      = fs.Open(file);
                        oldBlock = DFSTestUtil.GetAllBlocks(@in)[0].GetBlock();
                    }
                    finally
                    {
                        IOUtils.CloseStream(@in);
                    }
                    // Allocate a new block ID/gen stamp so we can simulate pipeline
                    // recovery.
                    string       clientName      = ((DistributedFileSystem)fs).GetClient().GetClientName();
                    LocatedBlock newLocatedBlock = namenode.UpdateBlockForPipeline(oldBlock, clientName
                                                                                   );
                    ExtendedBlock newBlock = new ExtendedBlock(oldBlock.GetBlockPoolId(), oldBlock.GetBlockId
                                                                   (), oldBlock.GetNumBytes(), newLocatedBlock.GetBlock().GetGenerationStamp());
                    // Delete the file from the present FS. It will still exist the
                    // previously-created snapshot. This will log an OP_DELETE for the
                    // file in question.
                    fs.Delete(file, true);
                    // Simulate a pipeline recovery, wherein a new block is allocated
                    // for the existing block, resulting in an OP_UPDATE_BLOCKS being
                    // logged for the file in question.
                    try
                    {
                        namenode.UpdatePipeline(clientName, oldBlock, newBlock, newLocatedBlock.GetLocations
                                                    (), newLocatedBlock.GetStorageIDs());
                    }
                    catch (IOException ioe)
                    {
                        // normal
                        GenericTestUtils.AssertExceptionContains("does not exist or it is not under construction"
                                                                 , ioe);
                    }
                    // Make sure the NN can restart with the edit logs as we have them now.
                    cluster.RestartNameNode(true);
                }
                finally
                {
                    IOUtils.CloseStream(@out);
                }
            }
            finally
            {
                cluster.Shutdown();
            }
        }