fi.jumi.test.BuildTest.java Source code

Java tutorial

Introduction

Here is the source code for fi.jumi.test.BuildTest.java

Source

// Copyright  2011-2013, Esko Luontola <www.orfjackal.net>
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package fi.jumi.test;

import fi.luontola.buildtest.*;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;

import javax.annotation.concurrent.*;
import java.io.*;
import java.util.*;

import static fi.luontola.buildtest.AsmMatchers.*;
import static fi.luontola.buildtest.AsmUtils.annotatedWithOneOf;
import static java.util.Arrays.asList;
import static org.fest.assertions.Assertions.assertThat;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.Assume.assumeTrue;

@RunWith(Parameterized.class)
public class BuildTest {

    private static final String MANIFEST = "META-INF/MANIFEST.MF";
    private static final String POM_FILES = "META-INF/maven/fi.jumi.actors/";
    private static final String BASE_PACKAGE = "fi/jumi/";

    private static final String[] DOES_NOT_NEED_JSR305_ANNOTATIONS = {
            // ignore, because the ThreadSafetyAgent anyways won't check itself
            "fi/jumi/threadsafetyagent/", };

    private final String artifactId;
    private final Integer[] expectedClassVersion;
    private final List<String> expectedDependencies;
    private final List<String> expectedContents;
    private final Deprecations expectedDeprecations;

    public BuildTest(String artifactId, List<Integer> expectedClassVersion, List<String> expectedDependencies,
            List<String> expectedContents, Deprecations expectedDeprecations) {
        this.artifactId = artifactId;
        this.expectedClassVersion = expectedClassVersion.toArray(new Integer[expectedClassVersion.size()]);
        this.expectedDependencies = expectedDependencies;
        this.expectedContents = expectedContents;
        this.expectedDeprecations = expectedDeprecations;
    }

    @Parameters(name = "{0}")
    public static Collection<Object[]> data() {
        return asList(new Object[][] {
                { "jumi-actors", asList(Opcodes.V1_6), asList(),
                        asList(MANIFEST, POM_FILES, BASE_PACKAGE + "actors/"), new Deprecations() },

                { "thread-safety-agent", asList(Opcodes.V1_5, Opcodes.V1_6), asList(),
                        asList(MANIFEST, POM_FILES, BASE_PACKAGE + "threadsafetyagent/"), new Deprecations() }, });
    }

    @Test
    public void pom_contains_only_allowed_dependencies() throws Exception {
        List<String> dependencies = MavenUtils.getRuntimeDependencies(getProjectPom());
        assertThat("dependencies of " + artifactId, dependencies, is(expectedDependencies));
    }

    @Test
    public void jar_contains_only_allowed_files() throws Exception {
        File jarFile = getProjectJar();
        JarUtils.assertContainsOnly(jarFile, expectedContents);
    }

    @Test
    public void jar_contains_a_pom_properties_with_the_maven_artifact_identifiers() throws IOException {
        Properties p = getPomProperties();
        assertThat("groupId", p.getProperty("groupId"), is("fi.jumi.actors"));
        assertThat("artifactId", p.getProperty("artifactId"), is(artifactId));
        assertThat("version", p.getProperty("version"), is(TestEnvironment.VERSION_NUMBERING));
    }

    @Test
    public void release_jar_contains_build_properties_with_the_Git_revision_ID() throws IOException {
        assumeReleaseBuild();

        Properties p = getBuildProperties();
        assertThat(p.getProperty("revision")).as("revision").matches("[0-9a-f]{40}");
    }

    @Test
    public void none_of_the_artifacts_may_have_dependencies_to_external_libraries() {
        for (String dependency : expectedDependencies) {
            assertThat("artifact " + artifactId, dependency, startsWith("fi.jumi.actors:"));
        }
    }

    @Test
    public void none_of_the_artifacts_may_contain_classes_from_external_libraries_without_shading_them() {
        for (String content : expectedContents) {
            assertThat("artifact " + artifactId, content, Matchers.<String>either(startsWith(BASE_PACKAGE))
                    .or(startsWith(POM_FILES)).or(startsWith(MANIFEST)));
        }
    }

    @Test
    public void all_classes_must_use_the_specified_bytecode_version() throws IOException {
        CompositeMatcher<ClassNode> matcher = newClassNodeCompositeMatcher()
                .assertThatIt(hasClassVersion(isOneOf(expectedClassVersion)));

        JarUtils.checkAllClasses(getProjectJar(), matcher);
    }

    @Test
    public void all_classes_must_be_annotated_with_JSR305_concurrent_annotations() throws Exception {
        CompositeMatcher<ClassNode> matcher = newClassNodeCompositeMatcher().excludeIf(is(anInterface()))
                .excludeIf(is(syntheticClass())).excludeIf(nameStartsWithOneOf(DOES_NOT_NEED_JSR305_ANNOTATIONS))
                .assertThatIt(is(annotatedWithOneOf(Immutable.class, NotThreadSafe.class, ThreadSafe.class)));

        JarUtils.checkAllClasses(getProjectJar(), matcher);
    }

    @Test
    public void deprecated_methods_are_removed_after_the_transition_period() throws IOException {
        expectedDeprecations.verify(new ClassesInJarFile(getProjectJar()));
    }

    // helper methods

    private File getProjectPom() throws IOException {
        return TestEnvironment.ARTIFACTS.getProjectPom(artifactId);
    }

    private File getProjectJar() throws IOException {
        return TestEnvironment.ARTIFACTS.getProjectJar(artifactId);
    }

    private void assumeReleaseBuild() throws IOException {
        String version = getPomProperties().getProperty("version");
        assumeTrue(TestEnvironment.VERSION_NUMBERING.isRelease(version));
    }

    private Properties getBuildProperties() throws IOException {
        return getMavenArtifactProperties(getProjectJar(), "build.properties");
    }

    private Properties getPomProperties() throws IOException {
        return getMavenArtifactProperties(getProjectJar(), "pom.properties");
    }

    private Properties getMavenArtifactProperties(File jarFile, String filename) {
        return JarUtils.getProperties(jarFile, POM_FILES + artifactId + "/" + filename);
    }
}