Package org.apache.hadoop.hdfs

Source Code of org.apache.hadoop.hdfs.TestAvatarQuiesce

package org.apache.hadoop.hdfs;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Random;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.server.common.Storage.StorageDirectory;
import org.apache.hadoop.hdfs.server.namenode.AvatarNode;
import org.apache.hadoop.hdfs.server.namenode.FSImage;
import org.apache.hadoop.hdfs.server.namenode.NNStorage;
import org.apache.hadoop.hdfs.server.namenode.Standby;
import org.apache.hadoop.hdfs.util.InjectionEvent;
import org.apache.hadoop.hdfs.util.MD5FileUtils;
import org.apache.hadoop.util.InjectionEventI;
import org.apache.hadoop.util.InjectionHandler;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

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

import org.junit.BeforeClass;
import org.junit.Test;

public class TestAvatarQuiesce {

  final static Log LOG = LogFactory.getLog(TestAvatarQuiesce.class);

  private MiniAvatarCluster cluster;
  private Configuration conf;
  private FileSystem fs;
  private Random random = new Random();

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    MiniAvatarCluster.createAndStartZooKeeper();
  }

  private void setUp(String name, boolean waitForCheckpoint)
      throws Exception {
    LOG.info("------------------- test: " + name + " START ----------------");
    conf = new Configuration();
    conf.setBoolean("fs.ha.retrywrites", true);
    conf.setBoolean("fs.checkpoint.enabled", true);
    conf.setLong("fs.checkpoint.period", 2);
    conf.setBoolean("fs.checkpoint.wait", waitForCheckpoint);
   
    cluster = new MiniAvatarCluster.Builder(conf).numDataNodes(3).enableQJM(false).build();
    fs = cluster.getFileSystem();
  }

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

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
    MiniAvatarCluster.shutDownZooKeeper();
  }

  public void createEdits(int nEdits) throws IOException {
    for (int i = 0; i < nEdits / 2; i++) {
      // Create file ends up logging two edits to the edit log, one for create
      // file and one for bumping up the generation stamp
      fs.create(new Path("/" + random.nextInt()));
    }
  }

  public long getCurrentTxId(AvatarNode avatar) {
    return avatar.getFSImage().getEditLog().getCurrentTxId();
  }

  // ////////////////////////////

  private void testQuiesceWhenSavingNamespace(InjectionEvent event,
      boolean expectException)
      throws Exception {
    TestAvatarQuiesceHandler h = new TestAvatarQuiesceHandler(event);
    InjectionHandler.set(h);
    setUp("testQuiesceWhenSavingNamespace: " + event, false);
    // fail once
    AvatarNode primary = cluster.getPrimaryAvatar(0).avatar;
    AvatarNode standby = cluster.getStandbyAvatar(0).avatar;
   
    createEdits(20);

    // wait to the savers are up for some checkpoint
    // and waiting until we interrupt
    h.waitReachedSynchronizationPoint();
     
    standby.quiesceStandby(getCurrentTxId(primary) - 1);
    // SLS + ELS + SLS + 20 edits
    assertEquals(23, getCurrentTxId(primary));
    assertEquals(getCurrentTxId(primary), getCurrentTxId(standby));
    if(expectException)
      assertTrue(h.exceptionEvent);
   
    //assert that the cancelled checkpoint was removed
    long ckptTxId = h.cancelledCkptTxid;
    for (Iterator<StorageDirectory> it = standby.getFSImage().dirIterator(); it
        .hasNext();) {
      StorageDirectory sd = it.next();
      File image = new File(sd.getRoot(), NNStorage.getImageFileName(ckptTxId));
      assertFalse(image.exists());
      assertFalse(new File(sd.getRoot(),
          NNStorage.getCheckpointImageFileName(ckptTxId)).exists());
      assertFalse(MD5FileUtils.getDigestFileForFile(image).exists());
    }
  }

  @Test
  public void testQuiesceWhenSN0() throws Exception {
    // save namespace - initiated
    // saver threads - not initiated
    // sn should stop before moving current
    // interruprion comes before sn starts
    testQuiesceWhenSavingNamespace(
        InjectionEvent.FSIMAGE_STARTING_SAVE_NAMESPACE, true);
  }

  @Test
  public void testQuiesceWhenSN1() throws Exception {
    // save namespace - initiated
    // saver threads - not initiated
    // sn should get InterruptedException when joining saverThreads
    // interruption comes before calling saver.join()
    testQuiesceWhenSavingNamespace(
        InjectionEvent.FSIMAGE_CREATING_SAVER_THREADS, true);
  }

  @Test
  public void testQuiesceWhenSN2() throws Exception {
    // save namespace - initiated
    // saver threads - initiated
    // sn should get InterruptedException when joining saverThreads
    // interruption comes during calling saver.join()
    testQuiesceWhenSavingNamespace(
        InjectionEvent.FSIMAGE_STARTING_SAVER_THREAD, true);
  }
 
  @Test
  public void testQuiesceWhenSN3() throws Exception {
    // save namespace - initiated
    // saver threads - initiated
    // interruption comes during just after the image and md5 were saved
    testQuiesceWhenSavingNamespace(
        InjectionEvent.FSIMAGE_SAVED_IMAGE, true);
  }

  class TestAvatarQuiesceHandler extends InjectionHandler {

    // specifies where the thread should wait for interruption
    private InjectionEvent synchronizationPoint;
    public boolean exceptionEvent = false;
    private volatile boolean receivedCancelRequest = false;
    volatile boolean reachedSynchronizationPoint = false;
    long cancelledCkptTxid = -1;

    public TestAvatarQuiesceHandler(InjectionEvent se) {
      synchronizationPoint = se;
    }
   
    private int skipEvents = 2;
   
    void waitReachedSynchronizationPoint() {
      while(!reachedSynchronizationPoint) {
        DFSTestUtil.waitSecond();
      }
    }

    @Override
    protected void _processEvent(InjectionEventI event, Object... args) {
      if (event == InjectionEvent.FSIMAGE_CANCEL_REQUEST_RECEIVED) {
        LOG.info("Injection handler: processing event - " + event);
        receivedCancelRequest = true;
        return;
      }
      if (synchronizationPoint == event) {
        if ((event == InjectionEvent.FSIMAGE_STARTING_SAVER_THREAD ||
            event == InjectionEvent.FSIMAGE_SAVED_IMAGE)
            && skipEvents > 0) {
          skipEvents--;
          LOG.info("Skipping event to accommodate format: " + event);
          return;
        }
        if (event == InjectionEvent.FSIMAGE_SAVED_IMAGE) {
          cancelledCkptTxid = (Long)args[0];
        }
        reachedSynchronizationPoint = true;
        while (!receivedCancelRequest) {
          DFSTestUtil.waitSecond();
        }
        LOG.info("FINISHED WAITING - TESTING ONLY : " + synchronizationPoint);
      } else if (event ==InjectionEvent.STANDBY_CANCELLED_EXCEPTION_THROWN) {
        exceptionEvent = true;
      }
    }
  }
}
TOP

Related Classes of org.apache.hadoop.hdfs.TestAvatarQuiesce

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.