/**
 * 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 java.util.List;

import org.apache.hadoop.hdfs.DFSClient;
import org.apache.commons.logging.impl.Log4JLogger;
import org.apache.hadoop.hdfs.protocol.LocatedBlock;
import org.apache.hadoop.hdfs.protocol.proto.DataTransferProtos.Status;
import org.apache.hadoop.fs.Path;
import org.apache.log4j.Level;

import org.junit.Test;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.never;

public class TestClientBlockVerification {

  static BlockReaderTestUtil util = null;
  static final Path TEST_FILE = new Path("/test.file");
  static final int FILE_SIZE_K = 256;
  static LocatedBlock testBlock = null;

  static {
    ((Log4JLogger)RemoteBlockReader2.LOG).getLogger().setLevel(Level.ALL);
  }
  @BeforeClass
  public static void setupCluster() throws Exception {
    final int REPLICATION_FACTOR = 1;
    util = new BlockReaderTestUtil(REPLICATION_FACTOR);
    util.writeFile(TEST_FILE, FILE_SIZE_K);
    List<LocatedBlock> blkList = util.getFileBlocks(TEST_FILE, FILE_SIZE_K);
    testBlock = blkList.get(0);     // Use the first block to test
  }

  /**
   * Verify that if we read an entire block, we send CHECKSUM_OK
   */
  @Test
  public void testBlockVerification() throws Exception {
    RemoteBlockReader2 reader = (RemoteBlockReader2)spy(
        util.getBlockReader(testBlock, 0, FILE_SIZE_K * 1024));
    util.readAndCheckEOS(reader, FILE_SIZE_K * 1024, true);
    verify(reader).sendReadResult(reader.dnSock, Status.CHECKSUM_OK);
    reader.close();
  }

  /**
   * Test that if we do an incomplete read, we don't call CHECKSUM_OK
   */
  @Test
  public void testIncompleteRead() throws Exception {
    RemoteBlockReader2 reader = (RemoteBlockReader2)spy(
        util.getBlockReader(testBlock, 0, FILE_SIZE_K * 1024));
    util.readAndCheckEOS(reader, FILE_SIZE_K / 2 * 1024, false);

    // We asked the blockreader for the whole file, and only read
    // half of it, so no CHECKSUM_OK
    verify(reader, never()).sendReadResult(reader.dnSock, Status.CHECKSUM_OK);
    reader.close();
  }

  /**
   * Test that if we ask for a half block, and read it all, we *do*
   * send CHECKSUM_OK. The DN takes care of knowing whether it was
   * the whole block or not.
   */
  @Test
  public void testCompletePartialRead() throws Exception {
    // Ask for half the file
    RemoteBlockReader2 reader = (RemoteBlockReader2)spy(
        util.getBlockReader(testBlock, 0, FILE_SIZE_K * 1024 / 2));
    // And read half the file
    util.readAndCheckEOS(reader, FILE_SIZE_K * 1024 / 2, true);
    verify(reader).sendReadResult(reader.dnSock, Status.CHECKSUM_OK);
    reader.close();
  }

  /**
   * Test various unaligned reads to make sure that we properly
   * account even when we don't start or end on a checksum boundary
   */
  @Test
  public void testUnalignedReads() throws Exception {
    int startOffsets[] = new int[] { 0, 3, 129 };
    int lengths[] = new int[] { 30, 300, 512, 513, 1025 };
    for (int startOffset : startOffsets) {
      for (int length : lengths) {
        DFSClient.LOG.info("Testing startOffset = " + startOffset + " and " +
                           " len=" + length);
        RemoteBlockReader2 reader = (RemoteBlockReader2)spy(
            util.getBlockReader(testBlock, startOffset, length));
        util.readAndCheckEOS(reader, length, true);
        verify(reader).sendReadResult(reader.dnSock, Status.CHECKSUM_OK);
        reader.close();
      }
    }
  }


  @AfterClass
  public static void teardownCluster() throws Exception {
    util.shutdown();
  }

}
