001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.mapreduce;
019
020import java.io.ByteArrayInputStream;
021import java.io.ByteArrayOutputStream;
022import java.io.File;
023import java.io.FileOutputStream;
024import java.io.FileWriter;
025import java.io.IOException;
026import java.io.OutputStream;
027import java.io.Writer;
028import java.text.MessageFormat;
029import java.util.Properties;
030import java.util.jar.JarInputStream;
031import java.util.jar.JarOutputStream;
032import java.util.jar.Manifest;
033import org.apache.hadoop.hbase.HBaseClassTestRule;
034import org.apache.hadoop.hbase.testclassification.SmallTests;
035import org.junit.Assert;
036import org.junit.ClassRule;
037import org.junit.Test;
038import org.junit.experimental.categories.Category;
039import org.slf4j.LoggerFactory;
040
041/**
042 * This file was forked from hadoop/common/branches/branch-2@1350012.
043 */
044@Category(SmallTests.class)
045public class TestJarFinder {
046
047  @ClassRule
048  public static final HBaseClassTestRule CLASS_RULE =
049      HBaseClassTestRule.forClass(TestJarFinder.class);
050
051  @Test
052  public void testJar() throws Exception {
053
054    //picking a class that is for sure in a JAR in the classpath
055    String jar = JarFinder.getJar(LoggerFactory.class);
056    Assert.assertTrue(new File(jar).exists());
057  }
058
059  private static void delete(File file) throws IOException {
060    if (file.getAbsolutePath().length() < 5) {
061      throw new IllegalArgumentException(
062        MessageFormat.format("Path [{0}] is too short, not deleting",
063                             file.getAbsolutePath()));
064    }
065    if (file.exists()) {
066      if (file.isDirectory()) {
067        File[] children = file.listFiles();
068        if (children != null) {
069          for (File child : children) {
070            delete(child);
071          }
072        }
073      }
074      if (!file.delete()) {
075        throw new RuntimeException(
076          MessageFormat.format("Could not delete path [{0}]",
077                               file.getAbsolutePath()));
078      }
079    }
080  }
081
082  @Test
083  public void testExpandedClasspath() throws Exception {
084    //picking a class that is for sure in a directory in the classpath
085    //in this case the JAR is created on the fly
086    String jar = JarFinder.getJar(TestJarFinder.class);
087    Assert.assertTrue(new File(jar).exists());
088  }
089
090  @Test
091  public void testExistingManifest() throws Exception {
092    File dir = new File(System.getProperty("test.build.dir", "target/test-dir"),
093                        TestJarFinder.class.getName() + "-testExistingManifest");
094    delete(dir);
095    dir.mkdirs();
096
097    File metaInfDir = new File(dir, "META-INF");
098    metaInfDir.mkdirs();
099    File manifestFile = new File(metaInfDir, "MANIFEST.MF");
100    Manifest manifest = new Manifest();
101    OutputStream os = new FileOutputStream(manifestFile);
102    manifest.write(os);
103    os.close();
104
105    File propsFile = new File(dir, "props.properties");
106    Writer writer = new FileWriter(propsFile);
107    new Properties().store(writer, "");
108    writer.close();
109    ByteArrayOutputStream baos = new ByteArrayOutputStream();
110    JarOutputStream zos = new JarOutputStream(baos);
111    JarFinder.jarDir(dir, "", zos);
112    JarInputStream jis =
113      new JarInputStream(new ByteArrayInputStream(baos.toByteArray()));
114    Assert.assertNotNull(jis.getManifest());
115    jis.close();
116  }
117
118  @Test
119  public void testNoManifest() throws Exception {
120    File dir = new File(System.getProperty("test.build.dir", "target/test-dir"),
121                        TestJarFinder.class.getName() + "-testNoManifest");
122    delete(dir);
123    dir.mkdirs();
124    File propsFile = new File(dir, "props.properties");
125    Writer writer = new FileWriter(propsFile);
126    new Properties().store(writer, "");
127    writer.close();
128    ByteArrayOutputStream baos = new ByteArrayOutputStream();
129    JarOutputStream zos = new JarOutputStream(baos);
130    JarFinder.jarDir(dir, "", zos);
131    JarInputStream jis =
132      new JarInputStream(new ByteArrayInputStream(baos.toByteArray()));
133    Assert.assertNotNull(jis.getManifest());
134    jis.close();
135  }
136}