Reputation: 21
I'm trying to setup my quarkus project with gitlab-ci and I'm constantly running into the next problem. Right now I'm trying to figure out how quarkus is running unit test vs integration test.
Both unit test and integration test work if run from the command line like this:
export QUARKUS_PROFILE=test
./mvnw verify
But when running from gitlab-ci it runs in containers and I just don't seem to be able to find out the right environment to setup.
The build stage below (only unit test - @QuarkusTest) runs fine. When adding integration test (./mvnw verify) it will fail with the database connection failed.
The verify stage below however fails on the unit tests. If I disable the unit tests (with @Disabled) the integration tests (@QuarkusIntegrationTest) runs fine with below environment variables.
It seems like unit tests needs the default postgress url (QUARKUS_DATASOURCE_REACTIVE_URL - not sure how to figure out what the actual default value is), but in integration test on gitlab this will fail with: Connect Connection refused). This can be solved with using the QUARKUS_DATASOURCE_REACTIVE_URL below.
Here is my application.properties
quarkus.container-image.group=yyyy/slideshow
quarkus.container-image.insecure=true
quarkus.container-image.registry=xxxx:5555
quarkus.container-image.build=true
quarkus.rest-client.piwigo-api.url=https://<hostname>
quarkus.datasource.devservices.enabled=true
quarkus.datasource.db-kind=postgresql
quarkus.hibernate-orm.database.generation=drop-and-create
%prod.quarkus.http.port=9090
%test.quarkus.http.port=9080
%test.quarkus.http.test-port=9081
%test.quarkus.hibernate-orm.sql-load-script=import.sql
Here is my gitlab-ci (quarkus-dev is my own image: eclipse-temurin:17 with docker-ce):
image: xxxx:5555/yyyy/util/quarkus-dev:0.1.0
variables:
IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME"
stages:
- build
- verify
- docker
unit-test:
stage: build
script:
- ./mvnw test
integration-test:
stage: verify
variables:
QUARKUS_PROFILE: test
QUARKUS_DATASOURCE_REACTIVE_URL: "vertx-reactive:postgresql://<ip docker host>:5432/quarkus?loggerLevel=OFF"
TEST_URL: "http://<ip docker host>:9081"
script:
- ./mvnw verify
docker-build:
stage: docker
when: manual
variables:
QUARKUS_CONTAINER_IMAGE_PUSH: "true"
script:
- ./mvnw install -DskipTests
A minimal example:
I based this example based on https://github.com/quarkusio/quarkus-quickstarts/tree/main/hibernate-reactive-panache-quickstart.
Dockerfile for the image used to run the pipeline in gitlab (/quarkus-dev:0.1.0)
FROM eclipse-temurin:17 as builder
RUN apt-get update && \
apt-get install -y apt-transport-https ca-certificates curl software-properties-common && \
apt-get clean
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && \
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \
apt-get clean
RUN apt-get install -y docker-ce && \
apt-get clean
Updated dockerfile src/main/docker/Dockerfile.jvm (changed to java 17):
FROM registry.access.redhat.com/ubi8/openjdk-17:1.14
ENV LANGUAGE='en_US:en'
# We make four distinct layers so if there are application changes the library layers can be re-used
COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/
COPY --chown=185 target/quarkus-app/*.jar /deployments/
COPY --chown=185 target/quarkus-app/app/ /deployments/app/
COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/
EXPOSE 8080
USER 185
ENV AB_JOLOKIA_OFF=""
ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
Updated pom file (similar to my failing project)
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
<artifactId>hibernate-reactive-panache-quickstart</artifactId>
<version>0.1.0-SNAPSHOT</version>
<properties>
<compiler-plugin.version>3.10.1</compiler-plugin.version>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>2.15.2.Final</quarkus.platform.version>
<surefire-plugin.version>3.0.0-M7</surefire-plugin.version>
<assertj.version>3.24.2</assertj.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-reactive-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-reactive-pg-client</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-container-image-docker</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<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>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<skipITs>false</skipITs>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
Updated Application properties:
quarkus.container-image.group=<group-name>
quarkus.container-image.insecure=true
quarkus.container-image.registry=<registery url>
quarkus.container-image.build=true
quarkus.datasource.devservices.enabled=true
quarkus.datasource.db-kind=postgresql
quarkus.hibernate-orm.database.generation=drop-and-create
%test.quarkus.http.port=9080
%test.quarkus.http.test-port=9081
%test.quarkus.hibernate-orm.sql-load-script=import.sql
Updated unit test:
package org.acme.hibernate.orm.panache;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.response.Response;
import static io.restassured.RestAssured.given;
import static org.assertj.core.api.Assertions.assertThat;
@QuarkusTest
public class FruitsEndpointTest {
@Test
@Disabled
public void testListAllFruits() {
//List all, should have all 3 fruits the database has initially:
Response response = given()
.when()
.get("/fruits")
.then()
.statusCode(200)
.contentType("application/json")
.extract().response();
assertThat(response.jsonPath().getList("name")).containsExactlyInAnyOrder("Cherry", "Apple", "Banana");
}
}
Updated integration test:
package org.acme.hibernate.orm.panache;
import io.quarkus.test.junit.QuarkusIntegrationTest;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.response.Response;
import static io.restassured.RestAssured.given;
import static org.assertj.core.api.Assertions.assertThat;
@QuarkusIntegrationTest
public class FruitsEndpointIT {
@Test
@Disabled
public void testListAllFruits() {
//List all, should have all 3 fruits the database has initially:
Response response = given()
.when()
.get("/fruits")
.then()
.statusCode(200)
.contentType("application/json")
.extract().response();
assertThat(response.jsonPath().getList("name")).containsExactlyInAnyOrder("Cherry", "Apple", "Banana");
}
}
Minimal gitlab-ci.yml:
image: <xxx>/quarkus-dev:0.1.0
stages:
- verify
unit-test:
stage: verify
script:
- ./mvnw test
integration-test:
stage: verify
variables:
QUARKUS_PROFILE: test
QUARKUS_DATASOURCE_REACTIVE_URL: "vertx-reactive:postgresql://<docker host ip>:5432/quarkus?loggerLevel=OFF"
TEST_URL: "http://<docker host ip>:9081"
script:
- ./mvnw verify
Running on the cmdline the following works:
export QUARKUS_PROFILE=test
./mvnw verify
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
The above example also works on the gitlab runner. However, as you se the unit test is disabled. After enabling it still works locally (mvnw verify), but it will fail on the gitlab runner.
The unit-test job will succeed, but the integration-test job will fail on the unit tests.
2023-01-28 12:34:45,902 ERROR [org.hib.rea.errors] (vert.x-eventloop-thread-3) HR000057: Failed to execute statement [select fruit0_.id as id1_0_, fruit0_.name as name2_0_ from Fruit fruit0_ order by fruit0_.name]: could not execute query: java.util.concurrent.CompletionException: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: /<ip>:5432
.
.
.
[ERROR] Failures:
[ERROR] FruitsEndpointTest.testListAllFruits:22 1 expectation failed.
Expected status code <200> but was <500>.
Upvotes: 2
Views: 966