Package org.apache.hadoop.raid

Source Code of org.apache.hadoop.raid.TestReadConstruction

package org.apache.hadoop.raid;

import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URI;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.zip.CRC32;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockMissingException;
import org.apache.hadoop.fs.ChecksumException;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.DistributedRaidFileSystem;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.RaidDFSUtil;
import org.apache.hadoop.hdfs.TestDatanodeBlockScanner;
import org.apache.hadoop.hdfs.TestRaidDfs;
import org.apache.hadoop.hdfs.protocol.LocatedBlocks;

import junit.framework.TestCase;

public class TestReadConstruction extends TestCase {

  final static String TEST_DIR = new File(
      System.getProperty("test.build.data",
          "build/contrib/raid/test/data")).getAbsolutePath();
  final static String CONFIG_FILE = new File(TEST_DIR,
      "test-raid.xml").getAbsolutePath();
  final static long RELOAD_INTERVAL = 1000;
  final static Log LOG = LogFactory.getLog(
      "org.apache.hadoop.raid.TestReadConstruction");
  final static Random rand = new Random();
  final static int NUM_DATANODES = 3;

  Configuration conf;
  String namenode = null;
  String hftp = null;
  MiniDFSCluster dfs = null;
  FileSystem fileSys = null;
  Path root = null;
  Set<String> allExpectedMissingFiles = null;
 
  protected void mySetup() throws Exception {
    conf = new Configuration();
    if (System.getProperty("hadoop.log.dir") == null) {
      String base = new File(".").getAbsolutePath();
      System.setProperty("hadoop.log.dir", new Path(base).toString()
          + "/logs");
    }
   

    new File(TEST_DIR).mkdirs(); // Make sure data directory exists
    conf.set("raid.config.file", CONFIG_FILE);
    conf.setBoolean("raid.config.reload", true);
    conf.setLong("raid.config.reload.interval", RELOAD_INTERVAL);

    // the RaidNode does the raiding inline
    conf.set("raid.classname", "org.apache.hadoop.raid.LocalRaidNode");
    // use local block fixer
    conf.set("raid.blockfix.classname",
        "org.apache.hadoop.raid.LocalBlockIntegrityMonitor");

    conf.set("raid.server.address", "localhost:0");
    Utils.loadTestCodecs(conf, 10, 1, 4, "/destraid", "/destraidrs");
    conf.setInt("fs.trash.interval", 1440);

    dfs = new MiniDFSCluster(conf, NUM_DATANODES, true, null);
    dfs.waitActive();
    fileSys = dfs.getFileSystem();
    namenode = fileSys.getUri().toString();
    hftp = "hftp://localhost.localdomain:" + dfs.getNameNodePort();

    FileSystem.setDefaultUri(conf, namenode);
  }

  private DistributedRaidFileSystem getRaidFS() throws IOException {
    DistributedFileSystem dfs = (DistributedFileSystem)fileSys;
    Configuration clientConf = new Configuration(conf);
    clientConf.set("fs.hdfs.impl",
        "org.apache.hadoop.hdfs.DistributedRaidFileSystem");
    clientConf.set("fs.raid.underlyingfs.impl",
        "org.apache.hadoop.hdfs.DistributedFileSystem");
    clientConf.setBoolean("fs.hdfs.impl.disable.cache", true);
    URI dfsUri = dfs.getUri();
    return (DistributedRaidFileSystem)FileSystem.get(dfsUri, clientConf);
  }
 
