/**
* Copyright 2015 StreamSets Inc.
*
* Licensed under the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.streamsets.datacollector.cluster;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Files;
import com.streamsets.datacollector.cluster.TarFileCreator;
import com.streamsets.pipeline.api.impl.Utils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.kamranzafar.jtar.TarEntry;
import org.kamranzafar.jtar.TarInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.zip.GZIPInputStream;
public class TestTarFileCreator {
private File tempDir;
@Before
public void setup() throws IOException {
tempDir = Files.createTempDir();
}
@After
public void tearDown() {
if (tempDir != null) {
FileUtils.deleteQuietly(tempDir);
}
}
@Test(expected = IllegalStateException.class)
public void testCreateEtcTarGzDirDoesNotExist() throws Exception {
File etcDir = new File(tempDir, "etc");
File tarFile = new File(tempDir, "etc.tar.gz");
TarFileCreator.createTarGz(etcDir, tarFile);
}
@Test(expected = IllegalStateException.class)
public void testCreateEtcTarGzDirIsEmpty() throws Exception {
File etcDir = new File(tempDir, "etc");
Assert.assertTrue(etcDir.mkdir());
File tarFile = new File(tempDir, "etc.tar.gz");
TarFileCreator.createTarGz(etcDir, tarFile);
}
@Test(expected = IllegalStateException.class)
public void testCreateEtcTarGzFileDirIsNotReadable() throws Exception {
File etcDir = new File(tempDir, "etc");
Assert.assertTrue(etcDir.mkdir());
etcDir.setReadable(false);
File tarFile = new File(tempDir, "etc.tar.gz");
TarFileCreator.createTarGz(etcDir, tarFile);
}
@Test
public void testCreateEtcTarGz() throws Exception {
File etcDir = new File(tempDir, "etc");
Assert.assertTrue(etcDir.mkdir());
createJar(etcDir);
createJar(etcDir);
File tarFile = new File(tempDir, "etc.tar.gz");
TarFileCreator.createTarGz(etcDir, tarFile);
TarInputStream tis = new TarInputStream(new GZIPInputStream(new FileInputStream(tarFile)));
readJar(tis);
readJar(tis);
}
@Test
public void testCreateLibsTarGz() throws Exception {
File apiLibDir = new File(tempDir, "api-lib");
File containerLibDir = new File(tempDir, "container-lib");
File streamsetsLibsDir = new File(tempDir, "streamsets-libs");
File userLibsDir = new File(tempDir, "user-libs");
URLClassLoader apiCl = new URLClassLoader(new URL[]{createJar(apiLibDir).toURI().toURL()});
URLClassLoader containerCL = new URLClassLoader(new URL[]{createJar(containerLibDir).toURI().toURL()});
Map<String, List<URL>> streamsetsLibsCl = new LinkedHashMap<>();
Map<String, List<URL>> userLibsCL = new LinkedHashMap<>();
streamsetsLibsCl.put("abc123", ImmutableList.copyOf(new URLClassLoader(new URL[]{createJar(new File(streamsetsLibsDir, "abc123"))
.toURI().toURL()}).getURLs()));
streamsetsLibsCl.put("abc456", ImmutableList.copyOf(new URLClassLoader(new URL[]{createJar(new File(streamsetsLibsDir, "abc456"))
.toURI().toURL()}).getURLs()));
userLibsCL.put("yxz456", ImmutableList.copyOf(new URLClassLoader(new URL[]{createJar(new File(userLibsDir, "yxz456"))
.toURI().toURL(), createJar(new File(tempDir, "yxz789")).toURI().toURL()}).getURLs()));
File staticWebDir = new File(tempDir, "static-web-dir");
Assert.assertTrue(staticWebDir.mkdir());
createJar(new File(staticWebDir, "subdir"));
File tarFile = new File(tempDir, "libs.tar.gz");
TarFileCreator.createLibsTarGz(ImmutableList.copyOf(apiCl.getURLs()), ImmutableList.copyOf(containerCL.getURLs()),
streamsetsLibsCl, userLibsCL, staticWebDir, tarFile);
TarInputStream tis = new TarInputStream(new GZIPInputStream(new FileInputStream(tarFile)));
readDir("api-lib/", tis);
readJar(tis);
readDir("container-lib/", tis);
readJar(tis);
readDir("streamsets-libs/", tis);
readDir("streamsets-libs/abc123/", tis);
readDir("streamsets-libs/abc123/lib/", tis);
readJar(tis);
readDir("streamsets-libs/abc456/", tis);
readDir("streamsets-libs/abc456/lib/", tis);
readJar(tis);
readDir("user-libs/", tis);
readDir("user-libs/yxz456/", tis);
readDir("user-libs/yxz456/lib/", tis);
readJar(tis);
readJar(tis);
readJar(tis);
readDir("libs-common-lib/", tis);
}
private static void readJar(TarInputStream tis) throws IOException {
TarEntry fileEntry = readFile(tis);
byte[] buffer = new byte[8192 * 8];
int read = IOUtils.read(tis, buffer);
JarInputStream jar = new JarInputStream(new ByteArrayInputStream(buffer, 0 , read));
JarEntry entry = jar.getNextJarEntry();
Assert.assertNotNull(Utils.format("Read {} bytes and found a null entry", read), entry);
Assert.assertEquals("sample.txt", entry.getName());
read = IOUtils.read(jar, buffer);
Assert.assertEquals(FilenameUtils.getBaseName(fileEntry.getName()),
new String(buffer, 0, read, StandardCharsets.UTF_8));
}
private static TarEntry readFile(TarInputStream tis) throws IOException {
return readDir(null, tis);
}
private static TarEntry readDir(String name, TarInputStream tis) throws IOException {
TarEntry entry = tis.getNextEntry();
if (name == null) {
Assert.assertNotNull("Entry should be not null", entry);
} else {
Assert.assertNotNull(Utils.format("Entry {} should be not null", name), entry);
Assert.assertEquals(name, entry.getName());
}
return entry;
}
private File createJar(File parentDir) throws IOException {
if (parentDir.isFile()) {
parentDir.delete();
}
parentDir.mkdirs();
Assert.assertTrue(parentDir.isDirectory());
String uuid = UUID.randomUUID().toString();
File jar = new File(parentDir, uuid + ".jar");
JarOutputStream out = new JarOutputStream(new FileOutputStream(jar));
JarEntry entry = new JarEntry("sample.txt");
out.putNextEntry(entry);
out.write(uuid.getBytes(StandardCharsets.UTF_8));
out.closeEntry();
out.close();
return jar;
}
}