Package org.apache.hadoop.hdfs.server.datanode

Source Code of org.apache.hadoop.hdfs.server.datanode.TestDatanodeFadvise$FadviseHandler

package org.apache.hadoop.hdfs.server.datanode;

import java.io.File;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.Random;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.DFSTestUtil;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.protocol.Block;
import org.apache.hadoop.io.WriteOptions;
import org.apache.hadoop.hdfs.protocol.LocatedBlock;
import org.apache.hadoop.hdfs.protocol.LocatedBlocks;
import org.apache.hadoop.hdfs.server.datanode.BlockDataFile.NativeOperation;
import org.apache.hadoop.hdfs.server.datanode.BlockDataFile.PosixFadviseRunnable;
import org.apache.hadoop.hdfs.util.InjectionEvent;
import org.apache.hadoop.util.InjectionEventCore;
import org.apache.hadoop.io.nativeio.NativeIO;
import org.apache.hadoop.util.InjectionEventI;
import org.apache.hadoop.util.InjectionHandler;

import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Test;

public class TestDatanodeFadvise {

  private static Configuration conf;
  private static MiniDFSCluster cluster;
  private static final int BLOCK_SIZE = 1024 * 1024 * 2;
  private static final int BLOCKS = 2;
  private static AtomicInteger nFadvise = new AtomicInteger();
  private static volatile boolean pass;

  public static void setUp(int dn, Configuration c) throws Exception {
    conf = c;
    conf.setBoolean("dfs.datanode.fadvise.secondary.replicas", true);
    conf.setInt("dfs.block.size", 1024);
    cluster = new MiniDFSCluster(conf, dn, true, null);
    pass = true;
    nFadvise.set(0);
  }

  private static class FadviseHandler extends InjectionHandler {
    private final int fadvise;

    public FadviseHandler(int fadvise) {
      this.fadvise = fadvise;
    }
    protected void _processEvent(InjectionEventI event, Object... args) {
      if (event == InjectionEventCore.NATIVEIO_POSIX_FADVISE) {
        nFadvise.incrementAndGet();
        int advise = (Integer) args[0];
        if (advise != fadvise) {
          pass = false;
        }
      } else if (event == InjectionEvent.DATANODE_SKIP_NATIVE_OPERATION) {
        NativeOperation op = (NativeOperation)args[1];
        if (op.getClass().equals(PosixFadviseRunnable.class)) {
          nFadvise.incrementAndGet();
          int advise = (Integer) args[0];
          if (advise != fadvise) {
            pass = false;
          }
        }
      }
    }
  }

  @Test
  public void testWriteWithRemoteFadvise() throws Exception {
    InjectionHandler.set(new FadviseHandler(NativeIO.POSIX_FADV_DONTNEED));
    setUp(3, new Configuration());
    DFSTestUtil util = new DFSTestUtil("/testWrite", 1, 3, BLOCK_SIZE * BLOCKS);
    util.createFiles(cluster.getFileSystem(), "/ABC");
    util.checkFiles(cluster.getFileSystem(), "/ABC");

    String[] fileNames = util.getFileNames("/ABC");
    assertEquals(1, fileNames.length);

    long start = System.currentTimeMillis();
    boolean replicated = false;
    long totalBlocks = -1;
    while (!replicated && (System.currentTimeMillis() - start < 30000)) {
      LocatedBlocks blocks = cluster.getNameNode().getBlockLocations(
          fileNames[0], 0, Long.MAX_VALUE);
      replicated = true;
      totalBlocks = blocks.getLocatedBlocks().size();
      for (LocatedBlock block : blocks.getLocatedBlocks()) {
        replicated = (replicated && (block.getLocations().length == 3));
      }
      Thread.sleep(1000);
    }
    assertTrue(replicated);

    assertTrue(NativeIO.isfadvisePossible());
    waitFadvise(2 * totalBlocks);
  }

  private void waitFadvise(long expected) throws Exception {
    long start = System.currentTimeMillis();
    while(System.currentTimeMillis() - start < 30000 && nFadvise.get() != expected) {
      Thread.sleep(1000);
    }
    assertTrue(pass);
    if (NativeIO.isAvailable()) {
      assertEquals(expected , nFadvise.get());
    }
  }


  private void runFileFadvise(int advise, int expectedFadvise) throws Exception {
    nFadvise.set(0);
    InjectionHandler.set(new FadviseHandler(advise));
    DistributedFileSystem fs = (DistributedFileSystem) cluster.getFileSystem();
    WriteOptions options = new WriteOptions();
    options.setFadvise(advise);
    FSDataOutputStream out = fs.create(new Path("/test"), null, true, 1024,
        (short) 3, BLOCK_SIZE, 512, null, null, options);
    Random r = new Random();
    byte buffer[] = new byte[BLOCK_SIZE];
    r.nextBytes(buffer);
    out.write(buffer);
    out.close();

    assertTrue(NativeIO.isfadvisePossible());
    waitFadvise(expectedFadvise);
  }

  @Test
  public void testFileFadvise() throws Exception {
    setUp(1, new Configuration());
    for (int advise = 1; advise < 6; advise++) {
      runFileFadvise(advise, 1);
    }
  }

  @Test
  public void testFileRangeFadvise() throws Exception {
    Configuration conf = new Configuration();
    conf.setInt("dfs.datanode.fadvise.filerange.size", BLOCK_SIZE / 20);
    setUp(1, conf);
    for (int advise = 1; advise < 6; advise++) {
      // 10 fadvise since we have 1MB buffer at the end of a block.
      // 1 extra fadvise while closing the block.
      runFileFadvise(advise, 11);
    }
  }

  @After
  public void tearDown() throws Exception {
    cluster.shutdown();
    InjectionHandler.clear();
  }

}
TOP

Related Classes of org.apache.hadoop.hdfs.server.datanode.TestDatanodeFadvise$FadviseHandler

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.