Пример #1
0
        /// <summary>
        /// If we have a UNIX domain socket configured,
        /// and we have dfs.client.domain.socket.data.traffic set to true,
        /// and short-circuit access fails, we should still be able to pass
        /// data traffic over the UNIX domain socket.
        /// </summary>
        /// <remarks>
        /// If we have a UNIX domain socket configured,
        /// and we have dfs.client.domain.socket.data.traffic set to true,
        /// and short-circuit access fails, we should still be able to pass
        /// data traffic over the UNIX domain socket.  Test this.
        /// </remarks>
        /// <exception cref="System.Exception"/>
        public virtual void TestFallbackFromShortCircuitToUnixDomainTraffic()
        {
            DFSInputStream.tcpReadsDisabledForTesting = true;
            TemporarySocketDirectory sockDir = new TemporarySocketDirectory();
            // The server is NOT configured with short-circuit local reads;
            // the client is.  Both support UNIX domain reads.
            Configuration clientConf = CreateShortCircuitConf("testFallbackFromShortCircuitToUnixDomainTraffic"
                                                              , sockDir);

            clientConf.Set(DFSConfigKeys.DfsClientContext, "testFallbackFromShortCircuitToUnixDomainTraffic_clientContext"
                           );
            clientConf.SetBoolean(DFSConfigKeys.DfsClientDomainSocketDataTraffic, true);
            Configuration serverConf = new Configuration(clientConf);

            serverConf.SetBoolean(DFSConfigKeys.DfsClientReadShortcircuitKey, false);
            MiniDFSCluster cluster = new MiniDFSCluster.Builder(serverConf).NumDataNodes(1).Build
                                         ();

            cluster.WaitActive();
            FileSystem dfs         = FileSystem.Get(cluster.GetURI(0), clientConf);
            string     TestFile    = "/test_file";
            int        TestFileLen = 8193;
            int        Seed        = unchecked ((int)(0xFADED));

            DFSTestUtil.CreateFile(dfs, new Path(TestFile), TestFileLen, (short)1, Seed);
            byte[] contents = DFSTestUtil.ReadFileBuffer(dfs, new Path(TestFile));
            byte[] expected = DFSTestUtil.CalculateFileContentsFromSeed(Seed, TestFileLen);
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(contents, expected));
            cluster.Shutdown();
            sockDir.Close();
        }
Пример #2
0
        // Regression test for HDFS-8070
        /// <exception cref="System.Exception"/>
        public virtual void TestPreReceiptVerificationDfsClientCanDoScr()
        {
            BlockReaderTestUtil.EnableShortCircuitShmTracing();
            TemporarySocketDirectory sockDir = new TemporarySocketDirectory();
            Configuration            conf    = CreateShortCircuitConf("testPreReceiptVerificationDfsClientCanDoScr"
                                                                      , sockDir);

            conf.SetLong(DFSConfigKeys.DfsClientReadShortcircuitStreamsCacheExpiryMsKey, 1000000000L
                         );
            MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(1).Build();

            cluster.WaitActive();
            DistributedFileSystem fs = cluster.GetFileSystem();

            fs.GetClient().GetConf().brfFailureInjector = new TestShortCircuitCache.TestPreReceiptVerificationFailureInjector
                                                              ();
            Path TestPath1 = new Path("/test_file1");

            DFSTestUtil.CreateFile(fs, TestPath1, 4096, (short)1, unchecked ((int)(0xFADE2)));
            Path TestPath2 = new Path("/test_file2");

            DFSTestUtil.CreateFile(fs, TestPath2, 4096, (short)1, unchecked ((int)(0xFADE2)));
            DFSTestUtil.ReadFileBuffer(fs, TestPath1);
            DFSTestUtil.ReadFileBuffer(fs, TestPath2);
            ShortCircuitRegistry registry = cluster.GetDataNodes()[0].GetShortCircuitRegistry
                                                ();

            registry.Visit(new _Visitor_780());
            cluster.Shutdown();
            sockDir.Close();
        }
