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

网格计算

开发平台:

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.FSDataInputStream;
  24. import org.apache.hadoop.fs.FileSystem;
  25. import org.apache.hadoop.fs.Path;
  26. import org.apache.hadoop.hdfs.server.datanode.SimulatedFSDataset;
  27. /**
  28.  * This class tests the DFS positional read functionality in a single node
  29.  * mini-cluster.
  30.  */
  31. public class TestPread extends TestCase {
  32.   static final long seed = 0xDEADBEEFL;
  33.   static final int blockSize = 4096;
  34.   boolean simulatedStorage = false;
  35.   private void writeFile(FileSystem fileSys, Path name) throws IOException {
  36.     // create and write a file that contains three blocks of data
  37.     DataOutputStream stm = fileSys.create(name, true, 4096, (short)1,
  38.                                           (long)blockSize);
  39.     // test empty file open and read
  40.     stm.close();
  41.     FSDataInputStream in = fileSys.open(name);
  42.     byte[] buffer = new byte[(int)(12*blockSize)];
  43.     in.readFully(0, buffer, 0, 0);
  44.     IOException res = null;
  45.     try { // read beyond the end of the file
  46.       in.readFully(0, buffer, 0, 1);
  47.     } catch (IOException e) {
  48.       // should throw an exception
  49.       res = e;
  50.     }
  51.     assertTrue("Error reading beyond file boundary.", res != null);
  52.     in.close();
  53.     if (!fileSys.delete(name, true))
  54.       assertTrue("Cannot delete file", false);
  55.     
  56.     // now create the real file
  57.     stm = fileSys.create(name, true, 4096, (short)1, (long)blockSize);
  58.     Random rand = new Random(seed);
  59.     rand.nextBytes(buffer);
  60.     stm.write(buffer);
  61.     stm.close();
  62.   }
  63.   
  64.   private void checkAndEraseData(byte[] actual, int from, byte[] expected, String message) {
  65.     for (int idx = 0; idx < actual.length; idx++) {
  66.       assertEquals(message+" byte "+(from+idx)+" differs. expected "+
  67.                         expected[from+idx]+" actual "+actual[idx],
  68.                         actual[idx], expected[from+idx]);
  69.       actual[idx] = 0;
  70.     }
  71.   }
  72.   
  73.   private void doPread(FSDataInputStream stm, long position, byte[] buffer,
  74.                        int offset, int length) throws IOException {
  75.     int nread = 0;
  76.     while (nread < length) {
  77.       int nbytes = stm.read(position+nread, buffer, offset+nread, length-nread);
  78.       assertTrue("Error in pread", nbytes > 0);
  79.       nread += nbytes;
  80.     }
  81.   }
  82.   
  83.   private void pReadFile(FileSystem fileSys, Path name) throws IOException {
  84.     FSDataInputStream stm = fileSys.open(name);
  85.     byte[] expected = new byte[(int)(12*blockSize)];
  86.     if (simulatedStorage) {
  87.       for (int i= 0; i < expected.length; i++) {  
  88.         expected[i] = SimulatedFSDataset.DEFAULT_DATABYTE;
  89.       }
  90.     } else {
  91.       Random rand = new Random(seed);
  92.       rand.nextBytes(expected);
  93.     }
  94.     // do a sanity check. Read first 4K bytes
  95.     byte[] actual = new byte[4096];
  96.     stm.readFully(actual);
  97.     checkAndEraseData(actual, 0, expected, "Read Sanity Test");
  98.     // now do a pread for the first 8K bytes
  99.     actual = new byte[8192];
  100.     doPread(stm, 0L, actual, 0, 8192);
  101.     checkAndEraseData(actual, 0, expected, "Pread Test 1");
  102.     // Now check to see if the normal read returns 4K-8K byte range
  103.     actual = new byte[4096];
  104.     stm.readFully(actual);
  105.     checkAndEraseData(actual, 4096, expected, "Pread Test 2");
  106.     // Now see if we can cross a single block boundary successfully
  107.     // read 4K bytes from blockSize - 2K offset
  108.     stm.readFully(blockSize - 2048, actual, 0, 4096);
  109.     checkAndEraseData(actual, (int)(blockSize-2048), expected, "Pread Test 3");
  110.     // now see if we can cross two block boundaries successfully
  111.     // read blockSize + 4K bytes from blockSize - 2K offset
  112.     actual = new byte[(int)(blockSize+4096)];
  113.     stm.readFully(blockSize - 2048, actual);
  114.     checkAndEraseData(actual, (int)(blockSize-2048), expected, "Pread Test 4");
  115.     // now see if we can cross two block boundaries that are not cached
  116.     // read blockSize + 4K bytes from 10*blockSize - 2K offset
  117.     actual = new byte[(int)(blockSize+4096)];
  118.     stm.readFully(10*blockSize - 2048, actual);
  119.     checkAndEraseData(actual, (int)(10*blockSize-2048), expected, "Pread Test 5");
  120.     // now check that even after all these preads, we can still read
  121.     // bytes 8K-12K
  122.     actual = new byte[4096];
  123.     stm.readFully(actual);
  124.     checkAndEraseData(actual, 8192, expected, "Pread Test 6");
  125.     // done
  126.     stm.close();
  127.     // check block location caching
  128.     stm = fileSys.open(name);
  129.     stm.readFully(1, actual, 0, 4096);
  130.     stm.readFully(4*blockSize, actual, 0, 4096);
  131.     stm.readFully(7*blockSize, actual, 0, 4096);
  132.     actual = new byte[3*4096];
  133.     stm.readFully(0*blockSize, actual, 0, 3*4096);
  134.     checkAndEraseData(actual, 0, expected, "Pread Test 7");
  135.     actual = new byte[8*4096];
  136.     stm.readFully(3*blockSize, actual, 0, 8*4096);
  137.     checkAndEraseData(actual, 3*blockSize, expected, "Pread Test 8");
  138.     // read the tail
  139.     stm.readFully(11*blockSize+blockSize/2, actual, 0, blockSize/2);
  140.     IOException res = null;
  141.     try { // read beyond the end of the file
  142.       stm.readFully(11*blockSize+blockSize/2, actual, 0, blockSize);
  143.     } catch (IOException e) {
  144.       // should throw an exception
  145.       res = e;
  146.     }
  147.     assertTrue("Error reading beyond file boundary.", res != null);
  148.     
  149.     stm.close();
  150.   }
  151.   
  152.   private void cleanupFile(FileSystem fileSys, Path name) throws IOException {
  153.     assertTrue(fileSys.exists(name));
  154.     assertTrue(fileSys.delete(name, true));
  155.     assertTrue(!fileSys.exists(name));
  156.   }
  157.   
  158.   /**
  159.    * Tests positional read in DFS.
  160.    */
  161.   public void testPreadDFS() throws IOException {
  162.     dfsPreadTest(false); //normal pread
  163.     dfsPreadTest(true); //trigger read code path without transferTo.
  164.   }
  165.   
  166.   private void dfsPreadTest(boolean disableTransferTo) throws IOException {
  167.     Configuration conf = new Configuration();
  168.     conf.setLong("dfs.block.size", 4096);
  169.     conf.setLong("dfs.read.prefetch.size", 4096);
  170.     if (simulatedStorage) {
  171.       conf.setBoolean("dfs.datanode.simulateddatastorage", true);
  172.     }
  173.     if (disableTransferTo) {
  174.       conf.setBoolean("dfs.datanode.transferTo.allowed", false);
  175.     }
  176.     MiniDFSCluster cluster = new MiniDFSCluster(conf, 3, true, null);
  177.     FileSystem fileSys = cluster.getFileSystem();
  178.     try {
  179.       Path file1 = new Path("preadtest.dat");
  180.       writeFile(fileSys, file1);
  181.       pReadFile(fileSys, file1);
  182.       cleanupFile(fileSys, file1);
  183.     } finally {
  184.       fileSys.close();
  185.       cluster.shutdown();
  186.     }
  187.   }
  188.   
  189.   public void testPreadDFSSimulated() throws IOException {
  190.     simulatedStorage = true;
  191.     testPreadDFS();
  192.     simulatedStorage = true;
  193.   }
  194.   
  195.   /**
  196.    * Tests positional read in LocalFS.
  197.    */
  198.   public void testPreadLocalFS() throws IOException {
  199.     Configuration conf = new Configuration();
  200.     FileSystem fileSys = FileSystem.getLocal(conf);
  201.     try {
  202.       Path file1 = new Path("build/test/data", "preadtest.dat");
  203.       writeFile(fileSys, file1);
  204.       pReadFile(fileSys, file1);
  205.       cleanupFile(fileSys, file1);
  206.     } finally {
  207.       fileSys.close();
  208.     }
  209.   }
  210.   public static void main(String[] args) throws Exception {
  211.     new TestPread().testPreadDFS();
  212.   }
  213. }