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

import java.io.IOException;

import org.apache.commons.logging.impl.Log4JLogger;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fi.DataTransferTestUtil;
import org.apache.hadoop.fi.DataTransferTestUtil.DataTransferTest;
import org.apache.hadoop.fi.DataTransferTestUtil.DoosAction;
import org.apache.hadoop.fi.DataTransferTestUtil.OomAction;
import org.apache.hadoop.fi.DataTransferTestUtil.SleepAction;
import org.apache.hadoop.fi.DataTransferTestUtil.VerificationAction;
import org.apache.hadoop.fi.FiTestUtil;
import org.apache.hadoop.fi.FiTestUtil.Action;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.HdfsConfiguration;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.protocol.datatransfer.DataTransferProtocol;
import org.apache.hadoop.hdfs.protocol.DatanodeID;
import org.apache.log4j.Level;
import org.junit.Assert;
import org.junit.Test;

/** Test DataTransferProtocol with fault injection. */
public class TestFiDataTransferProtocol {
  static final short REPLICATION = 3;
  static final long BLOCKSIZE = 1L * (1L << 20);

  static final Configuration conf = new HdfsConfiguration();
  static {
    conf.setInt(DFSConfigKeys.DFS_DATANODE_HANDLER_COUNT_KEY, 1);
    conf.setInt(DFSConfigKeys.DFS_REPLICATION_KEY, REPLICATION);
    conf.setInt(DFSConfigKeys.DFS_CLIENT_SOCKET_TIMEOUT_KEY, 5000);
  }

  static private FSDataOutputStream createFile(FileSystem fs, Path p
      ) throws IOException {
    return fs.create(p, true, fs.getConf().getInt("io.file.buffer.size", 4096),
        REPLICATION, BLOCKSIZE);
  }

  {
    ((Log4JLogger)DataTransferProtocol.LOG).getLogger().setLevel(Level.ALL);
  }