Пример #3
0
        public virtual void TestShortCircuitCacheShutdown()
        {
            TemporarySocketDirectory sockDir = new TemporarySocketDirectory();
            Configuration            conf    = CreateShortCircuitConf("testShortCircuitCacheShutdown", sockDir
                                                                      );

            conf.Set(DFSConfigKeys.DfsClientContext, "testShortCircuitCacheShutdown");
            Configuration serverConf = new Configuration(conf);

            DFSInputStream.tcpReadsDisabledForTesting = true;
            MiniDFSCluster cluster = new MiniDFSCluster.Builder(serverConf).NumDataNodes(1).Build
                                         ();

            cluster.WaitActive();
            DistributedFileSystem fs = (DistributedFileSystem)FileSystem.Get(cluster.GetURI(0
                                                                                            ), conf);
            string TestFile    = "/test_file";
            int    TestFileLen = 4000;
            int    Seed        = unchecked ((int)(0xFADEC));

            DFSTestUtil.CreateFile(fs, new Path(TestFile), TestFileLen, (short)1, Seed);
            byte[] contents = DFSTestUtil.ReadFileBuffer(fs, new Path(TestFile));
            byte[] expected = DFSTestUtil.CalculateFileContentsFromSeed(Seed, TestFileLen);
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(contents, expected));
            ShortCircuitCache cache = fs.dfs.GetClientContext().GetShortCircuitCache();

            cache.Close();
            NUnit.Framework.Assert.IsTrue(cache.GetDfsClientShmManager().GetDomainSocketWatcher
                                              ().IsClosed());
            cluster.Shutdown();
            sockDir.Close();
        }
Пример #4
0
        /// <summary>
        /// Test the case that remove a data volume on a particular DataNode when the
        /// volume is actively being written.
        /// </summary>
        /// <param name="dataNodeIdx">the index of the DataNode to remove a volume.</param>
        /// <exception cref="System.IO.IOException"/>
        /// <exception cref="Org.Apache.Hadoop.Conf.ReconfigurationException"/>
        /// <exception cref="Sharpen.TimeoutException"/>
        /// <exception cref="System.Exception"/>
        /// <exception cref="Sharpen.BrokenBarrierException"/>
        private void TestRemoveVolumeBeingWrittenForDatanode(int dataNodeIdx)
        {
            // Starts DFS cluster with 3 DataNodes to form a pipeline.
            StartDFSCluster(1, 3);
            short              Replication            = 3;
            DataNode           dn                     = cluster.GetDataNodes()[dataNodeIdx];
            FileSystem         fs                     = cluster.GetFileSystem();
            Path               testFile               = new Path("/test");
            long               lastTimeDiskErrorCheck = dn.GetLastDiskErrorCheck();
            FSDataOutputStream @out                   = fs.Create(testFile, Replication);
            Random             rb                     = new Random(0);

            byte[] writeBuf = new byte[BlockSize / 2];
            // half of the block.
            rb.NextBytes(writeBuf);
            @out.Write(writeBuf);
            @out.Hflush();
            // Make FsDatasetSpi#finalizeBlock a time-consuming operation. So if the
            // BlockReceiver releases volume reference before finalizeBlock(), the blocks
            // on the volume will be removed, and finalizeBlock() throws IOE.
            FsDatasetSpi <FsVolumeSpi> data = dn.data;

            dn.data = Org.Mockito.Mockito.Spy(data);
            Org.Mockito.Mockito.DoAnswer(new _Answer_599(data)).When(dn.data).FinalizeBlock(Matchers.Any
                                                                                            <ExtendedBlock>());
            // Bypass the argument to FsDatasetImpl#finalizeBlock to verify that
            // the block is not removed, since the volume reference should not
            // be released at this point.
            CyclicBarrier  barrier = new CyclicBarrier(2);
            IList <string> oldDirs = GetDataDirs(dn);
            string         newDirs = oldDirs[1];
            // Remove the first volume.
            IList <Exception> exceptions = new AList <Exception>();

            Sharpen.Thread reconfigThread = new _Thread_616(barrier, dn, newDirs, exceptions);
            reconfigThread.Start();
            barrier.Await();
            rb.NextBytes(writeBuf);
            @out.Write(writeBuf);
            @out.Hflush();
            @out.Close();
            reconfigThread.Join();
            // Verify the file has sufficient replications.
            DFSTestUtil.WaitReplication(fs, testFile, Replication);
            // Read the content back
            byte[] content = DFSTestUtil.ReadFileBuffer(fs, testFile);
            NUnit.Framework.Assert.AreEqual(BlockSize, content.Length);
            // If an IOException thrown from BlockReceiver#run, it triggers
            // DataNode#checkDiskError(). So we can test whether checkDiskError() is called,
            // to see whether there is IOException in BlockReceiver#run().
            NUnit.Framework.Assert.AreEqual(lastTimeDiskErrorCheck, dn.GetLastDiskErrorCheck(
                                                ));
            if (!exceptions.IsEmpty())
            {
                throw new IOException(exceptions[0].InnerException);
            }
        }
