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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Random;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.ChecksumFileSystem;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.junit.Test;

/**
 * This class tests the presence of seek bug as described
 * in HADOOP-508 
 */
public class TestSeekBug {
  static final long seed = 0xDEADBEEFL;
  static final int ONEMB = 1 << 20;
  
  private void checkAndEraseData(byte[] actual, int from, byte[] expected, String message) {
    for (int idx = 0; idx < actual.length; idx++) {
      assertEquals(message+" byte "+(from+idx)+" differs. expected "+
                        expected[from+idx]+" actual "+actual[idx],
                        actual[idx], expected[from+idx]);
      actual[idx] = 0;
    }
  }
  
  private void seekReadFile(FileSystem fileSys, Path name) throws IOException {
    FSDataInputStream stm = fileSys.open(name, 4096);
    byte[] expected = new byte[ONEMB];
    Random rand = new Random(seed);
    rand.nextBytes(expected);
    
    // First read 128 bytes to set count in BufferedInputStream
    byte[] actual = new byte[128];
    stm.read(actual, 0, actual.length);
    // Now read a byte array that is bigger than the internal buffer
    actual = new byte[100000];
    IOUtils.readFully(stm, actual, 0, actual.length);
    checkAndEraseData(actual, 128, expected, "First Read Test");
    // now do a small seek, within the range that is already read
    stm.seek(96036); // 4 byte seek
    actual = new byte[128];
    IOUtils.readFully(stm, actual, 0, actual.length);
    checkAndEraseData(actual, 96036, expected, "Seek Bug");
    // all done
    stm.close();
  }

  /*
   * Read some data, skip a few bytes and read more. HADOOP-922.
   */
  private void smallReadSeek(FileSystem fileSys, Path name) throws IOException {
    if (fileSys instanceof ChecksumFileSystem) {
      fileSys = ((ChecksumFileSystem)fileSys).getRawFileSystem();
    }
    // Make the buffer size small to trigger code for HADOOP-922
    FSDataInputStream stmRaw = fileSys.open(name, 1);
    byte[] expected = new byte[ONEMB];
    Random rand = new Random(seed);
    rand.nextBytes(expected);
    
    // Issue a simple read first.
    byte[] actual = new byte[128];
    stmRaw.seek(100000);
    stmRaw.read(actual, 0, actual.length);
    checkAndEraseData(actual, 100000, expected, "First Small Read Test");

    // now do a small seek of 4 bytes, within the same block.
    int newpos1 = 100000 + 128 + 4;
    stmRaw.seek(newpos1);
    stmRaw.read(actual, 0, actual.length);
    checkAndEraseData(actual, newpos1, expected, "Small Seek Bug 1");

    // seek another 256 bytes this time
    int newpos2 = newpos1 + 256;
    stmRaw.seek(newpos2);
    stmRaw.read(actual, 0, actual.length);
    checkAndEraseData(actual, newpos2, expected, "Small Seek Bug 2");

    // all done
    stmRaw.close();
  }
  
  private void cleanupFile(FileSystem fileSys, Path name) throws IOException {
    assertTrue(fileSys.exists(name));
    fileSys.delete(name, true);
    assertTrue(!fileSys.exists(name));
  }
  
  /**
   * Test if the seek bug exists in FSDataInputStream in DFS.
   */
  @Test
  public void testSeekBugDFS() throws IOException {
    Configuration conf = new HdfsConfiguration();
    MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).build();
    FileSystem fileSys = cluster.getFileSystem();
    try {
      Path file1 = new Path("seektest.dat");
      DFSTestUtil.createFile(fileSys, file1, ONEMB, ONEMB,
          fileSys.getDefaultBlockSize(file1),
          fileSys.getDefaultReplication(file1), seed);
      seekReadFile(fileSys, file1);
      smallReadSeek(fileSys, file1);
      cleanupFile(fileSys, file1);
    } finally {
      fileSys.close();
      cluster.shutdown();
    }
  }

 /**
  * Test (expected to throw IOE) for negative
  * <code>FSDataInpuStream#seek</code> argument
  */
  @Test (expected=IOException.class)
  public void testNegativeSeek() throws IOException {
    Configuration conf = new HdfsConfiguration();
    MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).build();
    FileSystem fs = cluster.getFileSystem();
    try {
      Path seekFile = new Path("seekboundaries.dat");
      DFSTestUtil.createFile(
        fs,
        seekFile,
        ONEMB,
        ONEMB,
        fs.getDefaultBlockSize(seekFile),
        fs.getDefaultReplication(seekFile),
        seed);
      FSDataInputStream stream = fs.open(seekFile);
      // Perform "safe seek" (expected to pass)
      stream.seek(65536);
      assertEquals(65536, stream.getPos());
      // expect IOE for this call
      stream.seek(-73);
    } finally {
      fs.close();
      cluster.shutdown();
    }
  }

 /**
  * Test (expected to throw IOE) for <code>FSDataInpuStream#seek</code>
  * when the position argument is larger than the file size.
  */
  @Test (expected=IOException.class)
  public void testSeekPastFileSize() throws IOException {
    Configuration conf = new HdfsConfiguration();
    MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).build();
    FileSystem fs = cluster.getFileSystem();
    try {
      Path seekFile = new Path("seekboundaries.dat");
      DFSTestUtil.createFile(
        fs,
        seekFile,
        ONEMB,
        ONEMB,
        fs.getDefaultBlockSize(seekFile),
        fs.getDefaultReplication(seekFile),
        seed);
      FSDataInputStream stream = fs.open(seekFile);
      // Perform "safe seek" (expected to pass)
      stream.seek(65536);
      assertEquals(65536, stream.getPos());
      // expect IOE for this call
      stream.seek(ONEMB + ONEMB + ONEMB);
    } finally {
      fs.close();
      cluster.shutdown();
    }
  }
 
  /**
   * Tests if the seek bug exists in FSDataInputStream in LocalFS.
   */
  @Test
  public void testSeekBugLocalFS() throws IOException {
    Configuration conf = new HdfsConfiguration();
    FileSystem fileSys = FileSystem.getLocal(conf);
    try {
      Path file1 = new Path("build/test/data", "seektest.dat");
      DFSTestUtil.createFile(fileSys, file1, ONEMB, ONEMB,
          fileSys.getDefaultBlockSize(file1),
          fileSys.getDefaultReplication(file1), seed);
      seekReadFile(fileSys, file1);
      cleanupFile(fileSys, file1);
    } finally {
      fileSys.close();
    }
  }
}
