You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by sh...@apache.org on 2009/02/17 21:01:33 UTC

svn commit: r745221 - /hadoop/core/trunk/src/test/org/apache/hadoop/hdfs/server/namenode/TestStorageRestore.java

Author: shv
Date: Tue Feb 17 20:01:32 2009
New Revision: 745221

URL: http://svn.apache.org/viewvc?rev=745221&view=rev
Log:
HADOOP-4885. Committing additional file TestStorageRestore.java.

Added:
    hadoop/core/trunk/src/test/org/apache/hadoop/hdfs/server/namenode/TestStorageRestore.java

Added: hadoop/core/trunk/src/test/org/apache/hadoop/hdfs/server/namenode/TestStorageRestore.java
URL: http://svn.apache.org/viewvc/hadoop/core/trunk/src/test/org/apache/hadoop/hdfs/server/namenode/TestStorageRestore.java?rev=745221&view=auto
==============================================================================
--- hadoop/core/trunk/src/test/org/apache/hadoop/hdfs/server/namenode/TestStorageRestore.java (added)
+++ hadoop/core/trunk/src/test/org/apache/hadoop/hdfs/server/namenode/TestStorageRestore.java Tue Feb 17 20:01:32 2009
@@ -0,0 +1,228 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hdfs.server.namenode;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Random;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.FileUtil;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.hadoop.hdfs.server.common.Storage;
+import org.apache.hadoop.hdfs.server.common.Storage.StorageDirectory;
+import org.apache.hadoop.hdfs.server.namenode.FSImage.NameNodeDirType;
+import org.apache.hadoop.hdfs.server.namenode.FSImage.NameNodeFile;
+
+
+/**
+ * Startup and checkpoint tests
+ * 
+ */
+public class TestStorageRestore extends TestCase {
+  public static final String NAME_NODE_HOST = "localhost:";
+  public static final String NAME_NODE_HTTP_HOST = "0.0.0.0:";
+  private static final Log LOG =
+    LogFactory.getLog(TestStorageRestore.class.getName());
+  private Configuration config;
+  private File hdfsDir=null;
+  static final long seed = 0xAAAAEEFL;
+  static final int blockSize = 4096;
+  static final int fileSize = 8192;
+  private File path1, path2, path3;
+  private MiniDFSCluster cluster;
+
+  private void writeFile(FileSystem fileSys, Path name, int repl)
+  throws IOException {
+    FSDataOutputStream stm = fileSys.create(name, true,
+        fileSys.getConf().getInt("io.file.buffer.size", 4096),
+        (short)repl, (long)blockSize);
+    byte[] buffer = new byte[fileSize];
+    Random rand = new Random(seed);
+    rand.nextBytes(buffer);
+    stm.write(buffer);
+    stm.close();
+  }
+  
+ 
+  protected void setUp() throws Exception {
+    config = new Configuration();
+    String baseDir = System.getProperty("test.build.data", "/tmp");
+    
+    hdfsDir = new File(baseDir, "dfs");
+    if ( hdfsDir.exists() && !FileUtil.fullyDelete(hdfsDir) ) {
+      throw new IOException("Could not delete hdfs directory '" + hdfsDir + "'");
+    }
+    
+    hdfsDir.mkdir();
+    path1 = new File(hdfsDir, "name1");
+    path2 = new File(hdfsDir, "name2");
+    path3 = new File(hdfsDir, "name3");
+    
+    path1.mkdir(); path2.mkdir(); path3.mkdir();
+    if(!path2.exists() ||  !path3.exists() || !path1.exists()) {
+      throw new IOException("Couldn't create dfs.name dirs");
+    }
+    
+    String dfs_name_dir = new String(path1.getPath() + "," + path2.getPath());
+    System.out.println("configuring hdfsdir is " + hdfsDir.getAbsolutePath() + 
+        "; dfs_name_dir = "+ dfs_name_dir + ";dfs_name_edits_dir(only)=" + path3.getPath());
+    
+    config.set("dfs.name.dir", dfs_name_dir);
+    config.set("dfs.name.edits.dir", dfs_name_dir + "," + path3.getPath());
+
+    config.set("fs.checkpoint.dir",new File(hdfsDir, "secondary").getPath());
+ 
+    FileSystem.setDefaultUri(config, "hdfs://"+NAME_NODE_HOST + "0");
+    
+    config.set("dfs.secondary.http.address", "0.0.0.0:0");
+    
+    // set the restore feature on
+    config.setBoolean("dfs.name.dir.restore", true);
+  }
+
+  /**
+   * clean up
+   */
+  public void tearDown() throws Exception {
+    if (hdfsDir.exists() && !FileUtil.fullyDelete(hdfsDir) ) {
+      throw new IOException("Could not delete hdfs directory in tearDown '" + hdfsDir + "'");
+    } 
+  }
+  
+  /**
+   * invalidate storage by removing current directories
+   */
+  public void invalidateStorage(FSImage fi) throws IOException {
+    fi.getEditLog().processIOError(2); //name3
+    fi.getEditLog().processIOError(1); // name2
+  }
+  
+  /**
+   * test
+   */
+  public void printStorages(FSImage fs) {
+    LOG.info("current storages and corresoponding sizes:");
+    for(Iterator<StorageDirectory> it = fs.dirIterator(); it.hasNext(); ) {
+      StorageDirectory sd = it.next();
+      
+      if(sd.getStorageDirType().isOfType(NameNodeDirType.IMAGE)) {
+        File imf = FSImage.getImageFile(sd, NameNodeFile.IMAGE);
+        LOG.info("  image file " + imf.getAbsolutePath() + "; len = " + imf.length());  
+      }
+      if(sd.getStorageDirType().isOfType(NameNodeDirType.EDITS)) {
+        File edf = FSImage.getImageFile(sd, NameNodeFile.EDITS);
+        LOG.info("  edits file " + edf.getAbsolutePath() + "; len = " + edf.length()); 
+      }
+    }
+  }
+  
+  /**
+   *  check if files exist/not exist
+   */
+  public void checkFiles(boolean valid) {
+    //look at the valid storage
+    File fsImg1 = new File(path1, Storage.STORAGE_DIR_CURRENT + "/" + NameNodeFile.IMAGE.getName());
+    File fsImg2 = new File(path2, Storage.STORAGE_DIR_CURRENT + "/" + NameNodeFile.IMAGE.getName());
+    File fsImg3 = new File(path3, Storage.STORAGE_DIR_CURRENT + "/" + NameNodeFile.IMAGE.getName());
+
+    File fsEdits1 = new File(path1, Storage.STORAGE_DIR_CURRENT + "/" + NameNodeFile.EDITS.getName());
+    File fsEdits2 = new File(path2, Storage.STORAGE_DIR_CURRENT + "/" + NameNodeFile.EDITS.getName());
+    File fsEdits3 = new File(path3, Storage.STORAGE_DIR_CURRENT + "/" + NameNodeFile.EDITS.getName());
+
+    this.printStorages(cluster.getNameNode().getFSImage());
+    
+    LOG.info("++++ image files = "+fsImg1.getAbsolutePath() + "," + fsImg2.getAbsolutePath() + ","+ fsImg3.getAbsolutePath());
+    LOG.info("++++ edits files = "+fsEdits1.getAbsolutePath() + "," + fsEdits2.getAbsolutePath() + ","+ fsEdits3.getAbsolutePath());
+    LOG.info("checkFiles compares lengths: img1=" + fsImg1.length()  + ",img2=" + fsImg2.length()  + ",img3=" + fsImg3.length());
+    LOG.info("checkFiles compares lengths: edits1=" + fsEdits1.length()  + ",edits2=" + fsEdits2.length()  + ",edits3=" + fsEdits3.length());
+    
+    if(valid) {
+      // should be the same
+      assertTrue(fsImg1.length() == fsImg2.length());
+      assertTrue(0 == fsImg3.length()); //shouldn't be created
+      assertTrue(fsEdits1.length() == fsEdits2.length());
+      assertTrue(fsEdits1.length() == fsEdits3.length());
+    } else {
+      // should be different
+      //assertTrue(fsImg1.length() != fsImg2.length());
+      //assertTrue(fsImg1.length() != fsImg3.length());
+      assertTrue(fsEdits1.length() != fsEdits2.length());
+      assertTrue(fsEdits1.length() != fsEdits3.length());
+    }
+  }
+  
+  /**
+   * test 
+   * 1. create DFS cluster with 3 storage directories - 2 EDITS_IMAGE, 1 EDITS
+   * 2. create a cluster and write a file
+   * 3. corrupt/disable one storage (or two) by removing
+   * 4. run doCheckpoint - it will fail on removed dirs (which
+   * will invalidate the storages)
+   * 5. write another file
+   * 6. check that edits and fsimage differ 
+   * 7. run doCheckpoint
+   * 8. verify that all the image and edits files are the same.
+   */
+  public void testStorageRestore() throws Exception {
+    int numDatanodes = 2;
+    //Collection<String> dirs = config.getStringCollection("dfs.name.dir");
+    cluster = new MiniDFSCluster(0, config, numDatanodes, true, false, true,  null, null, null, null);
+    cluster.waitActive();
+    
+    SecondaryNameNode secondary = new SecondaryNameNode(config);
+    System.out.println("****testStorageRestore: Cluster and SNN started");
+    printStorages(cluster.getNameNode().getFSImage());
+    
+    FileSystem fs = cluster.getFileSystem();
+    Path path = new Path("/", "test");
+    writeFile(fs, path, 2);
+    
+    System.out.println("****testStorageRestore: file test written, invalidating storage...");
+  
+    invalidateStorage(cluster.getNameNode().getFSImage());
+    //secondary.doCheckpoint(); // this will cause storages to be removed.
+    printStorages(cluster.getNameNode().getFSImage());
+    System.out.println("****testStorageRestore: storage invalidated + doCheckpoint");
+
+    path = new Path("/", "test1");
+    writeFile(fs, path, 2);
+    System.out.println("****testStorageRestore: file test1 written");
+    
+    checkFiles(false); // SHOULD BE FALSE
+    
+    System.out.println("****testStorageRestore: checkfiles(false) run");
+    
+    secondary.doCheckpoint();  ///should enable storage..
+    
+    checkFiles(true);
+    System.out.println("****testStorageRestore: second Checkpoint done and checkFiles(true) run");
+    secondary.shutdown();
+    cluster.shutdown();
+  }
+}