Пример #5
0
        // Regression test for HADOOP-11802
        /// <exception cref="System.Exception"/>
        public virtual void TestDataXceiverHandlesRequestShortCircuitShmFailure()
        {
            BlockReaderTestUtil.EnableShortCircuitShmTracing();
            TemporarySocketDirectory sockDir = new TemporarySocketDirectory();
            Configuration            conf    = CreateShortCircuitConf("testDataXceiverHandlesRequestShortCircuitShmFailure"
                                                                      , sockDir);

            conf.SetLong(DFSConfigKeys.DfsClientReadShortcircuitStreamsCacheExpiryMsKey, 1000000000L
                         );
            MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(1).Build();

            cluster.WaitActive();
            DistributedFileSystem fs = cluster.GetFileSystem();
            Path TestPath1           = new Path("/test_file1");

            DFSTestUtil.CreateFile(fs, TestPath1, 4096, (short)1, unchecked ((int)(0xFADE1)));
            Log.Info("Setting failure injector and performing a read which " + "should fail..."
                     );
            DataNodeFaultInjector failureInjector = Org.Mockito.Mockito.Mock <DataNodeFaultInjector
                                                                              >();

            Org.Mockito.Mockito.DoAnswer(new _Answer_710()).When(failureInjector).SendShortCircuitShmResponse
                ();
            DataNodeFaultInjector prevInjector = DataNodeFaultInjector.instance;

            DataNodeFaultInjector.instance = failureInjector;
            try
            {
                // The first read will try to allocate a shared memory segment and slot.
                // The shared memory segment allocation will fail because of the failure
                // injector.
                DFSTestUtil.ReadFileBuffer(fs, TestPath1);
                NUnit.Framework.Assert.Fail("expected readFileBuffer to fail, but it succeeded.");
            }
            catch (Exception t)
            {
                GenericTestUtils.AssertExceptionContains("TCP reads were disabled for " + "testing, but we failed to do a non-TCP read."
                                                         , t);
            }
            CheckNumberOfSegmentsAndSlots(0, 0, cluster.GetDataNodes()[0].GetShortCircuitRegistry
                                              ());
            Log.Info("Clearing failure injector and performing another read...");
            DataNodeFaultInjector.instance = prevInjector;
            fs.GetClient().GetClientContext().GetDomainSocketFactory().ClearPathMap();
            // The second read should succeed.
            DFSTestUtil.ReadFileBuffer(fs, TestPath1);
            // We should have added a new short-circuit shared memory segment and slot.
            CheckNumberOfSegmentsAndSlots(1, 1, cluster.GetDataNodes()[0].GetShortCircuitRegistry
                                              ());
            cluster.Shutdown();
            sockDir.Close();
        }
