Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange behaviour of QuarkusTestResourceLifecycleManager #43682

Closed
nicolasduminil opened this issue Oct 3, 2024 · 8 comments
Closed

Strange behaviour of QuarkusTestResourceLifecycleManager #43682

nicolasduminil opened this issue Oct 3, 2024 · 8 comments
Labels
area/testing kind/bug Something isn't working

Comments

@nicolasduminil
Copy link

nicolasduminil commented Oct 3, 2024

Describe the bug

With Quarkus 3.15.1, I'm using QuarkusTestResourceLifecycleManager to run docker images via testcontainers. The file package.png here attached shows the class diagram of a simple test project.
The class AbstractCurrentTimeResource defines test resource as follows:

    @QuarkusTestResource(value = MyTestRessource.class, restrictToAnnotatedClass = true)

The class MyTestResource implements QuarkusTestResourceLifecycleManager and starts the docker image required for testing. On its start method it returns the MP Config property which contains the URL of the deployed service under test.

Everything works as expected, excepting the fact that the docker image isn't reused across the tests but it's started and stopped for each single test. I can live with that waiting for the 3.16.

At this point all the mentioned classes belong to the same and unique Maven artifact. But now I need to share between several projects the calsses MyTestResources and AbstractCurrentTimeResource. I'm extracting them in a separate Maven artifact which I include as a dependency in the consumer projects. And then the MP Config property supposed to contain the URL of the service under test isn't resolved any more. It looks like AbstractCurrentTimeResource which is extended by the concrete test class CurrentTimeIT isn't executed any more, which is probably impossible.Image

Expected behavior

I expect that externalizing in a different Maven artifact the classes AbstractCurrentTimeResource and MyTestResource works exactly the same as they do when included in the same artifact as CurrentTimeIT.

Actual behavior

Externalizing the lifetime management classes from the integration test class doesn't work and raises the following exception:

