source: proiecte/HadoopJUnit/hadoop-0.20.1/src/test/org/apache/hadoop/hdfs/TestPread.java @ 120

Last change on this file since 120 was 120, checked in by (none), 14 years ago

Added the mail files for the Hadoop JUNit Project

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