Пример #6
0
 // expected
 /// <summary>Asserts that permission is granted to the given fs/user for the given file.
 ///     </summary>
 /// <param name="fs">FileSystem to check</param>
 /// <param name="user">UserGroupInformation owner of fs</param>
 /// <param name="pathToCheck">Path file to check</param>
 /// <exception cref="System.Exception">if there is an unexpected error</exception>
 public static void AssertFilePermissionGranted(FileSystem fs, UserGroupInformation
                                                user, Path pathToCheck)
 {
     try
     {
         DFSTestUtil.ReadFileBuffer(fs, pathToCheck);
     }
     catch (AccessControlException)
     {
         NUnit.Framework.Assert.Fail("expected permission granted for user " + user + ", path = "
                                     + pathToCheck);
     }
 }
Пример #7
0
 public void Run()
 {
     try
     {
         byte[] contents = DFSTestUtil.ReadFileBuffer(dfs, new Path(TestFile));
         NUnit.Framework.Assert.IsFalse(creationIsBlocked.Get());
         byte[] expected = DFSTestUtil.CalculateFileContentsFromSeed(Seed, TestFileLen);
         NUnit.Framework.Assert.IsTrue(Arrays.Equals(contents, expected));
     }
     catch (Exception e)
     {
         TestBlockReaderFactory.Log.Error("readerRunnable error", e);
         testFailed.Set(true);
     }
 }
Пример #8
0
        /// <summary>Test unlinking a file whose blocks we are caching in the DFSClient.</summary>
        /// <remarks>
        /// Test unlinking a file whose blocks we are caching in the DFSClient.
        /// The DataNode will notify the DFSClient that the replica is stale via the
        /// ShortCircuitShm.
        /// </remarks>
        /// <exception cref="System.Exception"/>
        public virtual void TestUnlinkingReplicasInFileDescriptorCache()
        {
            BlockReaderTestUtil.EnableShortCircuitShmTracing();
            TemporarySocketDirectory sockDir = new TemporarySocketDirectory();
            Configuration            conf    = CreateShortCircuitConf("testUnlinkingReplicasInFileDescriptorCache"
                                                                      , sockDir);

            // We don't want the CacheCleaner to time out short-circuit shared memory
            // segments during the test, so set the timeout really high.
            conf.SetLong(DFSConfigKeys.DfsClientReadShortcircuitStreamsCacheExpiryMsKey, 1000000000L
                         );
            MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(1).Build();

            cluster.WaitActive();
            DistributedFileSystem fs    = cluster.GetFileSystem();
            ShortCircuitCache     cache = fs.GetClient().GetClientContext().GetShortCircuitCache(
                );

            cache.GetDfsClientShmManager().Visit(new _Visitor_556());
            // The ClientShmManager starts off empty.
            Path TestPath    = new Path("/test_file");
            int  TestFileLen = 8193;
            int  Seed        = unchecked ((int)(0xFADE0));

            DFSTestUtil.CreateFile(fs, TestPath, TestFileLen, (short)1, Seed);
            byte[] contents = DFSTestUtil.ReadFileBuffer(fs, TestPath);
            byte[] expected = DFSTestUtil.CalculateFileContentsFromSeed(Seed, TestFileLen);
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(contents, expected));
            // Loading this file brought the ShortCircuitReplica into our local
            // replica cache.
            DatanodeInfo datanode = new DatanodeInfo(cluster.GetDataNodes()[0].GetDatanodeId(
                                                         ));

            cache.GetDfsClientShmManager().Visit(new _Visitor_577(datanode));
            // Remove the file whose blocks we just read.
            fs.Delete(TestPath, false);
            // Wait for the replica to be purged from the DFSClient's cache.
            GenericTestUtils.WaitFor(new _Supplier_593(this, cache, datanode), 10, 60000);
            // Check that all slots have been invalidated.
            cluster.Shutdown();
            sockDir.Close();
        }
