quarkus

@QuarkusIntegrationTest - change property during test runtime


I want to override an URL of external endpoint between test cases, but I cannot find out how. So for example in test 1, 2 and 3 I need to use a correct URL for testing, but in test 4 I need to test this timeout issue with a wrong URL.

I have a @TestProfile which overrides getConfigOverrides() methods and provide the correct URL, mocked by WireMock and returns 200; but then in production, an incident happens where the external endpoint stops working for some time and we are required to handle this unexpected situation. That's why I am trying to reproduce it in @QuarkusIntegrationTest.

I tried to define the wrong URL in application.yaml under another profile timeout, and switch test profile by System.setProperty("quarkus.test.profile", "timeout") at the beginning of my test case, but it does not work; the original URL still was picked, same as I thought. I understand that the properties are defined and cannot be changed during runtime easily.


What I want to simulate is an error of external server stops working, while IP can be resolved correctly(which means the host exists)

javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: org.apache.http.conn.ConnectTimeoutException: Connect to do-not-tell.com:443 [/xx.xx.xx.xx] failed: Read timed out

What can I do?

(and I found it's impossible to create 2 integration tests in my project, not sure why; or mvn verify cannot run 2 of @QuarkusIntegrationTest). If I can, then I could put this test case in another @QuarkusIntegrationTest.


Solution

  • Reminded by @geoand, I found that even original problem cannot be solved, I can work around by creating 2 integration tests with different test profiles, one extending another one and changing some of them to achieve the same goal.

    The trick is that I need to define 2 <execution>s for failsafe maven plugins, and then, put @Tag to each test, and configure respective value in <configuration><groups>. Now, with my config, with one mvn verify I can run both tests.

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <executions>
            <execution>
                <id>normal-int-test</id>
                <phase>integration-test</phase>
                <goals>
                    <goal>integration-test</goal>
                </goals>
                <configuration>
                    <groups>normal</groups> <!-- same as JUnit 5 @Tag -->
                    <systemPropertyVariables>
                        <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                        <maven.home>${maven.home}</maven.home>
                    </systemPropertyVariables>
                </configuration>
            </execution>
            <execution>
                <id>timeout-int-test</id>
                <phase>integration-test</phase>
                <goals>
                    <goal>integration-test</goal>
                </goals>
                <configuration>
                    <groups>oauth-timeout</groups> <!-- same as JUnit 5 @Tag -->
                    <systemPropertyVariables>
                        <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                        <maven.home>${maven.home}</maven.home>
                    </systemPropertyVariables>
                </configuration>
            </execution>
        </executions>
    </plugin>
    

    In the test:

    @QuarkusIntegrationTest
    @TestProfile(NormalTestProfile.class)
    @Tag("normal")
    public class NormalIT {
    ...
    }
    
    
    @QuarkusIntegrationTest
    @TestProfile(TimeoutTestProfile.class)
    @Tag("oauth-timeout")
    public class OauthTimeoutIT {
    ...
    }
    

    And two test profiles can inherit, so you don't define everything again:

    public class NormalTestProfile implements QuarkusTestProfile {
        @Override
        public Map<String, String> getConfigOverrides() {
            ...
        }
    }
    
    public class TimeoutTestProfile extends NormalTestProfile {
        @Override
        public Map<String, String> getConfigOverrides() {
            Map<String, String> originalProperties = super.getConfigOverrides();
            ... // iterate and modify and adds to a new Map
            ...
        }
    }