source: proiecte/HadoopJUnit/hadoop-0.20.1/src/test/org/apache/hadoop/io/file/tfile/TestTFileStreams.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: 11.3 KB
Line 
1/**
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with this
4 * work for additional information regarding copyright ownership. The ASF
5 * licenses this file to you under the Apache License, Version 2.0 (the
6 * "License"); you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 */
17
18package org.apache.hadoop.io.file.tfile;
19
20import java.io.DataOutputStream;
21import java.io.EOFException;
22import java.io.IOException;
23import java.util.Random;
24
25import junit.framework.Assert;
26import junit.framework.TestCase;
27
28import org.apache.hadoop.conf.Configuration;
29import org.apache.hadoop.fs.FSDataOutputStream;
30import org.apache.hadoop.fs.FileSystem;
31import org.apache.hadoop.fs.Path;
32import org.apache.hadoop.io.WritableUtils;
33import org.apache.hadoop.io.file.tfile.TFile.Reader;
34import org.apache.hadoop.io.file.tfile.TFile.Writer;
35import org.apache.hadoop.io.file.tfile.TFile.Reader.Scanner;
36
37/**
38 *
39 * Streaming interfaces test case class using GZ compression codec, base class
40 * of none and LZO compression classes.
41 *
42 */
43
44public class TestTFileStreams extends TestCase {
45  private static String ROOT =
46      System.getProperty("test.build.data", "/tmp/tfile-test");
47
48  private final static int BLOCK_SIZE = 512;
49  private final static int K = 1024;
50  private final static int M = K * K;
51  protected boolean skip = false;
52  private FileSystem fs;
53  private Configuration conf;
54  private Path path;
55  private FSDataOutputStream out;
56  Writer writer;
57
58  private String compression = Compression.Algorithm.GZ.getName();
59  private String comparator = "memcmp";
60  private String outputFile = "TFileTestStreams";
61
62  public void init(String compression, String comparator, String outputFile) {
63    this.compression = compression;
64    this.comparator = comparator;
65    this.outputFile = outputFile;
66  }
67
68  @Override
69  public void setUp() throws IOException {
70    conf = new Configuration();
71    path = new Path(ROOT, outputFile);
72    fs = path.getFileSystem(conf);
73    out = fs.create(path);
74    writer = new Writer(out, BLOCK_SIZE, compression, comparator, conf);
75  }
76
77  @Override
78  public void tearDown() throws IOException {
79    if (!skip) {
80      try {
81        closeOutput();
82      } catch (Exception e) {
83        // no-op
84      }
85      fs.delete(path, true);
86    }
87  }
88
89  public void testNoEntry() throws IOException {
90    if (skip)
91      return;
92    closeOutput();
93    TestTFileByteArrays.readRecords(fs, path, 0, conf);
94  }
95
96  public void testOneEntryKnownLength() throws IOException {
97    if (skip)
98      return;
99    writeRecords(1, true, true);
100
101    TestTFileByteArrays.readRecords(fs, path, 1, conf);
102  }
103
104  public void testOneEntryUnknownLength() throws IOException {
105    if (skip)
106      return;
107    writeRecords(1, false, false);
108
109    // TODO: will throw exception at getValueLength, it's inconsistent though;
110    // getKeyLength returns a value correctly, though initial length is -1
111    TestTFileByteArrays.readRecords(fs, path, 1, conf);
112  }
113
114  // known key length, unknown value length
115  public void testOneEntryMixedLengths1() throws IOException {
116    if (skip)
117      return;
118    writeRecords(1, true, false);
119
120    TestTFileByteArrays.readRecords(fs, path, 1, conf);
121  }
122
123  // unknown key length, known value length
124  public void testOneEntryMixedLengths2() throws IOException {
125    if (skip)
126      return;
127    writeRecords(1, false, true);
128
129    TestTFileByteArrays.readRecords(fs, path, 1, conf);
130  }
131
132  public void testTwoEntriesKnownLength() throws IOException {
133    if (skip)
134      return;
135    writeRecords(2, true, true);
136
137    TestTFileByteArrays.readRecords(fs, path, 2, conf);
138  }
139
140  // Negative test
141  public void testFailureAddKeyWithoutValue() throws IOException {
142    if (skip)
143      return;
144    DataOutputStream dos = writer.prepareAppendKey(-1);
145    dos.write("key0".getBytes());
146    try {
147      closeOutput();
148      fail("Cannot add only a key without a value. ");
149    }
150    catch (IllegalStateException e) {
151      // noop, expecting an exception
152    }
153  }
154
155  public void testFailureAddValueWithoutKey() throws IOException {
156    if (skip)
157      return;
158    DataOutputStream outValue = null;
159    try {
160      outValue = writer.prepareAppendValue(6);
161      outValue.write("value0".getBytes());
162      fail("Cannot add a value without adding key first. ");
163    }
164    catch (Exception e) {
165      // noop, expecting an exception
166    }
167    finally {
168      if (outValue != null) {
169        outValue.close();
170      }
171    }
172  }
173
174  public void testFailureOneEntryKnownLength() throws IOException {
175    if (skip)
176      return;
177    DataOutputStream outKey = writer.prepareAppendKey(2);
178    try {
179      outKey.write("key0".getBytes());
180      fail("Specified key length mismatched the actual key length.");
181    }
182    catch (IOException e) {
183      // noop, expecting an exception
184    }
185
186    DataOutputStream outValue = null;
187    try {
188      outValue = writer.prepareAppendValue(6);
189      outValue.write("value0".getBytes());
190    }
191    catch (Exception e) {
192      // noop, expecting an exception
193    }
194  }
195
196  public void testFailureKeyTooLong() throws IOException {
197    if (skip)
198      return;
199    DataOutputStream outKey = writer.prepareAppendKey(2);
200    try {
201      outKey.write("key0".getBytes());
202      outKey.close();
203      Assert.fail("Key is longer than requested.");
204    }
205    catch (Exception e) {
206      // noop, expecting an exception
207    }
208    finally {
209    }
210  }
211
212  public void testFailureKeyTooShort() throws IOException {
213    if (skip)
214      return;
215    DataOutputStream outKey = writer.prepareAppendKey(4);
216    outKey.write("key0".getBytes());
217    outKey.close();
218    DataOutputStream outValue = writer.prepareAppendValue(15);
219    try {
220      outValue.write("value0".getBytes());
221      outValue.close();
222      Assert.fail("Value is shorter than expected.");
223    }
224    catch (Exception e) {
225      // noop, expecting an exception
226    }
227    finally {
228    }
229  }
230
231  public void testFailureValueTooLong() throws IOException {
232    if (skip)
233      return;
234    DataOutputStream outKey = writer.prepareAppendKey(4);
235    outKey.write("key0".getBytes());
236    outKey.close();
237    DataOutputStream outValue = writer.prepareAppendValue(3);
238    try {
239      outValue.write("value0".getBytes());
240      outValue.close();
241      Assert.fail("Value is longer than expected.");
242    }
243    catch (Exception e) {
244      // noop, expecting an exception
245    }
246
247    try {
248      outKey.close();
249      outKey.close();
250    }
251    catch (Exception e) {
252      Assert.fail("Second or more close() should have no effect.");
253    }
254  }
255
256  public void testFailureValueTooShort() throws IOException {
257    if (skip)
258      return;
259    DataOutputStream outKey = writer.prepareAppendKey(8);
260    try {
261      outKey.write("key0".getBytes());
262      outKey.close();
263      Assert.fail("Key is shorter than expected.");
264    }
265    catch (Exception e) {
266      // noop, expecting an exception
267    }
268    finally {
269    }
270  }
271
272  public void testFailureCloseKeyStreamManyTimesInWriter() throws IOException {
273    if (skip)
274      return;
275    DataOutputStream outKey = writer.prepareAppendKey(4);
276    try {
277      outKey.write("key0".getBytes());
278      outKey.close();
279    }
280    catch (Exception e) {
281      // noop, expecting an exception
282    }
283    finally {
284      try {
285        outKey.close();
286      }
287      catch (Exception e) {
288        // no-op
289      }
290    }
291    outKey.close();
292    outKey.close();
293    Assert.assertTrue("Multiple close should have no effect.", true);
294  }
295
296  public void testFailureKeyLongerThan64K() throws IOException {
297    if (skip)
298      return;
299    try {
300      DataOutputStream outKey = writer.prepareAppendKey(64 * K + 1);
301      Assert.fail("Failed to handle key longer than 64K.");
302    }
303    catch (IndexOutOfBoundsException e) {
304      // noop, expecting exceptions
305    }
306    closeOutput();
307  }
308
309  public void testFailureKeyLongerThan64K_2() throws IOException {
310    if (skip)
311      return;
312    DataOutputStream outKey = writer.prepareAppendKey(-1);
313    try {
314      byte[] buf = new byte[K];
315      Random rand = new Random();
316      for (int nx = 0; nx < K + 2; nx++) {
317        rand.nextBytes(buf);
318        outKey.write(buf);
319      }
320      outKey.close();
321      Assert.fail("Failed to handle key longer than 64K.");
322    }
323    catch (EOFException e) {
324      // noop, expecting exceptions
325    }
326    finally {
327      try {
328        closeOutput();
329      }
330      catch (Exception e) {
331        // no-op
332      }
333    }
334  }
335
336  public void testFailureNegativeOffset() throws IOException {
337    if (skip)
338      return;
339    writeRecords(2, true, true);
340
341    Reader reader = new Reader(fs.open(path), fs.getFileStatus(path).getLen(), conf);
342    Scanner scanner = reader.createScanner();
343    byte[] buf = new byte[K];
344    try {
345      scanner.entry().getKey(buf, -1);
346      Assert.fail("Failed to handle key negative offset.");
347    }
348    catch (Exception e) {
349      // noop, expecting exceptions
350    }
351    finally {
352    }
353    scanner.close();
354    reader.close();
355  }
356
357  /**
358   * Verify that the compressed data size is less than raw data size.
359   *
360   * @throws IOException
361   */
362  public void testFailureCompressionNotWorking() throws IOException {
363    if (skip)
364      return;
365    long rawDataSize = writeRecords(10000, false, false, false);
366    if (!compression.equalsIgnoreCase(Compression.Algorithm.NONE.getName())) {
367      Assert.assertTrue(out.getPos() < rawDataSize);
368    }
369    closeOutput();
370  }
371
372  public void testFailureCompressionNotWorking2() throws IOException {
373    if (skip)
374      return;
375    long rawDataSize = writeRecords(10000, true, true, false);
376    if (!compression.equalsIgnoreCase(Compression.Algorithm.NONE.getName())) {
377      Assert.assertTrue(out.getPos() < rawDataSize);
378    }
379    closeOutput();
380  }
381
382  private long writeRecords(int count, boolean knownKeyLength,
383      boolean knownValueLength, boolean close) throws IOException {
384    long rawDataSize = 0;
385    for (int nx = 0; nx < count; nx++) {
386      String key = TestTFileByteArrays.composeSortedKey("key", count, nx);
387      DataOutputStream outKey =
388          writer.prepareAppendKey(knownKeyLength ? key.length() : -1);
389      outKey.write(key.getBytes());
390      outKey.close();
391      String value = "value" + nx;
392      DataOutputStream outValue =
393          writer.prepareAppendValue(knownValueLength ? value.length() : -1);
394      outValue.write(value.getBytes());
395      outValue.close();
396      rawDataSize +=
397          WritableUtils.getVIntSize(key.getBytes().length)
398              + key.getBytes().length
399              + WritableUtils.getVIntSize(value.getBytes().length)
400              + value.getBytes().length;
401    }
402    if (close) {
403      closeOutput();
404    }
405    return rawDataSize;
406  }
407
408  private long writeRecords(int count, boolean knownKeyLength,
409      boolean knownValueLength) throws IOException {
410    return writeRecords(count, knownKeyLength, knownValueLength, true);
411  }
412
413  private void closeOutput() throws IOException {
414    if (writer != null) {
415      writer.close();
416      writer = null;
417    }
418    if (out != null) {
419      out.close();
420      out = null;
421    }
422  }
423}
Note: See TracBrowser for help on using the repository browser.