Пример #9
0
        /// <exception cref="System.IO.IOException"/>
        /// <exception cref="System.Exception"/>
        public virtual void DoShortCircuitReadBlockFileCorruptionTest()
        {
            string MethodName = GenericTestUtils.GetMethodName();
            Path   path1      = new Path("/" + MethodName + ".01.dat");
            Path   path2      = new Path("/" + MethodName + ".02.dat");
            int    Seed       = unchecked ((int)(0xFADED));

            MakeRandomTestFile(path1, BlockSize, true, Seed);
            EnsureFileReplicasOnStorageType(path1, StorageType.RamDisk);
            // Create another file with a replica on RAM_DISK, which evicts the first.
            MakeRandomTestFile(path2, BlockSize, true, Seed);
            // Sleep for a short time to allow the lazy writer thread to do its job.
            Sharpen.Thread.Sleep(3 * LazyWriterIntervalSec * 1000);
            TriggerBlockReport();
            // Corrupt the lazy-persisted block file, and verify that checksum
            // verification catches it.
            EnsureFileReplicasOnStorageType(path1, StorageType.Default);
            cluster.CorruptReplica(0, DFSTestUtil.GetFirstBlock(fs, path1));
            exception.Expect(typeof(ChecksumException));
            DFSTestUtil.ReadFileBuffer(fs, path1);
        }
Пример #10
0
        // Regression test for HDFS-7915
        /// <exception cref="System.Exception"/>
        public virtual void TestDataXceiverCleansUpSlotsOnFailure()
        {
            BlockReaderTestUtil.EnableShortCircuitShmTracing();
            TemporarySocketDirectory sockDir = new TemporarySocketDirectory();
            Configuration            conf    = CreateShortCircuitConf("testDataXceiverCleansUpSlotsOnFailure"
                                                                      , sockDir);

            conf.SetLong(DFSConfigKeys.DfsClientReadShortcircuitStreamsCacheExpiryMsKey, 1000000000L
                         );
            MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(1).Build();

            cluster.WaitActive();
            DistributedFileSystem fs = cluster.GetFileSystem();
            Path TestPath1           = new Path("/test_file1");
            Path TestPath2           = new Path("/test_file2");
            int  TestFileLen         = 4096;
            int  Seed = unchecked ((int)(0xFADE1));

            DFSTestUtil.CreateFile(fs, TestPath1, TestFileLen, (short)1, Seed);
            DFSTestUtil.CreateFile(fs, TestPath2, TestFileLen, (short)1, Seed);
            // The first read should allocate one shared memory segment and slot.
            DFSTestUtil.ReadFileBuffer(fs, TestPath1);
            // The second read should fail, and we should only have 1 segment and 1 slot
            // left.
            fs.GetClient().GetConf().brfFailureInjector = new TestShortCircuitCache.TestCleanupFailureInjector
                                                              ();
            try
            {
                DFSTestUtil.ReadFileBuffer(fs, TestPath2);
            }
            catch (Exception t)
            {
                GenericTestUtils.AssertExceptionContains("TCP reads were disabled for " + "testing, but we failed to do a non-TCP read."
                                                         , t);
            }
            CheckNumberOfSegmentsAndSlots(1, 1, cluster.GetDataNodes()[0].GetShortCircuitRegistry
                                              ());
            cluster.Shutdown();
            sockDir.Close();
        }
