/// <summary>Initialize the versions array.</summary>
        /// <remarks>
        /// Initialize the versions array.  This array stores all combinations
        /// of cross product:
        /// {oldLayoutVersion,currentLayoutVersion,futureLayoutVersion} X
        /// {currentNamespaceId,incorrectNamespaceId} X
        /// {pastFsscTime,currentFsscTime,futureFsscTime}
        /// </remarks>
        /// <exception cref="System.Exception"/>
        private TestDFSStartupVersions.StorageData[] InitializeVersions()
        {
            int    layoutVersionOld = Storage.LastUpgradableLayoutVersion;
            int    layoutVersionCur = HdfsConstants.DatanodeLayoutVersion;
            int    layoutVersionNew = int.MinValue;
            int    namespaceIdCur   = UpgradeUtilities.GetCurrentNamespaceID(null);
            int    namespaceIdOld   = int.MinValue;
            long   fsscTimeOld      = long.MinValue;
            long   fsscTimeCur      = UpgradeUtilities.GetCurrentFsscTime(null);
            long   fsscTimeNew      = long.MaxValue;
            string clusterID        = "testClusterID";
            string invalidClusterID = "testClusterID";
            string bpid             = UpgradeUtilities.GetCurrentBlockPoolID(null);
            string invalidBpid      = "invalidBpid";

            return(new TestDFSStartupVersions.StorageData[] { new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionOld, namespaceIdCur, clusterID, fsscTimeOld, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionOld, namespaceIdCur, clusterID, fsscTimeCur, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionOld, namespaceIdCur, clusterID, fsscTimeNew, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionOld, namespaceIdOld, clusterID, fsscTimeOld, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionOld, namespaceIdOld, clusterID, fsscTimeCur, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionOld, namespaceIdOld, clusterID, fsscTimeNew, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionCur, namespaceIdCur, clusterID, fsscTimeOld, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionCur, namespaceIdCur, clusterID, fsscTimeCur, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionCur, namespaceIdCur, clusterID, fsscTimeNew, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionCur, namespaceIdOld, clusterID, fsscTimeOld, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionCur, namespaceIdOld, clusterID, fsscTimeCur, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionCur, namespaceIdOld, clusterID, fsscTimeNew, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionNew, namespaceIdCur, clusterID, fsscTimeOld, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionNew, namespaceIdCur, clusterID, fsscTimeCur, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionNew, namespaceIdCur, clusterID, fsscTimeNew, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionNew, namespaceIdOld, clusterID, fsscTimeOld, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionNew, namespaceIdOld, clusterID, fsscTimeCur, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionNew, namespaceIdOld, clusterID, fsscTimeNew, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionCur, namespaceIdCur, invalidClusterID, fsscTimeCur, bpid), new TestDFSStartupVersions.StorageData
                                                                  (layoutVersionCur, namespaceIdCur, clusterID, fsscTimeCur, invalidBpid) });
        }
        public virtual void TestRollback()
        {
            FilePath[] baseDirs;
            UpgradeUtilities.Initialize();
            StorageInfo storageInfo = null;

            for (int numDirs = 1; numDirs <= 2; numDirs++)
            {
                conf = new HdfsConfiguration();
                conf.SetInt(DFSConfigKeys.DfsDatanodeScanPeriodHoursKey, -1);
                conf = UpgradeUtilities.InitializeStorageStateConf(numDirs, conf);
                string[] nameNodeDirs = conf.GetStrings(DFSConfigKeys.DfsNamenodeNameDirKey);
                string[] dataNodeDirs = conf.GetStrings(DFSConfigKeys.DfsDatanodeDataDirKey);
                Log("Normal NameNode rollback", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "previous");
                NameNode.DoRollback(conf, false);
                CheckResult(HdfsServerConstants.NodeType.NameNode, nameNodeDirs);
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                Log("Normal DataNode rollback", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "previous");
                NameNode.DoRollback(conf, false);
                cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(0).Format(false).ManageDataDfsDirs
                              (false).ManageNameDfsDirs(false).DnStartupOption(HdfsServerConstants.StartupOption
                                                                               .Rollback).Build();
                UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "current");
                UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "previous");
                cluster.StartDataNodes(conf, 1, false, HdfsServerConstants.StartupOption.Rollback
                                       , null);
                CheckResult(HdfsServerConstants.NodeType.DataNode, dataNodeDirs);
                cluster.Shutdown();
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                UpgradeUtilities.CreateEmptyDirs(dataNodeDirs);
                Log("Normal BlockPool rollback", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "previous");
                NameNode.DoRollback(conf, false);
                cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(0).Format(false).ManageDataDfsDirs
                              (false).ManageNameDfsDirs(false).DnStartupOption(HdfsServerConstants.StartupOption
                                                                               .Rollback).Build();
                UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "current");
                UpgradeUtilities.CreateBlockPoolStorageDirs(dataNodeDirs, "current", UpgradeUtilities
                                                            .GetCurrentBlockPoolID(cluster));
                // Create a previous snapshot for the blockpool
                UpgradeUtilities.CreateBlockPoolStorageDirs(dataNodeDirs, "previous", UpgradeUtilities
                                                            .GetCurrentBlockPoolID(cluster));
                // Put newer layout version in current.
                storageInfo = new StorageInfo(HdfsConstants.DatanodeLayoutVersion - 1, UpgradeUtilities
                                              .GetCurrentNamespaceID(cluster), UpgradeUtilities.GetCurrentClusterID(cluster),
                                              UpgradeUtilities.GetCurrentFsscTime(cluster), HdfsServerConstants.NodeType.DataNode
                                              );
                // Overwrite VERSION file in the current directory of
                // volume directories and block pool slice directories
                // with a layout version from future.
                FilePath[] dataCurrentDirs = new FilePath[dataNodeDirs.Length];
                for (int i = 0; i < dataNodeDirs.Length; i++)
                {
                    dataCurrentDirs[i] = new FilePath((new Path(dataNodeDirs[i] + "/current")).ToString
                                                          ());
                }
                UpgradeUtilities.CreateDataNodeVersionFile(dataCurrentDirs, storageInfo, UpgradeUtilities
                                                           .GetCurrentBlockPoolID(cluster));
                cluster.StartDataNodes(conf, 1, false, HdfsServerConstants.StartupOption.Rollback
                                       , null);
                NUnit.Framework.Assert.IsTrue(cluster.IsDataNodeUp());
                cluster.Shutdown();
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                UpgradeUtilities.CreateEmptyDirs(dataNodeDirs);
                Log("NameNode rollback without existing previous dir", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                StartNameNodeShouldFail("None of the storage directories contain previous fs state"
                                        );
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                Log("DataNode rollback without existing previous dir", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(0).Format(false).ManageDataDfsDirs
                              (false).ManageNameDfsDirs(false).StartupOption(HdfsServerConstants.StartupOption
                                                                             .Upgrade).Build();
                UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "current");
                cluster.StartDataNodes(conf, 1, false, HdfsServerConstants.StartupOption.Rollback
                                       , null);
                cluster.Shutdown();
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                UpgradeUtilities.CreateEmptyDirs(dataNodeDirs);
                Log("DataNode rollback with future stored layout version in previous", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "previous");
                NameNode.DoRollback(conf, false);
                cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(0).Format(false).ManageDataDfsDirs
                              (false).ManageNameDfsDirs(false).DnStartupOption(HdfsServerConstants.StartupOption
                                                                               .Rollback).Build();
                UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "current");
                baseDirs    = UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "previous");
                storageInfo = new StorageInfo(int.MinValue, UpgradeUtilities.GetCurrentNamespaceID
                                                  (cluster), UpgradeUtilities.GetCurrentClusterID(cluster), UpgradeUtilities.GetCurrentFsscTime
                                                  (cluster), HdfsServerConstants.NodeType.DataNode);
                UpgradeUtilities.CreateDataNodeVersionFile(baseDirs, storageInfo, UpgradeUtilities
                                                           .GetCurrentBlockPoolID(cluster));
                StartBlockPoolShouldFail(HdfsServerConstants.StartupOption.Rollback, cluster.GetNamesystem
                                             ().GetBlockPoolId());
                cluster.Shutdown();
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                UpgradeUtilities.CreateEmptyDirs(dataNodeDirs);
                Log("DataNode rollback with newer fsscTime in previous", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "previous");
                NameNode.DoRollback(conf, false);
                cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(0).Format(false).ManageDataDfsDirs
                              (false).ManageNameDfsDirs(false).DnStartupOption(HdfsServerConstants.StartupOption
                                                                               .Rollback).Build();
                UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "current");
                baseDirs    = UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "previous");
                storageInfo = new StorageInfo(HdfsConstants.DatanodeLayoutVersion, UpgradeUtilities
                                              .GetCurrentNamespaceID(cluster), UpgradeUtilities.GetCurrentClusterID(cluster),
                                              long.MaxValue, HdfsServerConstants.NodeType.DataNode);
                UpgradeUtilities.CreateDataNodeVersionFile(baseDirs, storageInfo, UpgradeUtilities
                                                           .GetCurrentBlockPoolID(cluster));
                StartBlockPoolShouldFail(HdfsServerConstants.StartupOption.Rollback, cluster.GetNamesystem
                                             ().GetBlockPoolId());
                cluster.Shutdown();
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                UpgradeUtilities.CreateEmptyDirs(dataNodeDirs);
                Log("NameNode rollback with no edits file", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                baseDirs = UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "previous");
                DeleteMatchingFiles(baseDirs, "edits.*");
                StartNameNodeShouldFail("Gap in transactions");
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                Log("NameNode rollback with no image file", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                baseDirs = UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "previous");
                DeleteMatchingFiles(baseDirs, "fsimage_.*");
                StartNameNodeShouldFail("No valid image files found");
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                Log("NameNode rollback with corrupt version file", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                baseDirs = UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "previous");
                foreach (FilePath f in baseDirs)
                {
                    UpgradeUtilities.CorruptFile(new FilePath(f, "VERSION"), Sharpen.Runtime.GetBytesForString
                                                     ("layoutVersion", Charsets.Utf8), Sharpen.Runtime.GetBytesForString("xxxxxxxxxxxxx"
                                                                                                                         , Charsets.Utf8));
                }
                StartNameNodeShouldFail("file VERSION has layoutVersion missing");
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                Log("NameNode rollback with old layout version in previous", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                baseDirs    = UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "previous");
                storageInfo = new StorageInfo(1, UpgradeUtilities.GetCurrentNamespaceID(null), UpgradeUtilities
                                              .GetCurrentClusterID(null), UpgradeUtilities.GetCurrentFsscTime(null), HdfsServerConstants.NodeType
                                              .NameNode);
                UpgradeUtilities.CreateNameNodeVersionFile(conf, baseDirs, storageInfo, UpgradeUtilities
                                                           .GetCurrentBlockPoolID(cluster));
                StartNameNodeShouldFail("Cannot rollback to storage version 1 using this version"
                                        );
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
            }
        }
