TestSeekBug.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:5k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.hdfs;
  19. import junit.framework.TestCase;
  20. import java.io.*;
  21. import java.util.Random;
  22. import org.apache.hadoop.conf.Configuration;
  23. import org.apache.hadoop.fs.ChecksumFileSystem;
  24. import org.apache.hadoop.fs.FSDataInputStream;
  25. import org.apache.hadoop.fs.FSInputStream;
  26. import org.apache.hadoop.fs.FileSystem;
  27. import org.apache.hadoop.fs.Path;
  28. /**
  29.  * This class tests the presence of seek bug as described
  30.  * in HADOOP-508 
  31.  */
  32. public class TestSeekBug extends TestCase {
  33.   static final long seed = 0xDEADBEEFL;
  34.   static final int ONEMB = 1 << 20;
  35.   
  36.   private void writeFile(FileSystem fileSys, Path name) throws IOException {
  37.     // create and write a file that contains 1MB
  38.     DataOutputStream stm = fileSys.create(name);
  39.     byte[] buffer = new byte[ONEMB];
  40.     Random rand = new Random(seed);
  41.     rand.nextBytes(buffer);
  42.     stm.write(buffer);
  43.     stm.close();
  44.   }
  45.   
  46.   private void checkAndEraseData(byte[] actual, int from, byte[] expected, String message) {
  47.     for (int idx = 0; idx < actual.length; idx++) {
  48.       this.assertEquals(message+" byte "+(from+idx)+" differs. expected "+
  49.                         expected[from+idx]+" actual "+actual[idx],
  50.                         actual[idx], expected[from+idx]);
  51.       actual[idx] = 0;
  52.     }
  53.   }
  54.   
  55.   private void seekReadFile(FileSystem fileSys, Path name) throws IOException {
  56.     FSDataInputStream stm = fileSys.open(name, 4096);
  57.     byte[] expected = new byte[ONEMB];
  58.     Random rand = new Random(seed);
  59.     rand.nextBytes(expected);
  60.     
  61.     // First read 128 bytes to set count in BufferedInputStream
  62.     byte[] actual = new byte[128];
  63.     stm.read(actual, 0, actual.length);
  64.     // Now read a byte array that is bigger than the internal buffer
  65.     actual = new byte[100000];
  66.     stm.read(actual, 0, actual.length);
  67.     checkAndEraseData(actual, 128, expected, "First Read Test");
  68.     // now do a small seek, within the range that is already read
  69.     stm.seek(96036); // 4 byte seek
  70.     actual = new byte[128];
  71.     stm.read(actual, 0, actual.length);
  72.     checkAndEraseData(actual, 96036, expected, "Seek Bug");
  73.     // all done
  74.     stm.close();
  75.   }
  76.   /*
  77.    * Read some data, skip a few bytes and read more. HADOOP-922.
  78.    */
  79.   private void smallReadSeek(FileSystem fileSys, Path name) throws IOException {
  80.     if (fileSys instanceof ChecksumFileSystem) {
  81.       fileSys = ((ChecksumFileSystem)fileSys).getRawFileSystem();
  82.     }
  83.     // Make the buffer size small to trigger code for HADOOP-922
  84.     FSDataInputStream stmRaw = fileSys.open(name, 1);
  85.     byte[] expected = new byte[ONEMB];
  86.     Random rand = new Random(seed);
  87.     rand.nextBytes(expected);
  88.     
  89.     // Issue a simple read first.
  90.     byte[] actual = new byte[128];
  91.     stmRaw.seek(100000);
  92.     stmRaw.read(actual, 0, actual.length);
  93.     checkAndEraseData(actual, 100000, expected, "First Small Read Test");
  94.     // now do a small seek of 4 bytes, within the same block.
  95.     int newpos1 = 100000 + 128 + 4;
  96.     stmRaw.seek(newpos1);
  97.     stmRaw.read(actual, 0, actual.length);
  98.     checkAndEraseData(actual, newpos1, expected, "Small Seek Bug 1");
  99.     // seek another 256 bytes this time
  100.     int newpos2 = newpos1 + 256;
  101.     stmRaw.seek(newpos2);
  102.     stmRaw.read(actual, 0, actual.length);
  103.     checkAndEraseData(actual, newpos2, expected, "Small Seek Bug 2");
  104.     // all done
  105.     stmRaw.close();
  106.   }
  107.   
  108.   private void cleanupFile(FileSystem fileSys, Path name) throws IOException {
  109.     assertTrue(fileSys.exists(name));
  110.     fileSys.delete(name, true);
  111.     assertTrue(!fileSys.exists(name));
  112.   }
  113.   
  114.   /**
  115.    * Test if the seek bug exists in FSDataInputStream in DFS.
  116.    */
  117.   public void testSeekBugDFS() throws IOException {
  118.     Configuration conf = new Configuration();
  119.     MiniDFSCluster cluster = new MiniDFSCluster(conf, 1, true, null);
  120.     FileSystem fileSys = cluster.getFileSystem();
  121.     try {
  122.       Path file1 = new Path("seektest.dat");
  123.       writeFile(fileSys, file1);
  124.       seekReadFile(fileSys, file1);
  125.       smallReadSeek(fileSys, file1);
  126.       cleanupFile(fileSys, file1);
  127.     } finally {
  128.       fileSys.close();
  129.       cluster.shutdown();
  130.     }
  131.   }
  132.   
  133.   /**
  134.    * Tests if the seek bug exists in FSDataInputStream in LocalFS.
  135.    */
  136.   public void testSeekBugLocalFS() throws IOException {
  137.     Configuration conf = new Configuration();
  138.     FileSystem fileSys = FileSystem.getLocal(conf);
  139.     try {
  140.       Path file1 = new Path("build/test/data", "seektest.dat");
  141.       writeFile(fileSys, file1);
  142.       seekReadFile(fileSys, file1);
  143.       cleanupFile(fileSys, file1);
  144.     } finally {
  145.       fileSys.close();
  146.     }
  147.   }
  148. }