Пример #11
0
        /// <summary>
        /// Support for layout version change with rolling upgrade was
        /// added by HDFS-6800 and HDFS-6981.
        /// </summary>
        /// <exception cref="System.Exception"/>
        public virtual void TestWithLayoutChangeAndRollback()
        {
            long seed = unchecked ((int)(0x600DF00D));

            try
            {
                StartCluster();
                Path[]     paths      = new Path[3];
                FilePath[] blockFiles = new FilePath[3];
                // Create two files in DFS.
                for (int i = 0; i < 2; ++i)
                {
                    paths[i] = new Path("/" + GenericTestUtils.GetMethodName() + "." + i + ".dat");
                    DFSTestUtil.CreateFile(fs, paths[i], BlockSize, (short)1, seed);
                }
                StartRollingUpgrade();
                // Delete the first file. The DN will save its block files in trash.
                blockFiles[0] = GetBlockForFile(paths[0], true);
                FilePath trashFile0 = GetTrashFileForBlock(blockFiles[0], false);
                DeleteAndEnsureInTrash(paths[0], blockFiles[0], trashFile0);
                // Restart the DN with a new layout version to trigger layout upgrade.
                Log.Info("Shutting down the Datanode");
                MiniDFSCluster.DataNodeProperties dnprop = cluster.StopDataNode(0);
                DFSTestUtil.AddDataNodeLayoutVersion(DataNodeLayoutVersion.CurrentLayoutVersion -
                                                     1, "Test Layout for TestDataNodeRollingUpgrade");
                Log.Info("Restarting the DataNode");
                cluster.RestartDataNode(dnprop, true);
                cluster.WaitActive();
                dn0 = cluster.GetDataNodes()[0];
                Log.Info("The DN has been restarted");
                NUnit.Framework.Assert.IsFalse(trashFile0.Exists());
                NUnit.Framework.Assert.IsFalse(dn0.GetStorage().GetBPStorage(blockPoolId).IsTrashAllowed
                                                   (blockFiles[0]));
                // Ensure that the block file for the first file was moved from 'trash' to 'previous'.
                NUnit.Framework.Assert.IsTrue(IsBlockFileInPrevious(blockFiles[0]));
                NUnit.Framework.Assert.IsFalse(IsTrashRootPresent());
                // Delete the second file. Ensure that its block file is in previous.
                blockFiles[1] = GetBlockForFile(paths[1], true);
                fs.Delete(paths[1], false);
                NUnit.Framework.Assert.IsTrue(IsBlockFileInPrevious(blockFiles[1]));
                NUnit.Framework.Assert.IsFalse(IsTrashRootPresent());
                // Create and delete a third file. Its block file should not be
                // in either trash or previous after deletion.
                paths[2] = new Path("/" + GenericTestUtils.GetMethodName() + ".2.dat");
                DFSTestUtil.CreateFile(fs, paths[2], BlockSize, (short)1, seed);
                blockFiles[2] = GetBlockForFile(paths[2], true);
                fs.Delete(paths[2], false);
                NUnit.Framework.Assert.IsFalse(IsBlockFileInPrevious(blockFiles[2]));
                NUnit.Framework.Assert.IsFalse(IsTrashRootPresent());
                // Rollback and ensure that the first two file contents were restored.
                RollbackRollingUpgrade();
                for (int i_1 = 0; i_1 < 2; ++i_1)
                {
                    byte[] actual     = DFSTestUtil.ReadFileBuffer(fs, paths[i_1]);
                    byte[] calculated = DFSTestUtil.CalculateFileContentsFromSeed(seed, BlockSize);
                    Assert.AssertArrayEquals(actual, calculated);
                }
                // And none of the block files must be in previous or trash.
                NUnit.Framework.Assert.IsFalse(IsTrashRootPresent());
                for (int i_2 = 0; i_2 < 3; ++i_2)
                {
                    NUnit.Framework.Assert.IsFalse(IsBlockFileInPrevious(blockFiles[i_2]));
                }
            }
            finally
            {
                ShutdownCluster();
            }
        }
Пример #12
0
 /// <exception cref="System.IO.IOException"/>
 protected internal bool VerifyReadRandomFile(Path path, int fileLength, int seed)
 {
     byte[] contents = DFSTestUtil.ReadFileBuffer(fs, path);
     byte[] expected = DFSTestUtil.CalculateFileContentsFromSeed(seed, fileLength);
     return(Arrays.Equals(contents, expected));
 }