  /**
   * 1. create files with dfs
   * 2. write 1 byte
   * 3. close file
   * 4. open the same file
   * 5. read the 1 byte and compare results
   */
  static void write1byte(String methodName) throws IOException {
    final MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf
        ).numDataNodes(REPLICATION + 1).build();
    final FileSystem dfs = cluster.getFileSystem();
    try {
      final Path p = new Path("/" + methodName + "/foo");
      final FSDataOutputStream out = createFile(dfs, p);
      out.write(1);
      out.close();
      
      final FSDataInputStream in = dfs.open(p);
      final int b = in.read();
      in.close();
      Assert.assertEquals(1, b);
    }
    finally {
      dfs.close();
      cluster.shutdown();
    }
  }

  private static void runSlowDatanodeTest(String methodName, SleepAction a
                  ) throws IOException {
    FiTestUtil.LOG.info("Running " + methodName + " ...");
    final DataTransferTest t = (DataTransferTest)DataTransferTestUtil.initTest();
    t.fiCallReceivePacket.set(a);
    t.fiReceiverOpWriteBlock.set(a);
    t.fiStatusRead.set(a);
    write1byte(methodName);
  }
  
  private static void runReceiverOpWriteBlockTest(String methodName,
      int errorIndex, Action<DatanodeID, IOException> a) throws IOException {
    FiTestUtil.LOG.info("Running " + methodName + " ...");
    final DataTransferTest t = (DataTransferTest) DataTransferTestUtil
        .initTest();
    t.fiReceiverOpWriteBlock.set(a);
    t.fiPipelineInitErrorNonAppend.set(new VerificationAction(methodName,
        errorIndex));
    write1byte(methodName);
    Assert.assertTrue(t.isSuccess());
  }
  
  private static void runStatusReadTest(String methodName, int errorIndex,
      Action<DatanodeID, IOException> a) throws IOException {
    FiTestUtil.LOG.info("Running " + methodName + " ...");
    final DataTransferTest t = (DataTransferTest) DataTransferTestUtil
        .initTest();
    t.fiStatusRead.set(a);
    t.fiPipelineInitErrorNonAppend.set(new VerificationAction(methodName,
        errorIndex));
    write1byte(methodName);
    Assert.assertTrue(t.isSuccess());
  }

  private static void runCallWritePacketToDisk(String methodName,
      int errorIndex, Action<DatanodeID, IOException> a) throws IOException {
    FiTestUtil.LOG.info("Running " + methodName + " ...");
    final DataTransferTest t = (DataTransferTest)DataTransferTestUtil.initTest();
    t.fiCallWritePacketToDisk.set(a);
    t.fiPipelineErrorAfterInit.set(new VerificationAction(methodName, errorIndex));
    write1byte(methodName);
    Assert.assertTrue(t.isSuccess());
  }

  /**
   * Pipeline setup:
   * DN0 never responses after received setup request from client.
   * Client gets an IOException and determine DN0 bad.
   */
  @Test
  public void pipeline_Fi_01() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runReceiverOpWriteBlockTest(methodName, 0, new SleepAction(methodName, 0, 0));
  }

  /**
   * Pipeline setup:
   * DN1 never responses after received setup request from client.
   * Client gets an IOException and determine DN1 bad.
   */
  @Test
  public void pipeline_Fi_02() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runReceiverOpWriteBlockTest(methodName, 1, new SleepAction(methodName, 1, 0));
  }

  /**
   * Pipeline setup:
   * DN2 never responses after received setup request from client.
   * Client gets an IOException and determine DN2 bad.
   */
  @Test
  public void pipeline_Fi_03() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runReceiverOpWriteBlockTest(methodName, 2, new SleepAction(methodName, 2, 0));
  }

  /**
   * Pipeline setup, DN1 never responses after received setup ack from DN2.
   * Client gets an IOException and determine DN1 bad.
   */
  @Test
  public void pipeline_Fi_04() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runStatusReadTest(methodName, 1, new SleepAction(methodName, 1, 0));
  }

  /**
   * Pipeline setup, DN0 never responses after received setup ack from DN1.
   * Client gets an IOException and determine DN0 bad.
   */
  @Test
  public void pipeline_Fi_05() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runStatusReadTest(methodName, 0, new SleepAction(methodName, 0, 0));
  }

  /**
   * Pipeline setup with DN0 very slow but it won't lead to timeout.
   * Client finishes setup successfully.
   */
  @Test
  public void pipeline_Fi_06() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runSlowDatanodeTest(methodName, new SleepAction(methodName, 0, 3000));
  }

  /**
   * Pipeline setup with DN1 very slow but it won't lead to timeout.
   * Client finishes setup successfully.
   */
  @Test
  public void pipeline_Fi_07() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runSlowDatanodeTest(methodName, new SleepAction(methodName, 1, 3000));
  }

  /**
   * Pipeline setup with DN2 very slow but it won't lead to timeout.
   * Client finishes setup successfully.
   */
  @Test
  public void pipeline_Fi_08() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runSlowDatanodeTest(methodName, new SleepAction(methodName, 2, 3000));
  }

  /**
   * Pipeline setup, DN0 throws an OutOfMemoryException right after it
   * received a setup request from client.
   * Client gets an IOException and determine DN0 bad.
   */
  @Test
  public void pipeline_Fi_09() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runReceiverOpWriteBlockTest(methodName, 0, new OomAction(methodName, 0));
  }

  /**
   * Pipeline setup, DN1 throws an OutOfMemoryException right after it
   * received a setup request from DN0.
   * Client gets an IOException and determine DN1 bad.
   */
  @Test
  public void pipeline_Fi_10() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runReceiverOpWriteBlockTest(methodName, 1, new OomAction(methodName, 1));
  }

  /**
   * Pipeline setup, DN2 throws an OutOfMemoryException right after it
   * received a setup request from DN1.
   * Client gets an IOException and determine DN2 bad.
   */
  @Test
  public void pipeline_Fi_11() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runReceiverOpWriteBlockTest(methodName, 2, new OomAction(methodName, 2));
  }

  /**
   * Pipeline setup, DN1 throws an OutOfMemoryException right after it
   * received a setup ack from DN2.
   * Client gets an IOException and determine DN1 bad.
   */
  @Test
  public void pipeline_Fi_12() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runStatusReadTest(methodName, 1, new OomAction(methodName, 1));
  }

  /**
   * Pipeline setup, DN0 throws an OutOfMemoryException right after it
   * received a setup ack from DN1.
   * Client gets an IOException and determine DN0 bad.
   */
  @Test
  public void pipeline_Fi_13() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runStatusReadTest(methodName, 0, new OomAction(methodName, 0));
  }

  /**
   * Streaming: Write a packet, DN0 throws a DiskOutOfSpaceError
   * when it writes the data to disk.
   * Client gets an IOException and determine DN0 bad.
   */
  @Test
  public void pipeline_Fi_14() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runCallWritePacketToDisk(methodName, 0, new DoosAction(methodName, 0));
  }

  /**
   * Streaming: Write a packet, DN1 throws a DiskOutOfSpaceError
   * when it writes the data to disk.
   * Client gets an IOException and determine DN1 bad.
   */
  @Test
  public void pipeline_Fi_15() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runCallWritePacketToDisk(methodName, 1, new DoosAction(methodName, 1));
  }
  
  /**
   * Streaming: Write a packet, DN2 throws a DiskOutOfSpaceError
   * when it writes the data to disk.
   * Client gets an IOException and determine DN2 bad.
   */
  @Test
  public void pipeline_Fi_16() throws IOException {
    final String methodName = FiTestUtil.getMethodName();
    runCallWritePacketToDisk(methodName, 2, new DoosAction(methodName, 2));
  }
}
