TestDFSStartupVersions.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:10k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.hdfs;
  19. import java.io.File;
  20. import junit.framework.TestCase;
  21. import org.apache.commons.logging.Log;
  22. import org.apache.commons.logging.LogFactory;
  23. import org.apache.hadoop.conf.Configuration;
  24. import org.apache.hadoop.hdfs.protocol.FSConstants;
  25. import org.apache.hadoop.hdfs.server.common.HdfsConstants.NodeType;
  26. import org.apache.hadoop.hdfs.server.common.HdfsConstants.StartupOption;
  27. import static org.apache.hadoop.hdfs.server.common.HdfsConstants.NodeType.NAME_NODE;
  28. import static org.apache.hadoop.hdfs.server.common.HdfsConstants.NodeType.DATA_NODE;
  29. import org.apache.hadoop.hdfs.server.common.HdfsConstants;
  30. import org.apache.hadoop.hdfs.server.common.Storage;
  31. import org.apache.hadoop.hdfs.server.common.StorageInfo;
  32. import org.apache.hadoop.fs.Path;
  33. /**
  34.  * This test ensures the appropriate response (successful or failure) from 
  35.  * a Datanode when the system is started with differing version combinations. 
  36.  */
  37. public class TestDFSStartupVersions extends TestCase {
  38.   
  39.   private static final Log LOG = LogFactory.getLog(
  40.                                                    "org.apache.hadoop.hdfs.TestDFSStartupVersions");
  41.   private static Path TEST_ROOT_DIR = new Path(
  42.                                                System.getProperty("test.build.data","/tmp").toString().replace(' ', '+'));
  43.   private MiniDFSCluster cluster = null;
  44.   
  45.   /**
  46.    * Writes an INFO log message containing the parameters.
  47.    */
  48.   void log(String label, NodeType nodeType, Integer testCase, StorageInfo version) {
  49.     String testCaseLine = "";
  50.     if (testCase != null) {
  51.       testCaseLine = " testCase="+testCase;
  52.     }
  53.     LOG.info("============================================================");
  54.     LOG.info("***TEST*** " + label + ":"
  55.              + testCaseLine
  56.              + " nodeType="+nodeType
  57.              + " layoutVersion="+version.getLayoutVersion()
  58.              + " namespaceID="+version.getNamespaceID()
  59.              + " fsscTime="+version.getCTime());
  60.   }
  61.   
  62.   /**
  63.    * Initialize the versions array.  This array stores all combinations 
  64.    * of cross product:
  65.    *  {oldLayoutVersion,currentLayoutVersion,futureLayoutVersion} X
  66.    *    {currentNamespaceId,incorrectNamespaceId} X
  67.    *      {pastFsscTime,currentFsscTime,futureFsscTime}
  68.    */
  69.   private StorageInfo[] initializeVersions() throws Exception {
  70.     int layoutVersionOld = Storage.LAST_UPGRADABLE_LAYOUT_VERSION;
  71.     int layoutVersionCur = UpgradeUtilities.getCurrentLayoutVersion();
  72.     int layoutVersionNew = Integer.MIN_VALUE;
  73.     int namespaceIdCur = UpgradeUtilities.getCurrentNamespaceID(null);
  74.     int namespaceIdOld = Integer.MIN_VALUE;
  75.     long fsscTimeOld = Long.MIN_VALUE;
  76.     long fsscTimeCur = UpgradeUtilities.getCurrentFsscTime(null);
  77.     long fsscTimeNew = Long.MAX_VALUE;
  78.     
  79.     return new StorageInfo[] {
  80.       new StorageInfo(layoutVersionOld, namespaceIdCur, fsscTimeOld), // 0
  81.       new StorageInfo(layoutVersionOld, namespaceIdCur, fsscTimeCur), // 1
  82.       new StorageInfo(layoutVersionOld, namespaceIdCur, fsscTimeNew), // 2
  83.       new StorageInfo(layoutVersionOld, namespaceIdOld, fsscTimeOld), // 3
  84.       new StorageInfo(layoutVersionOld, namespaceIdOld, fsscTimeCur), // 4
  85.       new StorageInfo(layoutVersionOld, namespaceIdOld, fsscTimeNew), // 5
  86.       new StorageInfo(layoutVersionCur, namespaceIdCur, fsscTimeOld), // 6
  87.       new StorageInfo(layoutVersionCur, namespaceIdCur, fsscTimeCur), // 7
  88.       new StorageInfo(layoutVersionCur, namespaceIdCur, fsscTimeNew), // 8
  89.       new StorageInfo(layoutVersionCur, namespaceIdOld, fsscTimeOld), // 9
  90.       new StorageInfo(layoutVersionCur, namespaceIdOld, fsscTimeCur), // 10
  91.       new StorageInfo(layoutVersionCur, namespaceIdOld, fsscTimeNew), // 11
  92.       new StorageInfo(layoutVersionNew, namespaceIdCur, fsscTimeOld), // 12
  93.       new StorageInfo(layoutVersionNew, namespaceIdCur, fsscTimeCur), // 13
  94.       new StorageInfo(layoutVersionNew, namespaceIdCur, fsscTimeNew), // 14
  95.       new StorageInfo(layoutVersionNew, namespaceIdOld, fsscTimeOld), // 15
  96.       new StorageInfo(layoutVersionNew, namespaceIdOld, fsscTimeCur), // 16
  97.       new StorageInfo(layoutVersionNew, namespaceIdOld, fsscTimeNew), // 17
  98.     };
  99.   }
  100.   
  101.   /**
  102.    * Determines if the given Namenode version and Datanode version
  103.    * are compatible with each other. Compatibility in this case mean
  104.    * that the Namenode and Datanode will successfully start up and
  105.    * will work together. The rules for compatibility,
  106.    * taken from the DFS Upgrade Design, are as follows:
  107.    * <pre>
  108.    * 1. The data-node does regular startup (no matter which options 
  109.    *    it is started with) if
  110.    *       softwareLV == storedLV AND 
  111.    *       DataNode.FSSCTime == NameNode.FSSCTime
  112.    * 2. The data-node performs an upgrade if it is started without any 
  113.    *    options and
  114.    *       |softwareLV| > |storedLV| OR 
  115.    *       (softwareLV == storedLV AND
  116.    *        DataNode.FSSCTime < NameNode.FSSCTime)
  117.    * 3. NOT TESTED: The data-node rolls back if it is started with
  118.    *    the -rollback option and
  119.    *       |softwareLV| >= |previous.storedLV| AND 
  120.    *       DataNode.previous.FSSCTime <= NameNode.FSSCTime
  121.    * 4. In all other cases the startup fails.
  122.    * </pre>
  123.    */
  124.   boolean isVersionCompatible(StorageInfo namenodeVer, StorageInfo datanodeVer) {
  125.     // check #0
  126.     if (namenodeVer.getNamespaceID() != datanodeVer.getNamespaceID()) {
  127.       LOG.info("namespaceIDs are not equal: isVersionCompatible=false");
  128.       return false;
  129.     }
  130.     // check #1
  131.     int softwareLV = FSConstants.LAYOUT_VERSION;  // will also be Namenode's LV
  132.     int storedLV = datanodeVer.getLayoutVersion();
  133.     if (softwareLV == storedLV &&  
  134.         datanodeVer.getCTime() == namenodeVer.getCTime()) 
  135.       {
  136.         LOG.info("layoutVersions and cTimes are equal: isVersionCompatible=true");
  137.         return true;
  138.       }
  139.     // check #2
  140.     long absSoftwareLV = Math.abs((long)softwareLV);
  141.     long absStoredLV = Math.abs((long)storedLV);
  142.     if (absSoftwareLV > absStoredLV ||
  143.         (softwareLV == storedLV &&
  144.          datanodeVer.getCTime() < namenodeVer.getCTime())) 
  145.       {
  146.         LOG.info("softwareLayoutVersion is newer OR namenode cTime is newer: isVersionCompatible=true");
  147.         return true;
  148.       }
  149.     // check #4
  150.     LOG.info("default case: isVersionCompatible=false");
  151.     return false;
  152.   }
  153.   
  154.   /**
  155.    * This test ensures the appropriate response (successful or failure) from 
  156.    * a Datanode when the system is started with differing version combinations. 
  157.    * <pre>
  158.    * For each 3-tuple in the cross product
  159.    *   ({oldLayoutVersion,currentLayoutVersion,futureLayoutVersion},
  160.    *    {currentNamespaceId,incorrectNamespaceId},
  161.    *    {pastFsscTime,currentFsscTime,futureFsscTime})
  162.    *      1. Startup Namenode with version file containing 
  163.    *         (currentLayoutVersion,currentNamespaceId,currentFsscTime)
  164.    *      2. Attempt to startup Datanode with version file containing 
  165.    *         this iterations version 3-tuple
  166.    * </pre>
  167.    */
  168.   public void testVersions() throws Exception {
  169.     UpgradeUtilities.initialize();
  170.     Configuration conf = UpgradeUtilities.initializeStorageStateConf(1, 
  171.                                                       new Configuration());
  172.     StorageInfo[] versions = initializeVersions();
  173.     UpgradeUtilities.createStorageDirs(
  174.                                        NAME_NODE, conf.getStrings("dfs.name.dir"), "current");
  175.     cluster = new MiniDFSCluster(conf, 0, StartupOption.REGULAR);
  176.     StorageInfo nameNodeVersion = new StorageInfo(
  177.                                                   UpgradeUtilities.getCurrentLayoutVersion(),
  178.                                                   UpgradeUtilities.getCurrentNamespaceID(cluster),
  179.                                                   UpgradeUtilities.getCurrentFsscTime(cluster));
  180.     log("NameNode version info", NAME_NODE, null, nameNodeVersion);
  181.     for (int i = 0; i < versions.length; i++) {
  182.       File[] storage = UpgradeUtilities.createStorageDirs(
  183.                                                           DATA_NODE, conf.getStrings("dfs.data.dir"), "current");
  184.       log("DataNode version info", DATA_NODE, i, versions[i]);
  185.       UpgradeUtilities.createVersionFile(DATA_NODE, storage, versions[i]);
  186.       try {
  187.         cluster.startDataNodes(conf, 1, false, StartupOption.REGULAR, null);
  188.       } catch (Exception ignore) {
  189.         // Ignore.  The asserts below will check for problems.
  190.         // ignore.printStackTrace();
  191.       }
  192.       assertTrue(cluster.getNameNode() != null);
  193.       assertEquals(isVersionCompatible(nameNodeVersion, versions[i]),
  194.                    cluster.isDataNodeUp());
  195.       cluster.shutdownDataNodes();
  196.     }
  197.   }
  198.   
  199.   protected void tearDown() throws Exception {
  200.     LOG.info("Shutting down MiniDFSCluster");
  201.     if (cluster != null) cluster.shutdown();
  202.   }
  203.   
  204.   public static void main(String[] args) throws Exception {
  205.     new TestDFSStartupVersions().testVersions();
  206.   }
  207.   
  208. }