View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.util;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.apache.hadoop.conf.Configuration;
25  import org.apache.hadoop.hbase.SmallTests;
26  import org.apache.hadoop.hbase.io.compress.Compression;
27  import org.apache.hadoop.io.DataOutputBuffer;
28  import org.apache.hadoop.io.compress.CompressionCodec;
29  import org.apache.hadoop.io.compress.CompressionOutputStream;
30  import org.apache.hadoop.util.NativeCodeLoader;
31  import org.apache.hadoop.util.ReflectionUtils;
32  import org.junit.Test;
33  import org.junit.experimental.categories.Category;
34  
35  import java.io.BufferedOutputStream;
36  import java.io.DataOutputStream;
37  import java.io.IOException;
38  
39  import static org.junit.Assert.*;
40  
41  @Category(SmallTests.class)
42  public class TestCompressionTest {
43    static final Log LOG = LogFactory.getLog(TestCompressionTest.class);
44  
45    @Test
46    public void testExceptionCaching() {
47      // This test will fail if you run the tests with LZO compression available.
48      try {
49        CompressionTest.testCompression(Compression.Algorithm.LZO);
50        fail(); // always throws
51      } catch (IOException e) {
52        // there should be a 'cause'.
53        assertNotNull(e.getCause());
54      }
55  
56      // this is testing the caching of the test results.
57      try {
58        CompressionTest.testCompression(Compression.Algorithm.LZO);
59        fail(); // always throws
60      } catch (IOException e) {
61        // there should be NO cause because it's a direct exception not wrapped
62        assertNull(e.getCause());
63      }
64  
65      assertFalse(CompressionTest.testCompression("LZO"));
66    }
67  
68    @Test
69    public void testTestCompression() {
70      assertTrue(CompressionTest.testCompression("NONE"));
71      assertTrue(CompressionTest.testCompression("GZ"));
72  
73      if (NativeCodeLoader.isNativeCodeLoaded()) {
74        nativeCodecTest("LZO", "lzo2", "com.hadoop.compression.lzo.LzoCodec");
75        nativeCodecTest("LZ4", null, "org.apache.hadoop.io.compress.Lz4Codec");
76        nativeCodecTest("SNAPPY", "snappy", "org.apache.hadoop.io.compress.SnappyCodec");
77      } else {
78        // Hadoop nativelib is not available
79        LOG.debug("Native code not loaded");
80        assertFalse(CompressionTest.testCompression("LZO"));
81        assertFalse(CompressionTest.testCompression("LZ4"));
82        assertFalse(CompressionTest.testCompression("SNAPPY"));
83      }
84    }
85  
86    private boolean isCompressionAvailable(String codecClassName) {
87      try {
88        Thread.currentThread().getContextClassLoader().loadClass(codecClassName);
89        return true;
90      } catch (Exception ex) {
91        return false;
92      }
93    }
94  
95    /**
96     * Verify CompressionTest.testCompression() on a native codec.
97     */
98    private void nativeCodecTest(String codecName, String libName, String codecClassName) {
99      if (isCompressionAvailable(codecClassName)) {
100       try {
101         if (libName != null) {
102           System.loadLibrary(libName);
103         }
104 
105         try {
106             Configuration conf = new Configuration();
107             CompressionCodec codec = (CompressionCodec)
108               ReflectionUtils.newInstance(conf.getClassByName(codecClassName), conf);
109 
110             DataOutputBuffer compressedDataBuffer = new DataOutputBuffer();
111             CompressionOutputStream deflateFilter = codec.createOutputStream(compressedDataBuffer);
112 
113             byte[] data = new byte[1024];
114             DataOutputStream deflateOut = new DataOutputStream(new BufferedOutputStream(deflateFilter));
115             deflateOut.write(data, 0, data.length);
116             deflateOut.flush();
117             deflateFilter.finish();
118 
119             // Codec class, codec nativelib and Hadoop nativelib with codec JNIs are present
120             assertTrue(CompressionTest.testCompression(codecName));
121         } catch (UnsatisfiedLinkError e) {
122           // Hadoop nativelib does not have codec JNIs.
123           // cannot assert the codec here because the current logic of
124           // CompressionTest checks only classloading, not the codec
125           // usage.
126           LOG.debug("No JNI for codec '" + codecName + "' " + e.getMessage());
127         } catch (Exception e) {
128           LOG.error(codecName, e);
129         }
130       } catch (UnsatisfiedLinkError e) {
131         // nativelib is not available
132         LOG.debug("Native lib not available: " + codecName);
133         assertFalse(CompressionTest.testCompression(codecName));
134       }
135     } else {
136       // Compression Codec class is not available
137       LOG.debug("Codec class not available: " + codecName);
138       assertFalse(CompressionTest.testCompression(codecName));
139     }
140   }
141 }
142