diff --git a/pom.xml b/pom.xml index 0efa0ba..e246767 100644 --- a/pom.xml +++ b/pom.xml @@ -1,280 +1,292 @@ - + - - - org.jboss - jboss-parent - 21 - - + + + org.jboss + jboss-parent + 21 + + - - 4.0.0 + 4.0.0 - - org.jboss.arquillian.extension - arquillian-jacoco - 1.0.0.Final-SNAPSHOT - Arquillian Extension Jacoco - Jacoco integration to add code coverage to Arquillian + org.jboss.arquillian.extension + arquillian-jacoco + 1.0.0.Final-SNAPSHOT + Arquillian Extension Jacoco + Jacoco integration to add code coverage to Arquillian - - - - 1.1.11.Final - 0.7.7.201606060606 + + 1.1.11.Final + 0.7.7.201606060606 - - 8.2.1.Final - 1.2 - 1.0.0.Final + 8.2.1.Final + 1.2 - - 1.5 - 1.5 - 1.5 + 1.0.0.Final - ${project.build.directory}/wildfly-${version.wildfly} - + 1.10.19 + 2.5.0 - - - - org.jboss.arquillian - arquillian-bom - ${version.arquillian_core} - pom - import - - - org.jboss.arquillian - arquillian-build - ${version.arquillian_core} - pom - import - - - + + 1.5 + 1.5 + 1.5 - + ${project.build.directory}/wildfly-${version.wildfly} + + + - - org.jboss.arquillian.container - arquillian-container-spi - provided - - - org.jboss.arquillian.container - arquillian-container-test-spi - provided - - - org.jboss.shrinkwrap - shrinkwrap-api - compile - + + org.jboss.arquillian + arquillian-bom + ${version.arquillian_core} + pom + import + + + org.jboss.arquillian + arquillian-build + ${version.arquillian_core} + pom + import + + + - - org.jacoco - org.jacoco.core - ${version.jacoco} - provided - + + + + org.jboss.arquillian.container + arquillian-container-spi + provided + + + org.jboss.arquillian.container + arquillian-container-test-spi + provided + + + org.jboss.shrinkwrap + shrinkwrap-api + compile + - - - org.jboss.arquillian.junit - arquillian-junit-container - test - - - org.jboss.arquillian.protocol - arquillian-protocol-servlet - test - - - org.jboss.shrinkwrap.resolver - shrinkwrap-resolver-depchain - pom - test - + + org.jacoco + org.jacoco.core + ${version.jacoco} + provided + - - junit - junit - test - + + + org.jboss.arquillian.junit + arquillian-junit-container + test + + + org.jboss.arquillian.protocol + arquillian-protocol-servlet + test + + + org.jboss.shrinkwrap.resolver + shrinkwrap-resolver-depchain + pom + test + + + + junit + junit + test + + + javax.enterprise + cdi-api + ${version.cdi-api} + test + + + org.jboss.spec.javax.ejb + jboss-ejb-api_3.2_spec + ${version.ejb3} + test + + + org.mockito + mockito-all + ${version.mockito} + test + + + org.assertj + assertj-core + ${version.assertj} + test + + + + + + unit + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org/jboss/arquillian/extension/jacoco/test/unit/* + + + + + + + + managed + + true + + - javax.enterprise - cdi-api - ${version.cdi-api} - test + org.wildfly + wildfly-arquillian-container-managed + ${version.wildfly} + test + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack + process-test-classes + + unpack + + + + + org.wildfly + wildfly-dist + ${version.wildfly} + zip + false + ${project.build.directory} + + + + + + + + + + + remote + - org.jboss.spec.javax.ejb - jboss-ejb-api_3.2_spec - ${version.ejb3} - test + org.wildfly + wildfly-arquillian-container-remote + ${version.wildfly} + test - - - - - unit - - - - org.apache.maven.plugins - maven-surefire-plugin - - - org/jboss/arquillian/extension/jacoco/test/unit/* - - - - - - - - managed - - true - - - - org.wildfly - wildfly-arquillian-container-managed - ${version.wildfly} - test - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack - process-test-classes - - unpack - - - - - org.wildfly - wildfly-dist - ${version.wildfly} - zip - false - ${project.build.directory} - - - - - - - - - - - remote - - - org.wildfly - wildfly-arquillian-container-remote - ${version.wildfly} - test - - - - - integration - - true - - - - - org.jacoco - jacoco-maven-plugin - ${version.jacoco} - - - - prepare-agent - - - - report - prepare-package - - report - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - integration-tests - test - - test - - - - ${wildfly_home} - - false - - org/jboss/arquillian/extension/jacoco/test/unit/* - org/jboss/arquillian/extension/jacoco/test/integration/* - - - - - - verify-output-tests - test - - test - - - false - - org/jboss/arquillian/extension/jacoco/test/verify/* - - - - - - - - - - - + + + + integration + + true + + - - maven-release-plugin + + org.jacoco + jacoco-maven-plugin + ${version.jacoco} + + + + prepare-agent + + + + report + prepare-package + + report + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + integration-tests + test + + test + + + + ${wildfly_home} + + false + + org/jboss/arquillian/extension/jacoco/test/unit/* + org/jboss/arquillian/extension/jacoco/test/integration/* + + + + + + verify-output-tests + test + + test + - true - false - true + false + + org/jboss/arquillian/extension/jacoco/test/verify/* + - + + + - + + + + + + + + maven-release-plugin + + true + false + true + + + + diff --git a/src/main/java/org/jboss/arquillian/extension/jacoco/client/ArchiveInstrumenter.java b/src/main/java/org/jboss/arquillian/extension/jacoco/client/ArchiveInstrumenter.java new file mode 100644 index 0000000..e2f642f --- /dev/null +++ b/src/main/java/org/jboss/arquillian/extension/jacoco/client/ArchiveInstrumenter.java @@ -0,0 +1,58 @@ +package org.jboss.arquillian.extension.jacoco.client; + +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ArchivePath; +import org.jboss.shrinkwrap.api.Filter; +import org.jboss.shrinkwrap.api.Filters; +import org.jboss.shrinkwrap.api.Node; +import org.jboss.shrinkwrap.api.asset.Asset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; + +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ArchiveInstrumenter +{ + + private static final Logger LOGGER = Logger.getLogger(JaCoCoApplicationArchiveProcessor.class.getName()); + + private final SignatureRemover signatureRemover; + + public ArchiveInstrumenter(SignatureRemover signatureRemover) + { + this.signatureRemover = signatureRemover; + } + + public void processArchive(Archive archive, Filter filter) + { + instrument(archive, archive.getContent(filter)); + signatureRemover.removeSignatures(archive); + + final Map jars = archive.getContent(Filters.include(".*\\.(jar|war|rar|ear)$")); + for (Map.Entry entry : jars.entrySet()) + { + // Should have used genericArchive, but with GenericArchive we need + // to specify a ArchiveFormat and that trigger this SHRINKWRAP-474 + final JavaArchive subArchive = archive.getAsType(JavaArchive.class, entry.getKey()); + if (subArchive == null) // [ARQ-1931] Asset is null which means we are dealing with the directory + { + LOGGER.log(Level.WARNING, String.format("directory path %s ends one of the suffixes: [.ear, .war, .rar, .jar]", entry.getValue())); + } + else + { + processArchive(subArchive, filter); + } + } + } + + private void instrument(Archive archive, Map classes) + { + for (Map.Entry entry : classes.entrySet()) + { + final Asset original = entry.getValue().getAsset(); + archive.delete(entry.getKey()); + archive.add(new InstrumentedAsset(original), entry.getKey()); + } + } +} diff --git a/src/main/java/org/jboss/arquillian/extension/jacoco/client/CoverageDataReceiver.java b/src/main/java/org/jboss/arquillian/extension/jacoco/client/CoverageDataReceiver.java index 923d037..1bbcd17 100644 --- a/src/main/java/org/jboss/arquillian/extension/jacoco/client/CoverageDataReceiver.java +++ b/src/main/java/org/jboss/arquillian/extension/jacoco/client/CoverageDataReceiver.java @@ -1,12 +1,5 @@ package org.jboss.arquillian.extension.jacoco.client; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.UUID; - import org.jacoco.core.data.ExecutionData; import org.jacoco.core.data.ExecutionDataReader; import org.jacoco.core.data.ExecutionDataStore; @@ -16,6 +9,13 @@ import org.jboss.arquillian.core.api.annotation.Observes; import org.jboss.arquillian.extension.jacoco.CoverageDataCommand; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.UUID; + public class CoverageDataReceiver { public void storeCoverageData(@Observes CoverageDataCommand coverageDataCommandEvent) @@ -43,7 +43,7 @@ private void copyToAgentExecutionStore(ExecutionDataStore dataStore) throws Exce Field f = UUID.class.getDeclaredField("$jacocoAccess"); Object executor = f.get(null); - Method m = executor.getClass().getDeclaredMethod("getProbes", new Class[] {Object[].class}); + Method m = executor.getClass().getDeclaredMethod("getProbes", Object[].class); m.setAccessible(true); for (ExecutionData data : dataStore.getContents()) { @@ -62,7 +62,6 @@ private void copyToAgentExecutionStore(ExecutionDataStore dataStore) throws Exce private void read(InputStream stream, IExecutionDataVisitor executionDataVisitor, ISessionInfoVisitor sessionVisitor) - throws IOException { ExecutionDataReader reader = new ExecutionDataReader(stream); diff --git a/src/main/java/org/jboss/arquillian/extension/jacoco/client/InstrumenterAsset.java b/src/main/java/org/jboss/arquillian/extension/jacoco/client/InstrumentedAsset.java similarity index 83% rename from src/main/java/org/jboss/arquillian/extension/jacoco/client/InstrumenterAsset.java rename to src/main/java/org/jboss/arquillian/extension/jacoco/client/InstrumentedAsset.java index 5d5e351..d8f5311 100644 --- a/src/main/java/org/jboss/arquillian/extension/jacoco/client/InstrumenterAsset.java +++ b/src/main/java/org/jboss/arquillian/extension/jacoco/client/InstrumentedAsset.java @@ -16,14 +16,14 @@ */ package org.jboss.arquillian.extension.jacoco.client; -import java.io.ByteArrayInputStream; -import java.io.InputStream; - import org.jacoco.core.instr.Instrumenter; import org.jacoco.core.runtime.IRuntime; import org.jboss.arquillian.extension.jacoco.container.ArquillianRuntime; import org.jboss.shrinkwrap.api.asset.Asset; +import java.io.ByteArrayInputStream; +import java.io.InputStream; + /** * Instrument the underlying Class using the Jacoco Runtime. * @@ -32,13 +32,13 @@ * @author Aslak Knutsen * @version $Revision: $ */ -public class InstrumenterAsset implements Asset +public class InstrumentedAsset implements Asset { - private Asset asset; + private final Asset asset; public static final String EX_STRING = "arquillian"; - public InstrumenterAsset(Asset asset) + public InstrumentedAsset(Asset asset) { this.asset = asset; } @@ -50,10 +50,9 @@ public InputStream openStream() { try { - IRuntime runtime = ArquillianRuntime.getInstance(); - Instrumenter instrumenter = new Instrumenter(runtime); - byte[] instrumented = instrumenter.instrument(asset.openStream(), EX_STRING); - + final IRuntime runtime = ArquillianRuntime.getInstance(); + final Instrumenter instrumenter = new Instrumenter(runtime); + final byte[] instrumented = instrumenter.instrument(asset.openStream(), EX_STRING); return new ByteArrayInputStream(instrumented); } catch (Exception e) diff --git a/src/main/java/org/jboss/arquillian/extension/jacoco/client/ApplicationArchiveInstrumenter.java b/src/main/java/org/jboss/arquillian/extension/jacoco/client/JaCoCoApplicationArchiveProcessor.java similarity index 50% rename from src/main/java/org/jboss/arquillian/extension/jacoco/client/ApplicationArchiveInstrumenter.java rename to src/main/java/org/jboss/arquillian/extension/jacoco/client/JaCoCoApplicationArchiveProcessor.java index 705cc2f..26784d9 100644 --- a/src/main/java/org/jboss/arquillian/extension/jacoco/client/ApplicationArchiveInstrumenter.java +++ b/src/main/java/org/jboss/arquillian/extension/jacoco/client/JaCoCoApplicationArchiveProcessor.java @@ -16,63 +16,29 @@ */ package org.jboss.arquillian.extension.jacoco.client; -import java.util.Map; -import java.util.Map.Entry; - import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; import org.jboss.arquillian.core.api.Instance; import org.jboss.arquillian.core.api.annotation.Inject; import org.jboss.arquillian.test.spi.TestClass; import org.jboss.shrinkwrap.api.Archive; -import org.jboss.shrinkwrap.api.ArchivePath; -import org.jboss.shrinkwrap.api.Filter; -import org.jboss.shrinkwrap.api.Filters; -import org.jboss.shrinkwrap.api.Node; -import org.jboss.shrinkwrap.api.asset.Asset; -import org.jboss.shrinkwrap.api.spec.JavaArchive; /** * Instrument all Classes (or their subset if found in the User defined - * - * @Deployment. - * + * * @author Aslak Knutsen * @author Lukas Krejci - * * @version $Revision: $ + * @Deployment. */ -public class ApplicationArchiveInstrumenter implements - ApplicationArchiveProcessor +public class JaCoCoApplicationArchiveProcessor implements ApplicationArchiveProcessor { + @Inject private Instance config; - private void processArchive(Archive archive, Filter filter) - { - SignatureRemover signatureRemover = new SignatureRemover(); - - Map classes = archive.getContent(filter); - - for (Entry entry : classes.entrySet()) - { - Asset original = entry.getValue().getAsset(); - archive.delete(entry.getKey()); - archive.add(new InstrumenterAsset(original), entry.getKey()); - } - signatureRemover.removeSignatures(archive); - // Process sub-archives recursively - Map jars = archive.getContent(Filters.include(".*\\.(jar|war|rar|ear)$")); - for (Entry entry : jars.entrySet()) - { - // Should have used genericArchive, but with GenericArchive we need - // to specify a ArchiveFormat and that trigger this SHRINKWRAP-474 - JavaArchive subArchive = archive.getAsType(JavaArchive.class, entry.getKey()); - processArchive(subArchive, filter); - } - } - public void process(Archive applicationArchive, TestClass testClass) { - processArchive(applicationArchive, config.get().getClassFilter()); + new ArchiveInstrumenter(new SignatureRemover()).processArchive(applicationArchive, config.get().getClassFilter()); } + } diff --git a/src/main/java/org/jboss/arquillian/extension/jacoco/client/JacocoConfiguration.java b/src/main/java/org/jboss/arquillian/extension/jacoco/client/JacocoConfiguration.java index 938375d..d3a0451 100644 --- a/src/main/java/org/jboss/arquillian/extension/jacoco/client/JacocoConfiguration.java +++ b/src/main/java/org/jboss/arquillian/extension/jacoco/client/JacocoConfiguration.java @@ -18,6 +18,10 @@ package org.jboss.arquillian.extension.jacoco.client; +import org.jboss.shrinkwrap.api.ArchivePath; +import org.jboss.shrinkwrap.api.Filter; +import org.jboss.shrinkwrap.api.Filters; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -26,23 +30,21 @@ import java.util.Map; import java.util.UUID; -import org.jboss.shrinkwrap.api.ArchivePath; -import org.jboss.shrinkwrap.api.Filter; -import org.jboss.shrinkwrap.api.Filters; - /** * @author Lukas Krejci */ public class JacocoConfiguration { + public static final Filter ALL_CLASSES = Filters.include(".*\\.class"); + private static final String INCLUDES_PROPERTY = "includes"; public static final String INCLUDES_DEFAULT_VALUE = null; private static final String EXCLUDES_PROPERTY = "excludes"; public static final String EXCLUDES_DEFAULT_VALUE = null; private static final String APPEND_ASM_LIBRARY_PROPERTY = "appendAsmLibrary"; - private static final String APPEND_ASM_LIBRARY_DEFAULT = "true"; + private static final String APPEND_ASM_LIBRARY_DEFAULT = "true"; private static final String SEPARATOR = "\\s*;\\s*"; private List includes; @@ -98,11 +100,11 @@ public static JacocoConfiguration fromMap(Map map) ConfigMap c = new ConfigMap(map); String incls = c.get(INCLUDES_PROPERTY, INCLUDES_DEFAULT_VALUE); - ret.includes = incls == null ? Collections. emptyList() : Arrays + ret.includes = incls == null ? Collections.emptyList() : Arrays .asList(incls.split(SEPARATOR)); String excls = c.get(EXCLUDES_PROPERTY, EXCLUDES_DEFAULT_VALUE); - ret.excludes = excls == null ? Collections. emptyList() : Arrays + ret.excludes = excls == null ? Collections.emptyList() : Arrays .asList(excls.split(SEPARATOR)); ret.composedFilter = ret.composeFilter(); @@ -130,13 +132,13 @@ public Filter getClassFilter() public boolean isAppendAsmLibrary() { - return appendAsmLibrary; + return appendAsmLibrary; } private Filter composeFilter() { List> filters = new ArrayList>(); - filters.add(Filters.include(".*\\.class")); + filters.add(ALL_CLASSES); for (String include : getIncludeRegexps()) { @@ -166,9 +168,10 @@ private List convertToRegexps(List patterns) if (patterns.isEmpty()) { return patterns; - } else + } + else { - ArrayList ret = new ArrayList(patterns.size()); + final List ret = new ArrayList(patterns.size()); for (String regexp : patterns) { regexp = regexp.replace(".", "\\/").replace("*", ".*") @@ -186,8 +189,7 @@ public static boolean isJacocoAgentActive() try { UUID.class.getDeclaredField("$jacocoAccess"); - } - catch (Exception e) + } catch (Exception e) { return false; } diff --git a/src/main/java/org/jboss/arquillian/extension/jacoco/client/JacocoExtension.java b/src/main/java/org/jboss/arquillian/extension/jacoco/client/JacocoExtension.java index 33b7b65..921dd7f 100644 --- a/src/main/java/org/jboss/arquillian/extension/jacoco/client/JacocoExtension.java +++ b/src/main/java/org/jboss/arquillian/extension/jacoco/client/JacocoExtension.java @@ -35,7 +35,7 @@ public void register(ExtensionBuilder builder) if(JacocoConfiguration.isJacocoAgentActive()) { builder.service(AuxiliaryArchiveAppender.class, JacocoArchiveAppender.class) - .service(ApplicationArchiveProcessor.class, ApplicationArchiveInstrumenter.class); + .service(ApplicationArchiveProcessor.class, JaCoCoApplicationArchiveProcessor.class); builder.observer(CoverageDataReceiver.class) .observer(JacocoConfigurator.class); diff --git a/src/main/java/org/jboss/arquillian/extension/jacoco/client/SignatureRemover.java b/src/main/java/org/jboss/arquillian/extension/jacoco/client/SignatureRemover.java index 269bf50..3854685 100644 --- a/src/main/java/org/jboss/arquillian/extension/jacoco/client/SignatureRemover.java +++ b/src/main/java/org/jboss/arquillian/extension/jacoco/client/SignatureRemover.java @@ -15,7 +15,7 @@ import org.jboss.shrinkwrap.api.asset.Asset; /** - * Signed jars must have their signatures removed. Since {@link InstrumenterAsset} only deals with classes we must actually + * Signed jars must have their signatures removed. Since {@link InstrumentedAsset} only deals with classes we must actually * perform the duties of {@link org.jacoco.core.internal.instr.SignatureRemover} ourselves * * @see org.jacoco.core.internal.instr.SignatureRemover diff --git a/src/main/java/org/jboss/arquillian/extension/jacoco/container/ArquillianRuntime.java b/src/main/java/org/jboss/arquillian/extension/jacoco/container/ArquillianRuntime.java index 8b9fcca..f51a593 100644 --- a/src/main/java/org/jboss/arquillian/extension/jacoco/container/ArquillianRuntime.java +++ b/src/main/java/org/jboss/arquillian/extension/jacoco/container/ArquillianRuntime.java @@ -16,13 +16,14 @@ */ package org.jboss.arquillian.extension.jacoco.container; -import java.util.UUID; import org.jacoco.core.internal.instr.InstrSupport; import org.jacoco.core.runtime.IRuntime; import org.jacoco.core.runtime.RuntimeData; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; +import java.util.UUID; + /** * ArquillianRuntime * @@ -41,60 +42,59 @@ public static synchronized ArquillianRuntime getInstance() } return runtime; } - - private RuntimeData runtimeData; + + private RuntimeData runtimeData; /** - * + * */ private ArquillianRuntime() { - runtimeData = new RuntimeData(); - runtimeData.setSessionId(UUID.randomUUID().toString()); + runtimeData = new RuntimeData(); + runtimeData.setSessionId(UUID.randomUUID().toString()); } /** * Retrieves the execution probe array for a given class. The passed * {@link Object} array instance is used for parameters and the return value * as follows. Call parameters: - * + *

*

    *
  • args[0]: class id ({@link Long}) *
  • args[1]: vm class name ({@link String}) *
  • args[2]: probe count ({@link Integer}) *
- * + *

* Return value: - * + *

*

    *
  • args[0]: probe array (boolean[]) *
- * - * @param args - * parameter array of length 3 + * + * @param args parameter array of length 3 */ public void swapExecutionData(Object[] args) { final Long classid = (Long) args[0]; final String name = (String) args[1]; - final int probecount = ((Integer) args[2]).intValue(); + final int probecount = (Integer) args[2]; synchronized (runtimeData) { args[0] = runtimeData.getExecutionData(classid, name, probecount).getProbes(); } } - RuntimeData getRuntimeData() + RuntimeData getRuntimeData() { - return runtimeData; + return runtimeData; } - + /* (non-Javadoc) * @see org.jacoco.core.runtime.IRuntime#startup() */ public void startup(RuntimeData rd) throws Exception { - this.runtimeData = rd; + this.runtimeData = rd; } /* (non-Javadoc) @@ -109,7 +109,7 @@ public void shutdown() */ public void reset() { - runtimeData.reset(); + runtimeData.reset(); } /* (non-Javadoc) @@ -122,36 +122,36 @@ public int generateDataAccessor(long classid, String classname, int probecount, // stack[0]: [Ljava/lang/Object; mv.visitInsn(Opcodes.DUP); - + // stack[1]: [Ljava/lang/Object; // stack[0]: [Ljava/lang/Object; - + // 2. Invoke ArquillianRuntime: mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/jboss/arquillian/extension/jacoco/container/ArquillianRuntime", - "getInstance", - "()Lorg/jboss/arquillian/extension/jacoco/container/ArquillianRuntime;"); + "getInstance", + "()Lorg/jboss/arquillian/extension/jacoco/container/ArquillianRuntime;", false); // stack[2]: LArquillianRuntime; // stack[1]: [Ljava/lang/Object; // stack[0]: [Ljava/lang/Object; - + mv.visitInsn(Opcodes.SWAP); // stack[2]: [Ljava/lang/Object; // stack[1]: LArquillianRuntime; // stack[0]: [Ljava/lang/Object; - + // 3. Invoke ArquillianRuntime swapExecutionData, gets the boolean[] in Object[0]: mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/jboss/arquillian/extension/jacoco/container/ArquillianRuntime", "swapExecutionData", - "([Ljava/lang/Object;)V"); - + "([Ljava/lang/Object;)V", false); + // Stack[0]: [Ljava/lang/Object; mv.visitInsn(Opcodes.ICONST_0); mv.visitInsn(Opcodes.AALOAD); mv.visitTypeInsn(Opcodes.CHECKCAST, InstrSupport.DATAFIELD_DESC); - + // Stack[0]: [Z; return 5; @@ -161,18 +161,14 @@ public int generateDataAccessor(long classid, String classname, int probecount, * Generates code that creates the argument array for the * getExecutionData() method. The array instance is left on the * operand stack. The generated code requires a stack size of 5. - * - * @param classid - * class identifier - * @param classname - * VM class name - * @param probecount - * probe count for this class - * @param mv - * visitor to emit generated code + * + * @param classid class identifier + * @param classname VM class name + * @param probecount probe count for this class + * @param mv visitor to emit generated code */ public static void generateArgumentArray(final long classid, final String classname, final int probecount, - final MethodVisitor mv) + final MethodVisitor mv) { mv.visitInsn(Opcodes.ICONST_3); mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); @@ -180,8 +176,8 @@ public static void generateArgumentArray(final long classid, final String classn // Class Id: mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.ICONST_0); - mv.visitLdcInsn(Long.valueOf(classid)); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); + mv.visitLdcInsn(classid); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); mv.visitInsn(Opcodes.AASTORE); // Class Name: @@ -194,7 +190,7 @@ public static void generateArgumentArray(final long classid, final String classn mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.ICONST_2); InstrSupport.push(mv, probecount); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); mv.visitInsn(Opcodes.AASTORE); } } diff --git a/src/main/java/org/jboss/arquillian/extension/jacoco/container/StartCoverageData.java b/src/main/java/org/jboss/arquillian/extension/jacoco/container/StartCoverageData.java index eb3d9fd..f09b5e7 100644 --- a/src/main/java/org/jboss/arquillian/extension/jacoco/container/StartCoverageData.java +++ b/src/main/java/org/jboss/arquillian/extension/jacoco/container/StartCoverageData.java @@ -36,7 +36,7 @@ public class StartCoverageData @SuiteScoped private InstanceProducer runtimeInst; - public void createRuntime(@Observes BeforeSuite event) throws Exception + public void createRuntime(@Observes BeforeSuite event) { IRuntime runtime = ArquillianRuntime.getInstance(); runtimeInst.set(runtime); diff --git a/src/test/java/org/jboss/arquillian/extension/jacoco/test/included/ImportedSubArchive.java b/src/test/java/org/jboss/arquillian/extension/jacoco/test/included/ImportedSubArchive.java index e39a050..3151aac 100644 --- a/src/test/java/org/jboss/arquillian/extension/jacoco/test/included/ImportedSubArchive.java +++ b/src/test/java/org/jboss/arquillian/extension/jacoco/test/included/ImportedSubArchive.java @@ -16,9 +16,11 @@ */ package org.jboss.arquillian.extension.jacoco.test.included; -public class ImportedSubArchive { +public class ImportedSubArchive +{ - public String getName() { - return "A"; - } + public String getName() + { + return "A"; + } } diff --git a/src/test/java/org/jboss/arquillian/extension/jacoco/test/integration/ImportedSubArchiveTestCase.java b/src/test/java/org/jboss/arquillian/extension/jacoco/test/integration/ImportedSubArchiveTestCase.java index c037266..f0154a9 100644 --- a/src/test/java/org/jboss/arquillian/extension/jacoco/test/integration/ImportedSubArchiveTestCase.java +++ b/src/test/java/org/jboss/arquillian/extension/jacoco/test/integration/ImportedSubArchiveTestCase.java @@ -16,13 +16,6 @@ */ package org.jboss.arquillian.extension.jacoco.test.integration; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; - -import javax.inject.Inject; - -import junit.framework.Assert; - import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.extension.jacoco.test.included.ImportedSubArchive; import org.jboss.arquillian.junit.Arquillian; @@ -32,40 +25,48 @@ import org.jboss.shrinkwrap.api.importer.ZipImporter; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; +import javax.inject.Inject; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + /* * Test case to verify we can handle Classes found in archives imported * from a Zip file. Covergae verification is done in VerifyIntegrationCoverageTestCase */ @RunWith(Arquillian.class) -public class ImportedSubArchiveTestCase { +public class ImportedSubArchiveTestCase +{ + + @Deployment + public static WebArchive createImportedArchive() throws Exception + { + WebArchive war = ShrinkWrap.create(WebArchive.class) + .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") + .addClasses(ImportedSubArchiveTestCase.class) + .addAsLibraries( + ShrinkWrap.create(JavaArchive.class) + .addClass(ImportedSubArchive.class) + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml") + ); + + ByteArrayOutputStream target = new ByteArrayOutputStream(); + war.as(ZipExporter.class).exportTo(target); + target.flush(); + + ByteArrayInputStream source = new ByteArrayInputStream(target.toByteArray()); + return ShrinkWrap.create(ZipImporter.class, war.getName()).importFrom(source).as(WebArchive.class); + } - @Deployment - public static WebArchive createImportedArchive() throws Exception { - WebArchive war = ShrinkWrap.create(WebArchive.class) - .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") - .addClasses(ImportedSubArchiveTestCase.class) - .addAsLibraries( - ShrinkWrap.create(JavaArchive.class) - .addClass(ImportedSubArchive.class) - .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml") - ); - - ByteArrayOutputStream target = new ByteArrayOutputStream(); - war.as(ZipExporter.class).exportTo(target); - target.flush(); + @Inject + private ImportedSubArchive bean; - ByteArrayInputStream source = new ByteArrayInputStream(target.toByteArray()); - return ShrinkWrap.create(ZipImporter.class, war.getName()).importFrom(source).as(WebArchive.class); - } - - @Inject - private ImportedSubArchive bean; - - @Test - public void shouldBeInvoked() { - Assert.assertEquals("A", bean.getName()); - } + @Test + public void shouldBeInvoked() + { + Assert.assertEquals("A", bean.getName()); + } } diff --git a/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/ArchiveInstrumenterTest.java b/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/ArchiveInstrumenterTest.java new file mode 100644 index 0000000..cc37f5c --- /dev/null +++ b/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/ArchiveInstrumenterTest.java @@ -0,0 +1,92 @@ +package org.jboss.arquillian.extension.jacoco.test.unit; + +import org.jboss.arquillian.extension.jacoco.client.ArchiveInstrumenter; +import org.jboss.arquillian.extension.jacoco.client.InstrumentedAsset; +import org.jboss.arquillian.extension.jacoco.client.JacocoConfiguration; +import org.jboss.arquillian.extension.jacoco.client.ManifestAsset; +import org.jboss.arquillian.extension.jacoco.client.SignatureRemover; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ArchivePath; +import org.jboss.shrinkwrap.api.Node; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.Asset; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +public class ArchiveInstrumenterTest +{ + + private SignatureRemover signatureRemover; + + private ArchiveInstrumenter instrumenter; + + @Before + public void wire_instrumenter() + { + this.signatureRemover = mock(SignatureRemover.class); + this.instrumenter = new ArchiveInstrumenter(signatureRemover); + } + + @Test + public void should_remove_signatures_from_all_archives_ignoring_directories_named_with_java_archive_suffix() throws Exception + { + // given + final JavaArchive javaArchive = ShrinkWrap.create(JavaArchive.class, "dri.jar").addClass(ArchiveInstrumenterTest.class) + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); + + final EnterpriseArchive enterpriseArchive = ShrinkWrap.create(EnterpriseArchive.class, "test.ear") + .addAsLibraries(javaArchive) + .addAsManifestResource(new StringAsset(""), "application.xml") + // [ARQ-1931] Having directory with `.ear` suffix resulted in NPE + .addAsManifestResource(new StringAsset("sample content"), "dir.ear/pom.properties"); + + // when + instrumenter.processArchive(enterpriseArchive, JacocoConfiguration.ALL_CLASSES); + + // then + verify(signatureRemover, times(2)).removeSignatures(any(Archive.class)); + } + + @Test + public void should_instrument_all_classes_in_the_archive() throws Exception + { + // given + final JavaArchive javaArchive = ShrinkWrap.create(JavaArchive.class, "dri.jar") + .addClasses(ArchiveInstrumenterTest.class, ManifestAsset.class, ArchiveInstrumenter.class) + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); + + // when + instrumenter.processArchive(javaArchive, JacocoConfiguration.ALL_CLASSES); + final List classAssets = extractClassAssets(javaArchive); + + // then + assertThat(classAssets).hasSize(3).hasOnlyElementsOfType(InstrumentedAsset.class); + } + + private List extractClassAssets(JavaArchive javaArchive) + { + final List classAssets = new ArrayList(); + for (Map.Entry entry : javaArchive.getContent(JacocoConfiguration.ALL_CLASSES).entrySet()) + { + classAssets.add(entry.getValue().getAsset()); + } + return classAssets; + } + + +} + diff --git a/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/AuxiliaryArchiveAppenderTestCase.java b/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/AuxiliaryArchiveAppenderTestCase.java new file mode 100644 index 0000000..7a0ae4d --- /dev/null +++ b/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/AuxiliaryArchiveAppenderTestCase.java @@ -0,0 +1,62 @@ +package org.jboss.arquillian.extension.jacoco.test.unit; + +import org.jboss.arquillian.core.api.Instance; +import org.jboss.arquillian.extension.jacoco.client.JacocoArchiveAppender; +import org.jboss.arquillian.extension.jacoco.client.JacocoConfiguration; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; + +public class AuxiliaryArchiveAppenderTestCase +{ + + @Test + public void shouldPackageJacocoByDefault() throws Exception + { + JavaArchive archive = createArchive(JacocoConfiguration.fromMap(new HashMap())); + Assert.assertTrue(archive.contains("org/jacoco/core/JaCoCo.class")); + Assert.assertTrue(archive.contains("org/objectweb/asm/ClassReader.class")); + } + + @Test + public void shouldNotPackageASMIfConfigOptionSet() throws Exception + { + HashMap config = new HashMap(); + config.put("appendAsmLibrary", "false"); + + JavaArchive archive = createArchive(JacocoConfiguration.fromMap(config)); + Assert.assertTrue(archive.contains("org/jacoco/core/JaCoCo.class")); + Assert.assertFalse(archive.contains("org/objectweb/asm/ClassReader.class")); + } + + private JavaArchive createArchive(JacocoConfiguration configuration) + { + return createAppender(configuration).createAuxiliaryArchive().as(JavaArchive.class); + } + + private JacocoArchiveAppender createAppender(JacocoConfiguration configuration) + { + JacocoArchiveAppender appender = new JacocoArchiveAppender(); + appender.setConfig(new DummyInstance(configuration)); + return appender; + } + + private static class DummyInstance implements Instance + { + + private T dummy; + + public DummyInstance(T dummy) + { + this.dummy = dummy; + } + + @Override + public T get() + { + return dummy; + } + } +} \ No newline at end of file diff --git a/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/AxuiliaryArchiveAppenderTestCase.java b/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/AxuiliaryArchiveAppenderTestCase.java deleted file mode 100644 index 7b99d29..0000000 --- a/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/AxuiliaryArchiveAppenderTestCase.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.jboss.arquillian.extension.jacoco.test.unit; - -import java.util.HashMap; - -import org.jboss.arquillian.core.api.Instance; -import org.jboss.arquillian.extension.jacoco.client.JacocoArchiveAppender; -import org.jboss.arquillian.extension.jacoco.client.JacocoConfiguration; -import org.jboss.shrinkwrap.api.spec.JavaArchive; -import org.junit.Assert; -import org.junit.Test; - -public class AxuiliaryArchiveAppenderTestCase { - - @Test - public void shouldPackageJacocoByDefault() throws Exception { - JavaArchive archive = createArchive(JacocoConfiguration.fromMap(new HashMap())); - Assert.assertTrue(archive.contains("org/jacoco/core/JaCoCo.class")); - Assert.assertTrue(archive.contains("org/objectweb/asm/ClassReader.class")); - } - - @Test - public void shouldNotPackageASMIfConfigOptionSet() throws Exception { - HashMap config = new HashMap(); - config.put("appendAsmLibrary", "false"); - - JavaArchive archive = createArchive(JacocoConfiguration.fromMap(config)); - Assert.assertTrue(archive.contains("org/jacoco/core/JaCoCo.class")); - Assert.assertFalse(archive.contains("org/objectweb/asm/ClassReader.class")); - } - - private JavaArchive createArchive(JacocoConfiguration configuration) { - return createAppender(configuration).createAuxiliaryArchive().as(JavaArchive.class); - } - - private JacocoArchiveAppender createAppender(JacocoConfiguration configuration) { - JacocoArchiveAppender appender = new JacocoArchiveAppender(); - appender.setConfig(new DummyInstance(configuration)); - return appender; - } - - private static class DummyInstance implements Instance { - - private T dummy; - - public DummyInstance(T dummy) { - this.dummy = dummy; - } - - @Override - public T get() { - return dummy; - } - } -} \ No newline at end of file diff --git a/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/InstrumentTestCase.java b/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/InstrumentTestCase.java index 0452f4e..071c300 100644 --- a/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/InstrumentTestCase.java +++ b/src/test/java/org/jboss/arquillian/extension/jacoco/test/unit/InstrumentTestCase.java @@ -30,7 +30,7 @@ import org.jacoco.core.data.SessionInfo; import org.jacoco.core.instr.Instrumenter; import org.jacoco.core.runtime.RuntimeData; -import org.jboss.arquillian.extension.jacoco.client.InstrumenterAsset; +import org.jboss.arquillian.extension.jacoco.client.InstrumentedAsset; import org.jboss.arquillian.extension.jacoco.client.SignatureRemover; import org.jboss.arquillian.extension.jacoco.container.ArquillianRuntime; import org.jboss.arquillian.extension.jacoco.test.included.CoverageBean; @@ -76,7 +76,7 @@ public void shouldGetCoverageData() throws Exception ArquillianRuntime runtime = ArquillianRuntime.getInstance(); final Instrumenter instr = new Instrumenter(runtime); - final byte[] instrumented = instr.instrument(getTargetClass(targetName), InstrumenterAsset.EX_STRING); + final byte[] instrumented = instr.instrument(getTargetClass(targetName), InstrumentedAsset.EX_STRING); // Now we're ready to run our instrumented class and need to startup the // runtime first: RuntimeData rd = new RuntimeData(); @@ -107,7 +107,7 @@ public void visitSessionInfo(SessionInfo info) {} // information: final CoverageBuilder coverageBuilder = new CoverageBuilder(); final Analyzer analyzer = new Analyzer(executionData, coverageBuilder); - analyzer.analyzeClass(getTargetClass(targetName), InstrumenterAsset.EX_STRING); + analyzer.analyzeClass(getTargetClass(targetName), InstrumentedAsset.EX_STRING); Assert.assertNotNull(coverageBuilder.getClasses()); Assert.assertEquals(1, coverageBuilder.getClasses().size()); diff --git a/src/test/java/org/jboss/arquillian/extension/jacoco/test/verify/CoverageChecker.java b/src/test/java/org/jboss/arquillian/extension/jacoco/test/verify/CoverageChecker.java index 2bdccd6..b74969d 100644 --- a/src/test/java/org/jboss/arquillian/extension/jacoco/test/verify/CoverageChecker.java +++ b/src/test/java/org/jboss/arquillian/extension/jacoco/test/verify/CoverageChecker.java @@ -34,7 +34,7 @@ */ public final class CoverageChecker { - public static final File DEFAULT_OUTPUT_FILE = new File("target" + File.separator + "jacoco.exec"); + private static final File DEFAULT_OUTPUT_FILE = new File("target" + File.separator + "jacoco.exec"); private CoverageChecker() { } @@ -48,7 +48,7 @@ public static boolean hasCoverageData(File jacocoDataFile, Class... classes) return hasCoverageData(jacocoDataFile, Arrays.asList(classes)); } - public static boolean hasCoverageData(File jacocoDataFile, List> classes) throws IOException + private static boolean hasCoverageData(File jacocoDataFile, List> classes) throws IOException { FileInputStream fin = new FileInputStream(jacocoDataFile);