Package org.apache.hadoop.hdfs.notifier.server

Source Code of org.apache.hadoop.hdfs.notifier.server.TestPreTransactionalServerLogReader$DummyServerCore

/**
* 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.notifier.server;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.ConcurrentLinkedQueue;

import junit.framework.Assert;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.fs.permission.PermissionStatus;
import org.apache.hadoop.hdfs.notifier.NamespaceNotification;
import org.apache.hadoop.hdfs.protocol.Block;
import org.apache.hadoop.hdfs.server.common.Util;
import org.apache.hadoop.hdfs.server.namenode.EditLogFileOutputStream;
import org.apache.hadoop.hdfs.server.namenode.BlocksMap.BlockInfo;
import org.apache.hadoop.hdfs.server.namenode.FSEditLogOp;
import org.apache.hadoop.hdfs.server.namenode.INodeId;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class TestPreTransactionalServerLogReader {
  static private Logger LOG = LoggerFactory.getLogger(TestPreTransactionalServerLogReader.class);
  private static final String base_dir = System.getProperty("test.build.data"
      "build/test/data");

  static Configuration conf;
 
  @BeforeClass
  public static void initConf() {
    Configuration.addDefaultResource("namespace-notifier-server-default.xml");
    Configuration.addDefaultResource("hdfs-default.xml");
    conf = new Configuration();
    conf.addResource("namespace-notifier-server-site.xml");
    conf.addResource("hdfs-site.xml");
    conf = new Configuration();
  }
 
  /**
   * Creates the edits directory.
   * @return edits dir
   * @throws IOException
   */
  private File createEditsDir() throws IOException {
    File editsDir = new File(base_dir, "edits");
    File currentDir = new File(editsDir, "current");
    FileUtil.fullyDelete(editsDir);
    if (!editsDir.mkdirs() || !currentDir.mkdirs()) {
      throw new IOException("Can't create directory: " + editsDir);
    }
    return editsDir;
  }
 
 
  public static EditLogFileOutputStream initEdits(File editsDir) throws IOException {
    File edits = getFileWithCurrent(editsDir, "edits");
    File fstime = getFileWithCurrent(editsDir, "fstime");

    if (!edits.createNewFile())
      throw new IOException("Failed to create edits file");
    EditLogFileOutputStream out = new EditLogFileOutputStream(edits, null);
    out.create();
    if (!fstime.createNewFile())
      throw new IOException("Failed to create fstime file");
   
    return out;
  }
 
  static File getFileWithCurrent(File editsDir, String name) {
    File currentDir = new File(editsDir, "current");
    return new File(currentDir, name);
  }

  private EditLogFileOutputStream beginRoll(File editsDir,
      EditLogFileOutputStream editsOutput)
          throws IOException {
    File editsNew = getFileWithCurrent(editsDir, "edits.new");

    editsOutput.close();
    if (!editsNew.createNewFile())
      throw new IOException("Failed to create edits.new file");
    EditLogFileOutputStream out = new EditLogFileOutputStream(editsNew, null);
    out.create();
    Assert.assertTrue(editsNew.exists());

    return out;
  }
 
  private void endRoll(File editsDir) throws IOException {
    File edits = getFileWithCurrent(editsDir, "edits");
    File editsNew = getFileWithCurrent(editsDir, "edits.new");
    File fstime = getFileWithCurrent(editsDir, "fstime");
   
    Assert.assertTrue(editsNew.exists());
    Assert.assertTrue(fstime.exists());
    if (!editsNew.renameTo(edits)) {
      edits.delete();
      if (!editsNew.renameTo(edits))
        throw new IOException();
    }
   
    fstime.delete();
    DataOutputStream fstimeOutput =
        new DataOutputStream(new FileOutputStream(fstime));
    fstimeOutput.writeLong(System.currentTimeMillis());
    fstimeOutput.flush();
    fstimeOutput.close();
  }
 
 
  private void writeOperation(EditLogFileOutputStream out,
      long txId, boolean forceSync) throws IOException {
    FSEditLogOp.AddOp op = FSEditLogOp.AddOp.getUniqueInstance();
    op.setTransactionId(txId);
    op.set(INodeId.GRANDFATHER_INODE_ID, "/a/b", (short)3, 100L, 100L, 100L, new BlockInfo[0],
        PermissionStatus.createImmutable("x", "y", FsPermission.getDefault()),
        "x", "y");
    out.write(op);
    LOG.info("Wrote operation " + txId);
    if (txId % 10 == 0 || forceSync) {
      out.setReadyToFlush();
      out.flush();
      LOG.info("Flushed operation " + txId);
   
  }
 
 
  @Test
  public void testOneOperation() throws Exception {
    File editsDir = createEditsDir();
    DummyServerCore core = new DummyServerCore();
    EditLogFileOutputStream out = initEdits(editsDir);
    ServerLogReaderPreTransactional logReader = new ServerLogReaderPreTransactional(core,
        Util.stringAsURI(editsDir.getAbsolutePath()));
    core.logReader = logReader;
    Thread coreThread, logReaderThread;
   
    coreThread = new Thread(core);
    logReaderThread = new Thread(logReader);
   
    logReaderThread.start();
    coreThread.start();
    writeOperation(out, 1000, true);
    Thread.sleep(500);
    core.shutdown();
    logReaderThread.join();
    coreThread.join();
   
    Assert.assertEquals(1, core.notifications.size());
    Assert.assertEquals(1000, core.notifications.poll().txId);
  }
 
  @Test
  public void testMultipleOperations() throws Exception {
    File editsDir = createEditsDir();
    DummyServerCore core = new DummyServerCore();
    EditLogFileOutputStream out = initEdits(editsDir);
    ServerLogReaderPreTransactional logReader = new ServerLogReaderPreTransactional(core,
        Util.stringAsURI(editsDir.getAbsolutePath()));
    core.logReader = logReader;
    Thread coreThread, logReaderThread;
    long txCount = 1000;
   
    coreThread = new Thread(core);
    logReaderThread = new Thread(logReader);
   
    logReaderThread.start();
    coreThread.start();
    for (long txId = 0; txId < txCount; txId ++) {
      writeOperation(out, txId, false);
    }
   
    // flush
    out.setReadyToFlush();
    out.flush();
   
    Thread.sleep(500);
    core.shutdown();
    logReaderThread.join();
    coreThread.join();
   
    Assert.assertEquals(1000, core.notifications.size());
    for (long txId = 0; txId < txCount; txId ++)
      Assert.assertEquals(txId, core.notifications.poll().txId);
  }
 
  @Test
  public void testTwoOperationsRoll() throws Exception {
    File editsDir = createEditsDir();
    DummyServerCore core = new DummyServerCore();
    EditLogFileOutputStream out = initEdits(editsDir);
    ServerLogReaderPreTransactional logReader = new ServerLogReaderPreTransactional(core,
        Util.stringAsURI(editsDir.getAbsolutePath()));
    core.logReader = logReader;
    Thread coreThread, logReaderThread;

    coreThread = new Thread(core);
    logReaderThread = new Thread(logReader);
   
    coreThread.start();
    Thread.sleep(1000);
    logReaderThread.start();
    writeOperation(out, 1000, true);
    out = beginRoll(editsDir, out);
    writeOperation(out, 1001, true);   
    Thread.sleep(500);
    endRoll(editsDir);
    Thread.sleep(500);
    core.shutdown();
    logReaderThread.join();
    coreThread.join();
   
    Assert.assertEquals(2, core.notifications.size());
    Assert.assertEquals(1000, core.notifications.poll().txId);
    Assert.assertEquals(1001, core.notifications.poll().txId);
  }
 
  private void testMultipleOperationsRoll(long txPerNormalPhase,
      long txPerRollPhase, long txCount) throws Exception {
    File editsDir = createEditsDir();
    DummyServerCore core = new DummyServerCore();
    EditLogFileOutputStream out = initEdits(editsDir);
    ServerLogReaderPreTransactional logReader = new ServerLogReaderPreTransactional(core,
        Util.stringAsURI(editsDir.getAbsolutePath()));
    core.logReader = logReader;
    Thread coreThread, logReaderThread;
    boolean rollPhase = false;
   
    coreThread = new Thread(core);
    logReaderThread = new Thread(logReader);
   
    logReaderThread.start();
    coreThread.start();
    Thread.sleep(1000);
   
    long count = 0;
    for (long txId = 0; txId < txCount; txId ++) {
      if (rollPhase) {
        count --;
        if (count == 0) {
          rollPhase = false;
          count = txPerNormalPhase;
          endRoll(editsDir);
        }
      } else {
        count --;
        if (count == 0) {
          rollPhase = true;
          count = txPerRollPhase;
          beginRoll(editsDir, out);
        }
      }
     
      writeOperation(out, txId, false);
      if (txId % 10 == 0) {
        Thread.sleep(1);
      }
    }
   
    // flush
    out.setReadyToFlush();
    out.flush();
   
    Thread.sleep(1000);
    core.shutdown();
    logReaderThread.join();
    coreThread.join();
   
    Assert.assertEquals(txCount, core.notifications.size());
    for (long txId = 0; txId < txCount; txId ++)
      Assert.assertEquals(txId, core.notifications.poll().txId);
  }
 
  @Test
  public void testMultipleOperationsBigRoll() throws Exception {
    testMultipleOperationsRoll(3, 1000, 10000);
  }
 
  @Test
  public void testMultipleOperationsNormalRoll() throws Exception {
    testMultipleOperationsRoll(1000, 1000, 10000);
  }
 
  @Test
  public void testMultipleOperationsSmallRoll() throws Exception {
    testMultipleOperationsRoll(1000, 3, 10000);
  }
 
  public static class DummyServerCore extends EmptyServerCore {

    ConcurrentLinkedQueue<NamespaceNotification> notifications =
        new ConcurrentLinkedQueue<NamespaceNotification>();

    IServerLogReader logReader;
    Configuration config = conf;
   
    @Override
    public void handleNotification(NamespaceNotification n) {
      notifications.add(n);
    }
   
    @Override
    public void run() {
      try {
        while (!shutdownPending()) {
          NamespaceNotification n = logReader.getNamespaceNotification();
          if (n != null)
            handleNotification(n);
        }
      } catch (IOException e) {
        LOG.error("DummyServerCore failed reading notifications", e);
      } finally {
        shutdown();
      }
    }
   
    public void setConfiguration(Configuration conf) {
      this.config = conf;
    }
   
    @Override
    public Configuration getConfiguration() {
      return config;
    }
  }
 
}
TOP

Related Classes of org.apache.hadoop.hdfs.notifier.server.TestPreTransactionalServerLogReader$DummyServerCore

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.