Пример #13
0
        /// <summary>
        /// Test that we cannot read a file beyond its snapshot length
        /// when accessing it via a snapshot path.
        /// </summary>
        /// <exception cref="System.Exception"/>
        public virtual void TestSnapshotfileLength()
        {
            hdfs.Mkdirs(sub);
            int bytesRead;

            byte[]            buffer     = new byte[Blocksize * 8];
            int               origLen    = Blocksize + 1;
            int               toAppend   = Blocksize;
            FSDataInputStream fis        = null;
            FileStatus        fileStatus = null;
            // Create and write a file.
            Path file1 = new Path(sub, file1Name);

            DFSTestUtil.CreateFile(hdfs, file1, Blocksize, 0, Blocksize, Replication, Seed);
            DFSTestUtil.AppendFile(hdfs, file1, origLen);
            // Create a snapshot on the parent directory.
            hdfs.AllowSnapshot(sub);
            hdfs.CreateSnapshot(sub, snapshot1);
            Path         file1snap1  = SnapshotTestHelper.GetSnapshotPath(sub, snapshot1, file1Name);
            FileChecksum snapChksum1 = hdfs.GetFileChecksum(file1snap1);

            Assert.AssertThat("file and snapshot file checksums are not equal", hdfs.GetFileChecksum
                                  (file1), CoreMatchers.Is(snapChksum1));
            // Append to the file.
            FSDataOutputStream @out = hdfs.Append(file1);

            // Nothing has been appended yet. All checksums should still be equal.
            Assert.AssertThat("file and snapshot checksums (open for append) are not equal",
                              hdfs.GetFileChecksum(file1), CoreMatchers.Is(snapChksum1));
            Assert.AssertThat("snapshot checksum (post-open for append) has changed", hdfs.GetFileChecksum
                                  (file1snap1), CoreMatchers.Is(snapChksum1));
            try
            {
                AppendTestUtil.Write(@out, 0, toAppend);
                // Test reading from snapshot of file that is open for append
                byte[] dataFromSnapshot = DFSTestUtil.ReadFileBuffer(hdfs, file1snap1);
                Assert.AssertThat("Wrong data size in snapshot.", dataFromSnapshot.Length, CoreMatchers.Is
                                      (origLen));
                // Verify that checksum didn't change
                Assert.AssertThat("snapshot file checksum (pre-close) has changed", hdfs.GetFileChecksum
                                      (file1), CoreMatchers.Is(snapChksum1));
                Assert.AssertThat("snapshot checksum (post-append) has changed", hdfs.GetFileChecksum
                                      (file1snap1), CoreMatchers.Is(snapChksum1));
            }
            finally
            {
                @out.Close();
            }
            Assert.AssertThat("file and snapshot file checksums (post-close) are equal", hdfs
                              .GetFileChecksum(file1), CoreMatchers.Not(snapChksum1));
            Assert.AssertThat("snapshot file checksum (post-close) has changed", hdfs.GetFileChecksum
                                  (file1snap1), CoreMatchers.Is(snapChksum1));
            // Make sure we can read the entire file via its non-snapshot path.
            fileStatus = hdfs.GetFileStatus(file1);
            Assert.AssertThat(fileStatus.GetLen(), CoreMatchers.Is((long)origLen + toAppend));
            fis       = hdfs.Open(file1);
            bytesRead = fis.Read(0, buffer, 0, buffer.Length);
            Assert.AssertThat(bytesRead, CoreMatchers.Is(origLen + toAppend));
            fis.Close();
            // Try to open the file via its snapshot path.
            fis        = hdfs.Open(file1snap1);
            fileStatus = hdfs.GetFileStatus(file1snap1);
            Assert.AssertThat(fileStatus.GetLen(), CoreMatchers.Is((long)origLen));
            // Make sure we can only read up to the snapshot length.
            bytesRead = fis.Read(0, buffer, 0, buffer.Length);
            Assert.AssertThat(bytesRead, CoreMatchers.Is(origLen));
            fis.Close();
            byte[] dataFromSnapshot_1 = DFSTestUtil.ReadFileBuffer(hdfs, file1snap1);
            Assert.AssertThat("Wrong data size in snapshot.", dataFromSnapshot_1.Length, CoreMatchers.Is
                                  (origLen));
        }