quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.36k stars 2.56k forks source link

io.quarkus:quarkus-jacoco does not work with `QuarkusUnitTest` #23759

Open michael-simons opened 2 years ago

michael-simons commented 2 years ago

Describe the bug

The guide on https://quarkus.io/guides/tests-with-coverage#setting-up-jacoco has improved a lot, the quarkus-jacoco extension is a great idea. I wanted to correctly measure my Neo4j-Migrations extensions (https://github.com/michael-simons/neo4j-migrations/tree/main/neo4j-migrations-quarkus-parent) but the new plugin does not work with QuarkusUnitTest (it fails hard on deploy).

The reason being that outputDirectory in a io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem is null and the JacocoProcessor doesn't check against that (see https://github.com/quarkusio/quarkus/blob/68dff2c1da771fd2131e0ade904854282b4c8503/test-framework/jacoco/deployment/src/main/java/io/quarkus/jacoco/deployment/JacocoProcessor.java#L58).

Expected behavior

I expect that I can enhance classes subject to QuarkusUnitTest the same way as I can with @QuarkusTest, as the underlying mechanism is similar seen from the outside.

If this is not possible, I would like the quarkus-jacoco plugin to not fail.

Actual behavior

Tests registering QuarkusUnitTest doesn't even start but fail during augmentation when the jacoco plugin is on the test classpath:

java.lang.RuntimeException: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
    [error]: Build step io.quarkus.jacoco.deployment.JacocoProcessor#transformerBuildItem threw an exception: java.lang.NullPointerException: Cannot invoke "java.nio.file.Path.toAbsolutePath()" because the return value of "io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem.getOutputDirectory()" is null
    at io.quarkus.jacoco.deployment.JacocoProcessor.transformerBuildItem(JacocoProcessor.java:58)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:882)
    at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
    at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
    at java.base/java.lang.Thread.run(Thread.java:833)
    at org.jboss.threads.JBossThread.run(JBossThread.java:501)

    at io.quarkus.test.QuarkusUnitTest.beforeAll(QuarkusUnitTest.java:613)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$10(ClassBasedTestDescriptor.java:381)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:381)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:205)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:80)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:148)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)

How to Reproduce?

Generate a new extension, i.e. like this

mvn io.quarkus.platform:quarkus-maven-plugin:2.7.1.Final:create-extension -N \
  -DgroupId=io.quarkiverse.foo \
    -DextensionId=my-ext \
    -Dname="My Extension"

add

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-jacoco</artifactId>
      <scope>test</scope>
    </dependency>

to the deployment module, do an mvn package.

Output of uname -a or ver

No response

Output of java -version

No response

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.7.1

Build tool (ie. output of mvnw --version or gradlew --version)

Maven 3.8.4

Additional information

No response

quarkus-bot[bot] commented 2 years ago

/cc @geoand, @stuartwdouglas

geoand commented 2 years ago

As a first step, we should definitely not fail, that's easy :)