  private void doRaid(Path srcPath, Codec codec) throws IOException {
    RaidNode.doRaid(conf, fileSys.getFileStatus(srcPath),
              new Path(codec.parityDirectory), codec,
              new RaidNode.Statistics(),
              RaidUtils.NULL_PROGRESSABLE,
              false, 1, 1);
  }

 
  private boolean doThePartialTest(Codec codec,
                                int blockNum,
                                int[] corruptBlockIdxs) throws Exception {
    long blockSize = 8192L;
    int bufferSize = 4192;

    Path srcPath = new Path("/user/dikang/raidtest/file" +
                            UUID.randomUUID().toString());

    long crc = TestRaidDfs.createTestFilePartialLastBlock(fileSys, srcPath,
        1, blockNum, blockSize);
   
    DistributedRaidFileSystem raidFs = getRaidFS();
    assertTrue(raidFs.exists(srcPath));
   
    // generate the parity files.
    doRaid(srcPath, codec);

    FileStatus file1Stat = fileSys.getFileStatus(srcPath);
    long length = file1Stat.getLen();
    LocatedBlocks file1Loc =
        RaidDFSUtil.getBlockLocations((DistributedFileSystem)fileSys,
            srcPath.toUri().getPath(),
            0, length);
    // corrupt file1
   
    for (int idx: corruptBlockIdxs) {
      corruptBlock(file1Loc.get(idx).getBlock().getBlockName(),
                                dfs);
    }
    RaidDFSUtil.reportCorruptBlocks((DistributedFileSystem)fileSys, srcPath,
                         corruptBlockIdxs, blockSize);
   
    // verify the partial read
    byte[] buffer = new byte[bufferSize];
    FSDataInputStream in = raidFs.open(srcPath);
   
    long numRead = 0;
    CRC32 newcrc = new CRC32();
   
    int num = 0;
    while (num >= 0) {
      num = in.read(numRead, buffer, 0, bufferSize);
      if (num < 0) {
        break;
      }
      numRead += num;
      newcrc.update(buffer, 0, num);
    }
    in.close();

    if (numRead != length) {
      LOG.info("Number of bytes read " + numRead +
               " does not match file size " + length);
      return false;
    }

    LOG.info(" Newcrc " + newcrc.getValue() + " old crc " + crc);
    if (newcrc.getValue() != crc) {
      LOG.info("CRC mismatch of file " + srcPath.toUri().getPath() + ": " +
                newcrc + " vs. " + crc);
      return false;
    }
    return true;
  }
 
  public void testReadCorruptPartialSuccess() throws Exception {
    // test the "rs"
    try {
      mySetup();
      int blockNum = 10;
      int[][] corruptBlockIdxs = new int[][] {{0, 3, 6, 9}, {0, 1, 2, 3}};
      for (int i=0; i<corruptBlockIdxs.length; i++) {
        assertTrue(doThePartialTest(Codec.getCodec("rs"),
            blockNum, corruptBlockIdxs[i]));
      }
    } finally {
      if (null != dfs) {
        dfs.shutdown();
      }
    }
   
    // test the "xor"
    try {
      mySetup();
      int blockNum = 10;
      for (int i=0; i<blockNum; i++) {
        int[] corruptBlockIdxs = new int[]{i};
        LOG.info("Corrupt Block " + i +
            " in testReadCorruptParitalSuccess for xor.");
        assertTrue(doThePartialTest(Codec.getCodec("xor"),
                  blockNum, corruptBlockIdxs));
      }
    } finally {
      if (null != dfs) {
        dfs.shutdown();
      }
    }
  }
 
  public void testReadCorruptPartialFail() throws Exception {
   
    // test the "rs"
    try {
      mySetup();
      int blockNum = 10;
      int[] corruptBlockIdxs = new int[]{0, 4, 6, 8, 9};
      doThePartialTest(Codec.getCodec("rs"),
                        blockNum, corruptBlockIdxs);
      fail();
    } catch(ChecksumException e) {
    } catch(BlockMissingException e) {
    } finally {
      if (null != dfs) {
        dfs.shutdown();
      }
    }
   
    // test the "xor"
    try {
      mySetup();
      int blockNum = 10;
      int[] corruptBlockIdxs = new int[]{0, 1};
      doThePartialTest(Codec.getCodec("xor"),
                        blockNum, corruptBlockIdxs);
      fail();
    } catch(ChecksumException e) {
    } catch(BlockMissingException e) {
    } finally {
      if (null != dfs) {
        dfs.shutdown();
      }
    }
  }
 
  static void corruptBlock(String blockName, MiniDFSCluster dfs)
      throws IOException {
    boolean corrupted = false;
    for (int i = 0; i < NUM_DATANODES; i++) {
      corrupted |= TestDatanodeBlockScanner.corruptReplica(blockName, i, dfs);
    }
    assertTrue("could not corrupt block: " + blockName, corrupted);
  }
}
TOP

Related Classes of org.apache.hadoop.raid.TestReadConstruction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.