/// <summary>Test listing snapshots under a snapshottable directory</summary>
        /// <exception cref="System.Exception"/>
        public virtual void TestListSnapshots()
        {
            Path snapshotsPath = new Path(dir, ".snapshot");

            FileStatus[] stats = null;
            // special case: snapshots of root
            stats = hdfs.ListStatus(new Path("/.snapshot"));
            // should be 0 since root's snapshot quota is 0
            NUnit.Framework.Assert.AreEqual(0, stats.Length);
            // list before set dir as snapshottable
            try
            {
                stats = hdfs.ListStatus(snapshotsPath);
                NUnit.Framework.Assert.Fail("expect SnapshotException");
            }
            catch (IOException e)
            {
                GenericTestUtils.AssertExceptionContains("Directory is not a snapshottable directory: "
                                                         + dir.ToString(), e);
            }
            // list before creating snapshots
            hdfs.AllowSnapshot(dir);
            stats = hdfs.ListStatus(snapshotsPath);
            NUnit.Framework.Assert.AreEqual(0, stats.Length);
            // list while creating snapshots
            int snapshotNum = 5;

            for (int sNum = 0; sNum < snapshotNum; sNum++)
            {
                hdfs.CreateSnapshot(dir, "s_" + sNum);
                stats = hdfs.ListStatus(snapshotsPath);
                NUnit.Framework.Assert.AreEqual(sNum + 1, stats.Length);
                for (int i = 0; i <= sNum; i++)
                {
                    NUnit.Framework.Assert.AreEqual("s_" + i, stats[i].GetPath().GetName());
                }
            }
            // list while deleting snapshots
            for (int sNum_1 = snapshotNum - 1; sNum_1 > 0; sNum_1--)
            {
                hdfs.DeleteSnapshot(dir, "s_" + sNum_1);
                stats = hdfs.ListStatus(snapshotsPath);
                NUnit.Framework.Assert.AreEqual(sNum_1, stats.Length);
                for (int i = 0; i < sNum_1; i++)
                {
                    NUnit.Framework.Assert.AreEqual("s_" + i, stats[i].GetPath().GetName());
                }
            }
            // remove the last snapshot
            hdfs.DeleteSnapshot(dir, "s_0");
            stats = hdfs.ListStatus(snapshotsPath);
            NUnit.Framework.Assert.AreEqual(0, stats.Length);
        }
        public virtual void TestDiffReportWithRenameAndSnapshotDeletion()
        {
            Path root = new Path("/");
            Path foo  = new Path(root, "foo");
            Path bar  = new Path(foo, "bar");

            DFSTestUtil.CreateFile(hdfs, bar, Blocksize, Replication, seed);
            SnapshotTestHelper.CreateSnapshot(hdfs, root, "s0");
            // rename /foo to /foo2
            Path foo2 = new Path(root, "foo2");

            hdfs.Rename(foo, foo2);
            // now /foo/bar becomes /foo2/bar
            Path bar2 = new Path(foo2, "bar");

            // delete snapshot s0 so that the withNameList inside of the WithCount node
            // of foo becomes empty
            hdfs.DeleteSnapshot(root, "s0");
            // create snapshot s1 and rename bar again
            SnapshotTestHelper.CreateSnapshot(hdfs, root, "s1");
            Path bar3 = new Path(foo2, "bar-new");

            hdfs.Rename(bar2, bar3);
            // we always put modification on the file before rename
            VerifyDiffReport(root, "s1", string.Empty, new SnapshotDiffReport.DiffReportEntry
                                 (SnapshotDiffReport.DiffType.Modify, DFSUtil.String2Bytes(string.Empty)), new SnapshotDiffReport.DiffReportEntry
                                 (SnapshotDiffReport.DiffType.Modify, DFSUtil.String2Bytes("foo2")), new SnapshotDiffReport.DiffReportEntry
                                 (SnapshotDiffReport.DiffType.Rename, DFSUtil.String2Bytes("foo2/bar"), DFSUtil.String2Bytes
                                     ("foo2/bar-new")));
        }
        /// <exception cref="System.Exception"/>
        public virtual void TestQuotaByStorageTypeWithSnapshot()
        {
            Path sub1 = new Path(dir, "Sub1");

            dfs.Mkdirs(sub1);
            // Setup ONE_SSD policy and SSD quota of 4 * BLOCKSIZE on sub1
            dfs.SetStoragePolicy(sub1, HdfsConstants.OnessdStoragePolicyName);
            dfs.SetQuotaByStorageType(sub1, StorageType.Ssd, 4 * Blocksize);
            INode sub1Node = fsdir.GetINode4Write(sub1.ToString());

            NUnit.Framework.Assert.IsTrue(sub1Node.IsDirectory());
            NUnit.Framework.Assert.IsTrue(sub1Node.IsQuotaSet());
            // Create file1 of size 2 * BLOCKSIZE under sub1
            Path file1    = new Path(sub1, "file1");
            long file1Len = 2 * Blocksize;

            DFSTestUtil.CreateFile(dfs, file1, file1Len, Replication, seed);
            // Create snapshot on sub1 named s1
            SnapshotTestHelper.CreateSnapshot(dfs, sub1, "s1");
            // Verify sub1 SSD usage is unchanged after creating snapshot s1
            long ssdConsumed = sub1Node.AsDirectory().GetDirectoryWithQuotaFeature().GetSpaceConsumed
                                   ().GetTypeSpaces().Get(StorageType.Ssd);

            NUnit.Framework.Assert.AreEqual(file1Len, ssdConsumed);
            // Delete file1
            dfs.Delete(file1, false);
            // Verify sub1 SSD usage is unchanged due to the existence of snapshot s1
            ssdConsumed = sub1Node.AsDirectory().GetDirectoryWithQuotaFeature().GetSpaceConsumed
                              ().GetTypeSpaces().Get(StorageType.Ssd);
            NUnit.Framework.Assert.AreEqual(file1Len, ssdConsumed);
            QuotaCounts counts1 = new QuotaCounts.Builder().Build();

            sub1Node.ComputeQuotaUsage(fsn.GetBlockManager().GetStoragePolicySuite(), counts1
                                       , true);
            NUnit.Framework.Assert.AreEqual(sub1Node.DumpTreeRecursively().ToString(), file1Len
                                            , counts1.GetTypeSpaces().Get(StorageType.Ssd));
            ContentSummary cs1 = dfs.GetContentSummary(sub1);

            NUnit.Framework.Assert.AreEqual(cs1.GetSpaceConsumed(), file1Len * Replication);
            NUnit.Framework.Assert.AreEqual(cs1.GetTypeConsumed(StorageType.Ssd), file1Len);
            NUnit.Framework.Assert.AreEqual(cs1.GetTypeConsumed(StorageType.Disk), file1Len *
                                            2);
            // Delete the snapshot s1
            dfs.DeleteSnapshot(sub1, "s1");
            // Verify sub1 SSD usage is fully reclaimed and changed to 0
            ssdConsumed = sub1Node.AsDirectory().GetDirectoryWithQuotaFeature().GetSpaceConsumed
                              ().GetTypeSpaces().Get(StorageType.Ssd);
            NUnit.Framework.Assert.AreEqual(0, ssdConsumed);
            QuotaCounts counts2 = new QuotaCounts.Builder().Build();

            sub1Node.ComputeQuotaUsage(fsn.GetBlockManager().GetStoragePolicySuite(), counts2
                                       , true);
            NUnit.Framework.Assert.AreEqual(sub1Node.DumpTreeRecursively().ToString(), 0, counts2
                                            .GetTypeSpaces().Get(StorageType.Ssd));
            ContentSummary cs2 = dfs.GetContentSummary(sub1);

            NUnit.Framework.Assert.AreEqual(cs2.GetSpaceConsumed(), 0);
            NUnit.Framework.Assert.AreEqual(cs2.GetTypeConsumed(StorageType.Ssd), 0);
            NUnit.Framework.Assert.AreEqual(cs2.GetTypeConsumed(StorageType.Disk), 0);
        }
        public virtual void TestSuccessiveSnapshotXAttrChanges()
        {
            // First snapshot
            FileSystem.Mkdirs(hdfs, path, FsPermission.CreateImmutable((short)0x1c0));
            hdfs.SetXAttr(path, name1, value1);
            SnapshotTestHelper.CreateSnapshot(hdfs, path, snapshotName);
            IDictionary <string, byte[]> xattrs = hdfs.GetXAttrs(snapshotPath);

            NUnit.Framework.Assert.AreEqual(1, xattrs.Count);
            Assert.AssertArrayEquals(value1, xattrs[name1]);
            // Second snapshot
            hdfs.SetXAttr(path, name1, newValue1);
            hdfs.SetXAttr(path, name2, value2);
            SnapshotTestHelper.CreateSnapshot(hdfs, path, snapshotName2);
            xattrs = hdfs.GetXAttrs(snapshotPath2);
            NUnit.Framework.Assert.AreEqual(2, xattrs.Count);
            Assert.AssertArrayEquals(newValue1, xattrs[name1]);
            Assert.AssertArrayEquals(value2, xattrs[name2]);
            // Third snapshot
            hdfs.SetXAttr(path, name1, value1);
            hdfs.RemoveXAttr(path, name2);
            SnapshotTestHelper.CreateSnapshot(hdfs, path, snapshotName3);
            xattrs = hdfs.GetXAttrs(snapshotPath3);
            NUnit.Framework.Assert.AreEqual(1, xattrs.Count);
            Assert.AssertArrayEquals(value1, xattrs[name1]);
            // Check that the first and second snapshots'
            // XAttrs have stayed constant
            xattrs = hdfs.GetXAttrs(snapshotPath);
            NUnit.Framework.Assert.AreEqual(1, xattrs.Count);
            Assert.AssertArrayEquals(value1, xattrs[name1]);
            xattrs = hdfs.GetXAttrs(snapshotPath2);
            NUnit.Framework.Assert.AreEqual(2, xattrs.Count);
            Assert.AssertArrayEquals(newValue1, xattrs[name1]);
            Assert.AssertArrayEquals(value2, xattrs[name2]);
            // Remove the second snapshot and verify the first and
            // third snapshots' XAttrs have stayed constant
            hdfs.DeleteSnapshot(path, snapshotName2);
            xattrs = hdfs.GetXAttrs(snapshotPath);
            NUnit.Framework.Assert.AreEqual(1, xattrs.Count);
            Assert.AssertArrayEquals(value1, xattrs[name1]);
            xattrs = hdfs.GetXAttrs(snapshotPath3);
            NUnit.Framework.Assert.AreEqual(1, xattrs.Count);
            Assert.AssertArrayEquals(value1, xattrs[name1]);
            hdfs.DeleteSnapshot(path, snapshotName);
            hdfs.DeleteSnapshot(path, snapshotName3);
        }
        public virtual void TestSnapshots()
        {
            cluster.GetNamesystem().GetSnapshotManager().SetAllowNestedSnapshots(true);
            MetricsAsserts.AssertGauge("Snapshots", 0, MetricsAsserts.GetMetrics(NsMetrics));
            MetricsAsserts.AssertCounter("CreateSnapshotOps", 0L, MetricsAsserts.GetMetrics(NnMetrics
                                                                                            ));
            // Create a snapshot for a non-snapshottable directory, thus should not
            // change the metrics
            try
            {
                hdfs.CreateSnapshot(sub1, "s1");
            }
            catch (Exception)
            {
            }
            MetricsAsserts.AssertGauge("Snapshots", 0, MetricsAsserts.GetMetrics(NsMetrics));
            MetricsAsserts.AssertCounter("CreateSnapshotOps", 1L, MetricsAsserts.GetMetrics(NnMetrics
                                                                                            ));
            // Create snapshot for sub1
            hdfs.AllowSnapshot(sub1);
            hdfs.CreateSnapshot(sub1, "s1");
            MetricsAsserts.AssertGauge("Snapshots", 1, MetricsAsserts.GetMetrics(NsMetrics));
            MetricsAsserts.AssertCounter("CreateSnapshotOps", 2L, MetricsAsserts.GetMetrics(NnMetrics
                                                                                            ));
            hdfs.CreateSnapshot(sub1, "s2");
            MetricsAsserts.AssertGauge("Snapshots", 2, MetricsAsserts.GetMetrics(NsMetrics));
            MetricsAsserts.AssertCounter("CreateSnapshotOps", 3L, MetricsAsserts.GetMetrics(NnMetrics
                                                                                            ));
            hdfs.GetSnapshotDiffReport(sub1, "s1", "s2");
            MetricsAsserts.AssertCounter("SnapshotDiffReportOps", 1L, MetricsAsserts.GetMetrics
                                             (NnMetrics));
            // Create snapshot for a directory under sub1
            Path subsub1 = new Path(sub1, "sub1sub1");
            Path subfile = new Path(subsub1, "file");

            DFSTestUtil.CreateFile(hdfs, subfile, 1024, Replication, seed);
            hdfs.AllowSnapshot(subsub1);
            hdfs.CreateSnapshot(subsub1, "s11");
            MetricsAsserts.AssertGauge("Snapshots", 3, MetricsAsserts.GetMetrics(NsMetrics));
            MetricsAsserts.AssertCounter("CreateSnapshotOps", 4L, MetricsAsserts.GetMetrics(NnMetrics
                                                                                            ));
            // delete snapshot
            hdfs.DeleteSnapshot(sub1, "s2");
            MetricsAsserts.AssertGauge("Snapshots", 2, MetricsAsserts.GetMetrics(NsMetrics));
            MetricsAsserts.AssertCounter("DeleteSnapshotOps", 1L, MetricsAsserts.GetMetrics(NnMetrics
                                                                                            ));
            // rename snapshot
            hdfs.RenameSnapshot(sub1, "s1", "NewS1");
            MetricsAsserts.AssertGauge("Snapshots", 2, MetricsAsserts.GetMetrics(NsMetrics));
            MetricsAsserts.AssertCounter("RenameSnapshotOps", 1L, MetricsAsserts.GetMetrics(NnMetrics
                                                                                            ));
        }
 public virtual void TearDown()
 {
     if (fs.Exists(new Path("/sub1")))
     {
         if (fs.Exists(new Path("/sub1/.snapshot")))
         {
             foreach (FileStatus st in fs.ListStatus(new Path("/sub1/.snapshot")))
             {
                 fs.DeleteSnapshot(new Path("/sub1"), st.GetPath().GetName());
             }
             fs.DisallowSnapshot(new Path("/sub1"));
         }
         fs.Delete(new Path("/sub1"), true);
     }
 }
        /// <exception cref="System.IO.IOException"/>
        private void DoTestMultipleSnapshots(bool saveNamespace)
        {
            Path path = new Path("/test");

            DoWriteAndAbort(fs, path);
            fs.CreateSnapshot(path, "s2");
            fs.Delete(new Path("/test/test"), true);
            fs.DeleteSnapshot(path, "s2");
            cluster.TriggerBlockReports();
            if (saveNamespace)
            {
                NameNode nameNode = cluster.GetNameNode();
                NameNodeAdapter.EnterSafeMode(nameNode, false);
                NameNodeAdapter.SaveNamespace(nameNode);
                NameNodeAdapter.LeaveSafeMode(nameNode);
            }
            cluster.RestartNameNode(true);
        }
Beispiel #8
0
        /// <summary>Testing a special case with snapshots.</summary>
        /// <remarks>
        /// Testing a special case with snapshots. When the following steps happen:
        /// <pre>
        /// 1. Take snapshot s1 on dir.
        /// 2. Create new dir and files under subsubDir, which is descendant of dir.
        /// 3. Take snapshot s2 on dir.
        /// 4. Delete subsubDir.
        /// 5. Delete snapshot s2.
        /// </pre>
        /// When we merge the diff from s2 to s1 (since we deleted s2), we need to make
        /// sure all the files/dirs created after s1 should be destroyed. Otherwise
        /// we may save these files/dirs to the fsimage, and cause FileNotFound
        /// Exception while loading fsimage.
        /// </remarks>
        /// <exception cref="System.Exception"/>
        public virtual void TestSaveLoadImageAfterSnapshotDeletion()
        {
            // create initial dir and subdir
            Path dir       = new Path("/dir");
            Path subDir    = new Path(dir, "subdir");
            Path subsubDir = new Path(subDir, "subsubdir");

            hdfs.Mkdirs(subsubDir);
            // take snapshots on subdir and dir
            SnapshotTestHelper.CreateSnapshot(hdfs, dir, "s1");
            // create new dir under initial dir
            Path newDir  = new Path(subsubDir, "newdir");
            Path newFile = new Path(newDir, "newfile");

            hdfs.Mkdirs(newDir);
            DFSTestUtil.CreateFile(hdfs, newFile, Blocksize, Replication, seed);
            // create another snapshot
            SnapshotTestHelper.CreateSnapshot(hdfs, dir, "s2");
            // delete subsubdir
            hdfs.Delete(subsubDir, true);
            // delete snapshot s2
            hdfs.DeleteSnapshot(dir, "s2");
            // restart cluster
            cluster.Shutdown();
            cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(Replication).Format(false
                                                                                        ).Build();
            cluster.WaitActive();
            fsn  = cluster.GetNamesystem();
            hdfs = cluster.GetFileSystem();
            // save namespace to fsimage
            hdfs.SetSafeMode(HdfsConstants.SafeModeAction.SafemodeEnter);
            hdfs.SaveNamespace();
            hdfs.SetSafeMode(HdfsConstants.SafeModeAction.SafemodeLeave);
            cluster.Shutdown();
            cluster = new MiniDFSCluster.Builder(conf).Format(false).NumDataNodes(Replication
                                                                                  ).Build();
            cluster.WaitActive();
            fsn  = cluster.GetNamesystem();
            hdfs = cluster.GetFileSystem();
        }
        /// <summary>for snapshot file.</summary>
        /// <exception cref="System.Exception"/>
        public virtual void TestSnapshotPathINodes()
        {
            // Create a snapshot for the dir, and check the inodes for the path
            // pointing to a snapshot file
            hdfs.AllowSnapshot(sub1);
            hdfs.CreateSnapshot(sub1, "s1");
            // The path when accessing the snapshot file of file1 is
            // /TestSnapshot/sub1/.snapshot/s1/file1
            string snapshotPath = sub1.ToString() + "/.snapshot/s1/file1";

            string[]     names       = INode.GetPathNames(snapshotPath);
            byte[][]     components  = INode.GetPathComponents(names);
            INodesInPath nodesInPath = INodesInPath.Resolve(fsdir.rootDir, components, false);

            // Length of inodes should be (components.length - 1), since we will ignore
            // ".snapshot"
            NUnit.Framework.Assert.AreEqual(nodesInPath.Length(), components.Length - 1);
            // SnapshotRootIndex should be 3: {root, Testsnapshot, sub1, s1, file1}
            Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot snapshot = GetSnapshot(nodesInPath
                                                                                            , "s1", 3);
            AssertSnapshot(nodesInPath, true, snapshot, 3);
            // Check the INode for file1 (snapshot file)
            INode snapshotFileNode = nodesInPath.GetLastINode();

            AssertINodeFile(snapshotFileNode, file1);
            NUnit.Framework.Assert.IsTrue(snapshotFileNode.GetParent().IsWithSnapshot());
            // Call getExistingPathINodes and request only one INode.
            nodesInPath = INodesInPath.Resolve(fsdir.rootDir, components, false);
            NUnit.Framework.Assert.AreEqual(nodesInPath.Length(), components.Length - 1);
            AssertSnapshot(nodesInPath, true, snapshot, 3);
            // Check the INode for file1 (snapshot file)
            AssertINodeFile(nodesInPath.GetLastINode(), file1);
            // Resolve the path "/TestSnapshot/sub1/.snapshot"
            string dotSnapshotPath = sub1.ToString() + "/.snapshot";

            names       = INode.GetPathNames(dotSnapshotPath);
            components  = INode.GetPathComponents(names);
            nodesInPath = INodesInPath.Resolve(fsdir.rootDir, components, false);
            // The number of INodes returned should still be components.length
            // since we put a null in the inode array for ".snapshot"
            NUnit.Framework.Assert.AreEqual(nodesInPath.Length(), components.Length);
            // No SnapshotRoot dir is included in the resolved inodes
            AssertSnapshot(nodesInPath, true, snapshot, -1);
            // The last INode should be null, the last but 1 should be sub1
            NUnit.Framework.Assert.IsNull(nodesInPath.GetLastINode());
            NUnit.Framework.Assert.AreEqual(nodesInPath.GetINode(-2).GetFullPathName(), sub1.
                                            ToString());
            NUnit.Framework.Assert.IsTrue(nodesInPath.GetINode(-2).IsDirectory());
            string[] invalidPathComponent = new string[] { "invalidDir", "foo", ".snapshot",
                                                           "bar" };
            Path invalidPath = new Path(invalidPathComponent[0]);

            for (int i = 1; i < invalidPathComponent.Length; i++)
            {
                invalidPath = new Path(invalidPath, invalidPathComponent[i]);
                try
                {
                    hdfs.GetFileStatus(invalidPath);
                    NUnit.Framework.Assert.Fail();
                }
                catch (FileNotFoundException fnfe)
                {
                    System.Console.Out.WriteLine("The exception is expected: " + fnfe);
                }
            }
            hdfs.DeleteSnapshot(sub1, "s1");
            hdfs.DisallowSnapshot(sub1);
        }