Exemple #3
0
        /// <summary>
        /// This test attempts to upgrade the NameNode and DataNode under
        /// a number of valid and invalid conditions.
        /// </summary>
        /// <exception cref="System.Exception"/>
        public virtual void TestUpgrade()
        {
            FilePath[]  baseDirs;
            StorageInfo storageInfo = null;

            for (int numDirs = 1; numDirs <= 2; numDirs++)
            {
                conf = new HdfsConfiguration();
                conf = UpgradeUtilities.InitializeStorageStateConf(numDirs, conf);
                string[] nameNodeDirs = conf.GetStrings(DFSConfigKeys.DfsNamenodeNameDirKey);
                string[] dataNodeDirs = conf.GetStrings(DFSConfigKeys.DfsDatanodeDataDirKey);
                conf.SetBoolean(DFSConfigKeys.DfsDatanodeDuplicateReplicaDeletion, false);
                Log("Normal NameNode upgrade", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                cluster = CreateCluster();
                // make sure that rolling upgrade cannot be started
                try
                {
                    DistributedFileSystem dfs = cluster.GetFileSystem();
                    dfs.SetSafeMode(HdfsConstants.SafeModeAction.SafemodeEnter);
                    dfs.RollingUpgrade(HdfsConstants.RollingUpgradeAction.Prepare);
                    NUnit.Framework.Assert.Fail();
                }
                catch (RemoteException re)
                {
                    NUnit.Framework.Assert.AreEqual(typeof(InconsistentFSStateException).FullName, re
                                                    .GetClassName());
                    Log.Info("The exception is expected.", re);
                }
                CheckNameNode(nameNodeDirs, ExpectedTxid);
                if (numDirs > 1)
                {
                    TestParallelImageWrite.CheckImages(cluster.GetNamesystem(), numDirs);
                }
                cluster.Shutdown();
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                Log("Normal DataNode upgrade", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                cluster = CreateCluster();
                UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "current");
                cluster.StartDataNodes(conf, 1, false, HdfsServerConstants.StartupOption.Regular,
                                       null);
                CheckDataNode(dataNodeDirs, UpgradeUtilities.GetCurrentBlockPoolID(null));
                cluster.Shutdown();
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                UpgradeUtilities.CreateEmptyDirs(dataNodeDirs);
                Log("NameNode upgrade with existing previous dir", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "previous");
                StartNameNodeShouldFail(HdfsServerConstants.StartupOption.Upgrade);
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                Log("DataNode upgrade with existing previous dir", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                cluster = CreateCluster();
                UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "current");
                UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "previous");
                cluster.StartDataNodes(conf, 1, false, HdfsServerConstants.StartupOption.Regular,
                                       null);
                CheckDataNode(dataNodeDirs, UpgradeUtilities.GetCurrentBlockPoolID(null));
                cluster.Shutdown();
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                UpgradeUtilities.CreateEmptyDirs(dataNodeDirs);
                Log("DataNode upgrade with future stored layout version in current", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                cluster     = CreateCluster();
                baseDirs    = UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "current");
                storageInfo = new StorageInfo(int.MinValue, UpgradeUtilities.GetCurrentNamespaceID
                                                  (cluster), UpgradeUtilities.GetCurrentClusterID(cluster), UpgradeUtilities.GetCurrentFsscTime
                                                  (cluster), HdfsServerConstants.NodeType.DataNode);
                UpgradeUtilities.CreateDataNodeVersionFile(baseDirs, storageInfo, UpgradeUtilities
                                                           .GetCurrentBlockPoolID(cluster));
                StartBlockPoolShouldFail(HdfsServerConstants.StartupOption.Regular, UpgradeUtilities
                                         .GetCurrentBlockPoolID(null));
                cluster.Shutdown();
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                UpgradeUtilities.CreateEmptyDirs(dataNodeDirs);
                Log("DataNode upgrade with newer fsscTime in current", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                cluster     = CreateCluster();
                baseDirs    = UpgradeUtilities.CreateDataNodeStorageDirs(dataNodeDirs, "current");
                storageInfo = new StorageInfo(HdfsConstants.DatanodeLayoutVersion, UpgradeUtilities
                                              .GetCurrentNamespaceID(cluster), UpgradeUtilities.GetCurrentClusterID(cluster),
                                              long.MaxValue, HdfsServerConstants.NodeType.DataNode);
                UpgradeUtilities.CreateDataNodeVersionFile(baseDirs, storageInfo, UpgradeUtilities
                                                           .GetCurrentBlockPoolID(cluster));
                // Ensure corresponding block pool failed to initialized
                StartBlockPoolShouldFail(HdfsServerConstants.StartupOption.Regular, UpgradeUtilities
                                         .GetCurrentBlockPoolID(null));
                cluster.Shutdown();
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                UpgradeUtilities.CreateEmptyDirs(dataNodeDirs);
                Log("NameNode upgrade with no edits file", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                DeleteStorageFilesWithPrefix(nameNodeDirs, "edits_");
                StartNameNodeShouldFail(HdfsServerConstants.StartupOption.Upgrade);
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                Log("NameNode upgrade with no image file", numDirs);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                DeleteStorageFilesWithPrefix(nameNodeDirs, "fsimage_");
                StartNameNodeShouldFail(HdfsServerConstants.StartupOption.Upgrade);
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                Log("NameNode upgrade with corrupt version file", numDirs);
                baseDirs = UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                foreach (FilePath f in baseDirs)
                {
                    UpgradeUtilities.CorruptFile(new FilePath(f, "VERSION"), Sharpen.Runtime.GetBytesForString
                                                     ("layoutVersion", Charsets.Utf8), Sharpen.Runtime.GetBytesForString("xxxxxxxxxxxxx"
                                                                                                                         , Charsets.Utf8));
                }
                StartNameNodeShouldFail(HdfsServerConstants.StartupOption.Upgrade);
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                Log("NameNode upgrade with old layout version in current", numDirs);
                baseDirs    = UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                storageInfo = new StorageInfo(Storage.LastUpgradableLayoutVersion + 1, UpgradeUtilities
                                              .GetCurrentNamespaceID(null), UpgradeUtilities.GetCurrentClusterID(null), UpgradeUtilities
                                              .GetCurrentFsscTime(null), HdfsServerConstants.NodeType.NameNode);
                UpgradeUtilities.CreateNameNodeVersionFile(conf, baseDirs, storageInfo, UpgradeUtilities
                                                           .GetCurrentBlockPoolID(cluster));
                StartNameNodeShouldFail(HdfsServerConstants.StartupOption.Upgrade);
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
                Log("NameNode upgrade with future layout version in current", numDirs);
                baseDirs    = UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                storageInfo = new StorageInfo(int.MinValue, UpgradeUtilities.GetCurrentNamespaceID
                                                  (null), UpgradeUtilities.GetCurrentClusterID(null), UpgradeUtilities.GetCurrentFsscTime
                                                  (null), HdfsServerConstants.NodeType.NameNode);
                UpgradeUtilities.CreateNameNodeVersionFile(conf, baseDirs, storageInfo, UpgradeUtilities
                                                           .GetCurrentBlockPoolID(cluster));
                StartNameNodeShouldFail(HdfsServerConstants.StartupOption.Upgrade);
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
            }
            // end numDir loop
            // One more check: normal NN upgrade with 4 directories, concurrent write
            int numDirs_1 = 4;
            {
                conf = new HdfsConfiguration();
                conf.SetInt(DFSConfigKeys.DfsDatanodeScanPeriodHoursKey, -1);
                conf.SetBoolean(DFSConfigKeys.DfsDatanodeDuplicateReplicaDeletion, false);
                conf = UpgradeUtilities.InitializeStorageStateConf(numDirs_1, conf);
                string[] nameNodeDirs = conf.GetStrings(DFSConfigKeys.DfsNamenodeNameDirKey);
                Log("Normal NameNode upgrade", numDirs_1);
                UpgradeUtilities.CreateNameNodeStorageDirs(nameNodeDirs, "current");
                cluster = CreateCluster();
                // make sure that rolling upgrade cannot be started
                try
                {
                    DistributedFileSystem dfs = cluster.GetFileSystem();
                    dfs.SetSafeMode(HdfsConstants.SafeModeAction.SafemodeEnter);
                    dfs.RollingUpgrade(HdfsConstants.RollingUpgradeAction.Prepare);
                    NUnit.Framework.Assert.Fail();
                }
                catch (RemoteException re)
                {
                    NUnit.Framework.Assert.AreEqual(typeof(InconsistentFSStateException).FullName, re
                                                    .GetClassName());
                    Log.Info("The exception is expected.", re);
                }
                CheckNameNode(nameNodeDirs, ExpectedTxid);
                TestParallelImageWrite.CheckImages(cluster.GetNamesystem(), numDirs_1);
                cluster.Shutdown();
                UpgradeUtilities.CreateEmptyDirs(nameNodeDirs);
            }
        }
        /// <summary>
        /// This test ensures the appropriate response (successful or failure) from
        /// a Datanode when the system is started with differing version combinations.
        /// </summary>
        /// <remarks>
        /// This test ensures the appropriate response (successful or failure) from
        /// a Datanode when the system is started with differing version combinations.
        /// <pre>
        /// For each 3-tuple in the cross product
        /// ({oldLayoutVersion,currentLayoutVersion,futureLayoutVersion},
        /// {currentNamespaceId,incorrectNamespaceId},
        /// {pastFsscTime,currentFsscTime,futureFsscTime})
        /// 1. Startup Namenode with version file containing
        /// (currentLayoutVersion,currentNamespaceId,currentFsscTime)
        /// 2. Attempt to startup Datanode with version file containing
        /// this iterations version 3-tuple
        /// </pre>
        /// </remarks>
        /// <exception cref="System.Exception"/>
        public virtual void TestVersions()
        {
            UpgradeUtilities.Initialize();
            Configuration conf = UpgradeUtilities.InitializeStorageStateConf(1, new HdfsConfiguration
                                                                                 ());

            TestDFSStartupVersions.StorageData[] versions = InitializeVersions();
            UpgradeUtilities.CreateNameNodeStorageDirs(conf.GetStrings(DFSConfigKeys.DfsNamenodeNameDirKey
                                                                       ), "current");
            cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(0).Format(false).ManageDataDfsDirs
                          (false).ManageNameDfsDirs(false).StartupOption(HdfsServerConstants.StartupOption
                                                                         .Regular).Build();
            TestDFSStartupVersions.StorageData nameNodeVersion = new TestDFSStartupVersions.StorageData
                                                                     (HdfsConstants.NamenodeLayoutVersion, UpgradeUtilities.GetCurrentNamespaceID(cluster
                                                                                                                                                  ), UpgradeUtilities.GetCurrentClusterID(cluster), UpgradeUtilities.GetCurrentFsscTime
                                                                         (cluster), UpgradeUtilities.GetCurrentBlockPoolID(cluster));
            Log("NameNode version info", HdfsServerConstants.NodeType.NameNode, null, nameNodeVersion
                );
            string bpid = UpgradeUtilities.GetCurrentBlockPoolID(cluster);

            for (int i = 0; i < versions.Length; i++)
            {
                FilePath[] storage = UpgradeUtilities.CreateDataNodeStorageDirs(conf.GetStrings(DFSConfigKeys
                                                                                                .DfsDatanodeDataDirKey), "current");
                Log("DataNode version info", HdfsServerConstants.NodeType.DataNode, i, versions[i
                    ]);
                UpgradeUtilities.CreateDataNodeVersionFile(storage, versions[i].storageInfo, bpid
                                                           , versions[i].blockPoolId);
                try
                {
                    cluster.StartDataNodes(conf, 1, false, HdfsServerConstants.StartupOption.Regular,
                                           null);
                }
                catch (Exception)
                {
                }
                // Ignore.  The asserts below will check for problems.
                // ignore.printStackTrace();
                NUnit.Framework.Assert.IsTrue(cluster.GetNameNode() != null);
                NUnit.Framework.Assert.AreEqual(IsVersionCompatible(nameNodeVersion, versions[i])
                                                , cluster.IsDataNodeUp());
                cluster.ShutdownDataNodes();
            }
        }