com.infosupport.ellison.core.archive.ApplicationArchiveTest.java Source code

Java tutorial

Introduction

Here is the source code for com.infosupport.ellison.core.archive.ApplicationArchiveTest.java

Source

/*
 * Ellison: EL checker
 * Copyright (C) 2013 Info Support
 * dev@sonar.codehaus.org
 * 
 * Sonar is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 * 
 * Sonar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with Sonar; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
 */
package com.infosupport.ellison.core.archive;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.io.Files;
import com.infosupport.ellison.core.archive.ApplicationArchive;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.annotation.Nullable;
import junitx.util.PrivateAccessor;
import org.apache.commons.lang.RandomStringUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
import static org.mockito.Answers.CALLS_REAL_METHODS;
import static org.mockito.Mockito.*;

/**
 * Tests the {@link com.infosupport.ellison.core.archive.ApplicationArchive} class.
 *
 * @author StefanZ
 */
@RunWith(MockitoJUnitRunner.class)
public class ApplicationArchiveTest {
    private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationArchiveTest.class);
    static File inputJar = null;
    static Collection<String> inputJarContents = null;
    @Mock(answer = CALLS_REAL_METHODS)
    ApplicationArchive applicationArchive;

    @BeforeClass
    public static void setupClass() throws Exception {
        inputJar = new File(ApplicationArchiveTest.class.getResource("/example.jar").toURI());
        inputJarContents = new ArrayList<>();
        File contentsFile = new File(ApplicationArchiveTest.class.getResource("/example.jar.contents").toURI());
        inputJarContents = Files.readLines(contentsFile, Charset.defaultCharset());
    }

    @Before
    public void setupTest() {
        doReturn(inputJar).when(applicationArchive).getApplicationFile();
    }

    /**
     * Tests whether {@link com.infosupport.ellison.core.archive.ApplicationArchive#unpackJar()}
     * actually unpacks an archive (and only once). This is done by asserting that files within the archive exist in
     * the directory the archive was unpacked to.
     */
    @Test
    public void testUnpackJar_Success() throws Exception {
        doReturn(inputJar).when(applicationArchive).getApplicationFile();

        applicationArchive.unpackJar();
        applicationArchive.unpackJar();

        // The JAR should only be unpacked once!
        verify(applicationArchive, times(1)).unpackJarHelper(inputJar);

        for (String inputJarContent : inputJarContents) {
            File content = applicationArchive.getFile(inputJarContent);

            assertThat(content, is(notNullValue()));
            assertThat(content.isDirectory(), is(equalTo(inputJarContent.endsWith("/"))));
        }
    }

    @Test(expected = IOException.class)
    public void testUnpackJar_IOException() throws Exception {
        doReturn(inputJar).when(applicationArchive).getApplicationFile();
        doThrow(IOException.class).when(applicationArchive).unpackJarEntry(Matchers.any(File.class),
                Matchers.any(JarFile.class), Matchers.any(JarEntry.class));

        applicationArchive.unpackJar();
    }

    @Test(expected = SecurityException.class)
    public void testUnpackJar_SecurityException() throws Exception {
        doReturn(inputJar).when(applicationArchive).getApplicationFile();
        doThrow(SecurityException.class).when(applicationArchive).unpackJarEntry(Matchers.any(File.class),
                Matchers.any(JarFile.class), Matchers.any(JarEntry.class));

        applicationArchive.unpackJar();
    }

    @Test(expected = FileNotFoundException.class)
    public void testUnpackJar_FileNotFoundException() throws Exception {
        doReturn(inputJar).when(applicationArchive).getApplicationFile();
        doThrow(FileNotFoundException.class).when(applicationArchive).unpackJarEntry(Matchers.any(File.class),
                Matchers.any(JarFile.class), Matchers.any(JarEntry.class));

        applicationArchive.unpackJar();
    }

    @Test(expected = FileNotFoundException.class)
    public void testGetFile_FileNotFound() throws Exception {
        String randomFileName = null;
        do {
            randomFileName = RandomStringUtils.randomAlphanumeric(10);
        } while (inputJarContents.contains(randomFileName));

        applicationArchive.getFile(randomFileName);
    }

    @Test(expected = SecurityException.class)
    public void testGetFile_NotRelativeFilePathUnix() throws Exception {
        applicationArchive.getFile("/");
    }

    @Test(expected = SecurityException.class)
    public void testGetFile_NotRelativeFilePathWindowsCurrentDrive() throws Exception {
        applicationArchive.getFile("\\");
    }

    @Test(expected = SecurityException.class)
    public void testGetFile_NotRelativeFilePathWindowsDrivePrefix() throws Exception {
        applicationArchive.getFile("C:\\");
    }

    @Test(expected = SecurityException.class)
    public void testGetFile_NotRelativeFilePathWindowsNetwork() throws Exception {
        applicationArchive.getFile("\\\\bla");
    }

    @Test
    public void testFindFilesByGlobPattern_AllClasses() throws Exception {
        applicationArchive.unpackJar();
        final URI unpackedPathURI = ((File) PrivateAccessor.getField(applicationArchive, "unpackedPath")).toURI();
        List<String> expectedClassFileNames = new ArrayList<>(
                Collections2.filter(inputJarContents, new Predicate<String>() {
                    @Override
                    public boolean apply(@Nullable String input) {
                        return input.endsWith(".class");
                    }
                }));
        Collection<URI> actualClassFiles = applicationArchive.findFilesByGlobPattern("com", "*.class");
        List<String> actualClassFileNames = new ArrayList<>(
                Collections2.transform(actualClassFiles, new Function<URI, String>() {
                    @Override
                    public String apply(@Nullable URI input) {
                        return unpackedPathURI.relativize(input).toString();
                    }
                }));

        Collections.sort(expectedClassFileNames);
        Collections.sort(actualClassFileNames);

        assertThat(actualClassFileNames, is(equalTo(expectedClassFileNames)));
    }

    @Test
    public void testFindFilesByGlobPattern_ClassInRoot() throws Exception {
        applicationArchive.unpackJar();

        Collection<URI> foundClassFiles = applicationArchive.findFilesByGlobPattern(null, "*.class", false);

        assertThat(foundClassFiles.size(), is(equalTo(0)));
    }

    @Test(expected = FileNotFoundException.class)
    public void testFindFilesByGlobPattern_NoSuchFile() throws Exception {
        applicationArchive.unpackJar();

        String noSuchFile = null;

        do {
            noSuchFile = RandomStringUtils.random(12);
        } while (inputJarContents.contains(noSuchFile + "/"));

        applicationArchive.findFilesByGlobPattern(noSuchFile, "");
    }

    @Test(expected = IllegalArgumentException.class)
    public void testFindFilesByGlobPattern_NotADirectory() throws Exception {
        applicationArchive.unpackJar();

        URI unpackedPathURI = ((File) PrivateAccessor.getField(applicationArchive, "unpackedPath")).toURI();
        String existingFile = unpackedPathURI
                .relativize(applicationArchive.findFilesByGlobPattern(null, "*").iterator().next()).toString();

        applicationArchive.findFilesByGlobPattern(existingFile, "");
    }

    @Test(expected = SecurityException.class)
    public void testFindFilesByGlobPattern_InsecureBasePathDoubleDot() throws Exception {
        applicationArchive.findFilesByGlobPattern("..", "");
    }

    @Test(expected = SecurityException.class)
    public void testFindFilesByGlobPattern_InsecureBasePathDoubleDotAfterDirectory() throws Exception {
        applicationArchive.findFilesByGlobPattern("bla/..", "");
    }

    @Test
    public void testRelativizePath() throws Exception {
        applicationArchive.unpackJar();
        URI relativePath = URI.create("somefile");
        URI absolutePath = applicationArchive.getUnpackedPath().toURI().resolve(relativePath);

        URI returnedPath = applicationArchive.relativizePath(absolutePath);

        assertThat(returnedPath, is(equalTo(relativePath)));
    }
}