Beispiel #10
0
        /// <summary>Test deleting a file with snapshots.</summary>
        /// <remarks>
        /// Test deleting a file with snapshots. Need to check the blocksMap to make
        /// sure the corresponding record is updated correctly.
        /// </remarks>
        /// <exception cref="System.Exception"/>
        public virtual void TestDeletionWithSnapshots()
        {
            Path file0 = new Path(sub1, "file0");
            Path file1 = new Path(sub1, "file1");
            Path sub2  = new Path(sub1, "sub2");
            Path file2 = new Path(sub2, "file2");
            Path file3 = new Path(sub1, "file3");
            Path file4 = new Path(sub1, "file4");
            Path file5 = new Path(sub1, "file5");

            // Create file under sub1
            DFSTestUtil.CreateFile(hdfs, file0, 4 * Blocksize, Replication, seed);
            DFSTestUtil.CreateFile(hdfs, file1, 2 * Blocksize, Replication, seed);
            DFSTestUtil.CreateFile(hdfs, file2, 3 * Blocksize, Replication, seed);
            {
                // Normal deletion
                INodeFile             f2     = AssertBlockCollection(file2.ToString(), 3, fsdir, blockmanager);
                BlockInfoContiguous[] blocks = f2.GetBlocks();
                hdfs.Delete(sub2, true);
                // The INode should have been removed from the blocksMap
                foreach (BlockInfoContiguous b in blocks)
                {
                    NUnit.Framework.Assert.IsNull(blockmanager.GetBlockCollection(b));
                }
            }
            // Create snapshots for sub1
            string[] snapshots = new string[] { "s0", "s1", "s2" };
            DFSTestUtil.CreateFile(hdfs, file3, 5 * Blocksize, Replication, seed);
            SnapshotTestHelper.CreateSnapshot(hdfs, sub1, snapshots[0]);
            DFSTestUtil.CreateFile(hdfs, file4, 1 * Blocksize, Replication, seed);
            SnapshotTestHelper.CreateSnapshot(hdfs, sub1, snapshots[1]);
            DFSTestUtil.CreateFile(hdfs, file5, 7 * Blocksize, Replication, seed);
            SnapshotTestHelper.CreateSnapshot(hdfs, sub1, snapshots[2]);
            {
                // set replication so that the inode should be replaced for snapshots
                INodeFile f1 = AssertBlockCollection(file1.ToString(), 2, fsdir, blockmanager);
                NUnit.Framework.Assert.AreSame(typeof(INodeFile), f1.GetType());
                hdfs.SetReplication(file1, (short)2);
                f1 = AssertBlockCollection(file1.ToString(), 2, fsdir, blockmanager);
                NUnit.Framework.Assert.IsTrue(f1.IsWithSnapshot());
                NUnit.Framework.Assert.IsFalse(f1.IsUnderConstruction());
            }
            // Check the block information for file0
            INodeFile f0 = AssertBlockCollection(file0.ToString(), 4, fsdir, blockmanager);

            BlockInfoContiguous[] blocks0 = f0.GetBlocks();
            // Also check the block information for snapshot of file0
            Path snapshotFile0 = SnapshotTestHelper.GetSnapshotPath(sub1, "s0", file0.GetName
                                                                        ());

            AssertBlockCollection(snapshotFile0.ToString(), 4, fsdir, blockmanager);
            // Delete file0
            hdfs.Delete(file0, true);
            // Make sure the blocks of file0 is still in blocksMap
            foreach (BlockInfoContiguous b_1 in blocks0)
            {
                NUnit.Framework.Assert.IsNotNull(blockmanager.GetBlockCollection(b_1));
            }
            AssertBlockCollection(snapshotFile0.ToString(), 4, fsdir, blockmanager);
            // Compare the INode in the blocksMap with INodes for snapshots
            string s1f0 = SnapshotTestHelper.GetSnapshotPath(sub1, "s1", file0.GetName()).ToString
                              ();

            AssertBlockCollection(s1f0, 4, fsdir, blockmanager);
            // Delete snapshot s1
            hdfs.DeleteSnapshot(sub1, "s1");
            // Make sure the first block of file0 is still in blocksMap
            foreach (BlockInfoContiguous b_2 in blocks0)
            {
                NUnit.Framework.Assert.IsNotNull(blockmanager.GetBlockCollection(b_2));
            }
            AssertBlockCollection(snapshotFile0.ToString(), 4, fsdir, blockmanager);
            try
            {
                INodeFile.ValueOf(fsdir.GetINode(s1f0), s1f0);
                NUnit.Framework.Assert.Fail("Expect FileNotFoundException when identifying the INode in a deleted Snapshot"
                                            );
            }
            catch (IOException e)
            {
                GenericTestUtils.AssertExceptionContains("File does not exist: " + s1f0, e);
            }
        }
        /// <summary>
        /// Create a snapshot for /test/foo and create another snapshot for
        /// /test/foo/bar.
        /// </summary>
        /// <remarks>
        /// Create a snapshot for /test/foo and create another snapshot for
        /// /test/foo/bar.  Files created before the snapshots should appear in both
        /// snapshots and the files created after the snapshots should not appear in
        /// any of the snapshots.
        /// </remarks>
        /// <exception cref="System.Exception"/>
        public virtual void TestNestedSnapshots()
        {
            cluster.GetNamesystem().GetSnapshotManager().SetAllowNestedSnapshots(true);
            Path foo   = new Path("/testNestedSnapshots/foo");
            Path bar   = new Path(foo, "bar");
            Path file1 = new Path(bar, "file1");

            DFSTestUtil.CreateFile(hdfs, file1, Blocksize, Replication, Seed);
            Print("create file " + file1);
            string s1name = "foo-s1";
            Path   s1path = SnapshotTestHelper.GetSnapshotRoot(foo, s1name);

            hdfs.AllowSnapshot(foo);
            Print("allow snapshot " + foo);
            hdfs.CreateSnapshot(foo, s1name);
            Print("create snapshot " + s1name);
            string s2name = "bar-s2";
            Path   s2path = SnapshotTestHelper.GetSnapshotRoot(bar, s2name);

            hdfs.AllowSnapshot(bar);
            Print("allow snapshot " + bar);
            hdfs.CreateSnapshot(bar, s2name);
            Print("create snapshot " + s2name);
            Path file2 = new Path(bar, "file2");

            DFSTestUtil.CreateFile(hdfs, file2, Blocksize, Replication, Seed);
            Print("create file " + file2);
            AssertFile(s1path, s2path, file1, true, true, true);
            AssertFile(s1path, s2path, file2, true, false, false);
            //test root
            string rootStr  = "/";
            Path   rootPath = new Path(rootStr);

            hdfs.AllowSnapshot(rootPath);
            Print("allow snapshot " + rootStr);
            Path rootSnapshot = hdfs.CreateSnapshot(rootPath);

            Print("create snapshot " + rootSnapshot);
            hdfs.DeleteSnapshot(rootPath, rootSnapshot.GetName());
            Print("delete snapshot " + rootSnapshot);
            hdfs.DisallowSnapshot(rootPath);
            Print("disallow snapshot " + rootStr);
            //change foo to non-snapshottable
            hdfs.DeleteSnapshot(foo, s1name);
            hdfs.DisallowSnapshot(foo);
            //test disallow nested snapshots
            cluster.GetNamesystem().GetSnapshotManager().SetAllowNestedSnapshots(false);
            try
            {
                hdfs.AllowSnapshot(rootPath);
                NUnit.Framework.Assert.Fail();
            }
            catch (SnapshotException se)
            {
                AssertNestedSnapshotException(se, "subdirectory");
            }
            try
            {
                hdfs.AllowSnapshot(foo);
                NUnit.Framework.Assert.Fail();
            }
            catch (SnapshotException se)
            {
                AssertNestedSnapshotException(se, "subdirectory");
            }
            Path sub1Bar = new Path(bar, "sub1");
            Path sub2Bar = new Path(sub1Bar, "sub2");

            hdfs.Mkdirs(sub2Bar);
            try
            {
                hdfs.AllowSnapshot(sub1Bar);
                NUnit.Framework.Assert.Fail();
            }
            catch (SnapshotException se)
            {
                AssertNestedSnapshotException(se, "ancestor");
            }
            try
            {
                hdfs.AllowSnapshot(sub2Bar);
                NUnit.Framework.Assert.Fail();
            }
            catch (SnapshotException se)
            {
                AssertNestedSnapshotException(se, "ancestor");
            }
        }