[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 4.376 s <<< FAILURE! -- in  fr.simplex_software.quarkus_test_resource_lifecycle_manager_issue.tests.CurrentTimeIT
[ERROR] fr.simplex_software.quarkus_test_resource_lifecycle_manager_issue.tests.CurrentTimeIT -- Time elapsed: 4.376 s <<< ERROR!
java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus
    at io.quarkus.test.junit.QuarkusTestExtension.throwBootFailureException(QuarkusTestExtension.java:634)
    at io.quarkus.test.junit.QuarkusTestExtension.interceptBeforeAllMethod(QuarkusTestExtension.java:702)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: java.lang.RuntimeException: Failed to start quarkus
    at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
    at io.quarkus.runtime.Application.start(Application.java:101)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at io.quarkus.runner.bootstrap.StartupActionImpl.run(StartupActionImpl.java:305)
    at io.quarkus.test.junit.QuarkusTestExtension.doJavaStart(QuarkusTestExtension.java:248)
    at io.quarkus.test.junit.QuarkusTestExtension.ensureStarted(QuarkusTestExtension.java:601)
    at io.quarkus.test.junit.QuarkusTestExtension.beforeAll(QuarkusTestExtension.java:651)
    ... 1 more
Caused by: jakarta.enterprise.inject.spi.DeploymentException: io.quarkus.runtime.configuration.ConfigurationException: Failed to load  config value of type class java.lang.String for: quarkus.rest-client.baseUrl.url

    at io.quarkus.arc.runtime.ConfigRecorder.validateConfigProperties(ConfigRecorder.java:70)
    at io.quarkus.deployment.steps.ConfigBuildStep$validateRuntimeConfigProperty1282080724.deploy_0(Unknown Source)
    at io.quarkus.deployment.steps.ConfigBuildStep$validateRuntimeConfigProperty1282080724.deploy(Unknown Source)
    ... 8 more
    Suppressed: java.util.NoSuchElementException: SRCFG00014: The config property quarkus.rest-client.baseUrl.url is required but it could  not be found in any config source
            at io.smallrye.config.SmallRyeConfig.convertValue(SmallRyeConfig.java:436)
            at io.smallrye.config.inject.ConfigProducerUtil.getValue(ConfigProducerUtil.java:100)
            at io.quarkus.arc.runtime.ConfigRecorder.validateConfigProperties(ConfigRecorder.java:60)
            ... 10 more
Caused by: io.quarkus.runtime.configuration.ConfigurationException: Failed to load config value of type class java.lang.String for: quarkus.rest-client.baseUrl.url

How to Reproduce?

I could provide a reproducer if required.

Output of uname -a or ver

Linux nicolas-XPS-15-9570 6.8.0-45-generic #45-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 30 12:02:04 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

java version "21.0.3" 2024-04-16 LTS Java(TM) SE Runtime Environment (build 21.0.3+7-LTS-152) Java HotSpot(TM) 64-Bit Server VM (build 21.0.3+7-LTS-152, mixed mode, sharing)

Quarkus version or git rev

3.15.1

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

Apache Maven 3.9.5 (57804ffe001d7215b5e7bcb531cf83df38f93546) Maven home: /opt/apache-maven-3.9.5 Java version: 21.0.3, vendor: Oracle Corporation, runtime: /usr/lib/jvm/jdk-21-oracle-x64 Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "6.8.0-45-generic", arch: "amd64", family: "unix"

Additional information

N/A

@nicolasduminil nicolasduminil added the kind/bug Something isn't working label Oct 3, 2024
@nicolasduminil
Copy link
Author

I forgot to mention that I'm using the jandex-maven-plugin, of course.

@geoand
Copy link
Contributor

geoand commented Oct 4, 2024

Do you mind putting a sample together that shows the problem in action?
It's hard to provide any meaningful help in this case without seeing the problem in action.

Thanks

@geoand geoand added the triage/needs-reproducer We are waiting for a reproducer. label Oct 4, 2024
@nicolasduminil
Copy link
Author

@geoand : I agree it's hard to understand. Here is a reproducer. To reproduce, proceed as follows:

$ git clone https://github.com/nicolasduminil/quarkus-test-resource-lifecycle-manager-issue.git
$ cd  quarkus-test-resource-lifecycle-manager-issue
$ mvn verify

This should work as expected, except the testcontainers reuse feature.

$ git checkout issue
$ mvn clean verify

This should reproduce the exception.

@geoand
Copy link
Contributor

geoand commented Oct 4, 2024

Thanks a lot.

Next week I likely won't be around, so I'll likely try the week after

@nicolasduminil
Copy link
Author

nicolasduminil commented Oct 7, 2024

To resume, what seems to happen is that, in a test class hierarchy, where the test classes extend an abstract class which declares @QuarkusTestResource(...), things work as expected as long as the abstract class and the associated test resource class referenced by it, are in the same JAR as the concrete extension test classes.

But as soon as the abstract class, together with the test resource class, is isolated in a separate test JAR, i.e. a JAR built with jar:test-jar, for example:

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.4.2</version>
        <executions>
          <execution>
            <goals>
              <goal>test-jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

and this test jar is used as a test dependency, i.e <type>test-jar</type>, in the extension test class artifact, the mentioned exception is raised. In this case, the resource class referenced by the abstract base class doesn't seem to be executed.

I tried to figure out what happens, but unsuccessfully. Perhaps something related to the fact of using a test JAR ? I didn't try to change that such that to use a normal JAR because, in this case, I'd have had to move the test scoped dependencies in compile scoped ones, which wouldn't have made sense with artifacts like quarkus-junit5 or testcontainers.

@geoand geoand removed the triage/needs-reproducer We are waiting for a reproducer. label Oct 15, 2024
@geoand
Copy link
Contributor

geoand commented Oct 15, 2024

Thanks for looking into this.

What you are seeing is indeed a limitation of how we discover @QuarkusTestResource and @WithTestResource - they essentially need to be in the same jar as the test being executed.
There is no automatic way I can think of for handling this use case. One way of doing it (which is far from ideal, but could likely work) would be to have a configuration property that would be applicable to test and would let users configure artifacts which Quarkus would inspect for @QuarkusTestResource and @WithTestResource.

@nicolasduminil
Copy link
Author

Okay, I'll have to experience something like that, thanks. But my understanding is that @WithTestResource is only available starting with 3.16, right?

@geoand
Copy link
Contributor

geoand commented Oct 15, 2024

That is correct

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/testing kind/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants