From 62991b79bf40e954a91b6e17aef20a830d90f024 Mon Sep 17 00:00:00 2001 From: pablo gonzalez granados Date: Wed, 18 Aug 2021 20:03:07 +0200 Subject: [PATCH] Verify devService integration * Keycloak * Kafka/RedPanda * amqp * Postgresql * Mysql * Mariadb * Mssql --- ...DevModeAmqpDevServiceUserExperienceIT.java | 43 +++++++++++ .../messaging/amqpreactive/DevModeAmqpIT.java | 9 +++ .../messaging/amqpreactive/DockerUtils.java | 71 +++++++++++++++++++ .../messaging/kafka/DevModeKafkaStreamIT.java | 7 ++ ...odeRedPandaDevServiceUserExperienceIT.java | 41 +++++++++++ .../ts/messaging/kafka/DockerUtils.java | 71 +++++++++++++++++++ ...odeKeycloakDevServiceUserExperienceIT.java | 45 ++++++++++++ .../ts/security/DevModeOidcSecurityIT.java | 1 + .../io/quarkus/ts/security/DockerUtils.java | 71 +++++++++++++++++++ ...odeMariadbDevServicesUserExperienceIT.java | 46 ++++++++++++ .../ts/sqldb/sqlapp/DevModeMariadbIT.java | 22 ++++++ ...vModeMssqlDevServicesUserExperienceIT.java | 47 ++++++++++++ .../ts/sqldb/sqlapp/DevModeMssqlIT.java | 22 ++++++ ...evModeMysqlDevServiceUserExperienceIT.java | 46 ++++++++++++ .../ts/sqldb/sqlapp/DevModeMysqlIT.java | 22 ++++++ ...ePostgresqlDevServiceUserExperienceIT.java | 45 ++++++++++++ .../ts/sqldb/sqlapp/DevModePostgresqlIT.java | 7 ++ .../quarkus/ts/sqldb/sqlapp/DockerUtils.java | 71 +++++++++++++++++++ .../sqlapp/OpenShiftMssqlDatabaseIT.java | 6 +- .../container-license-acceptance.txt | 2 + .../src/test/resources/mssql.properties | 6 +- 21 files changed, 696 insertions(+), 5 deletions(-) create mode 100644 messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DevModeAmqpDevServiceUserExperienceIT.java create mode 100644 messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DockerUtils.java create mode 100644 messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DevModeRedPandaDevServiceUserExperienceIT.java create mode 100644 messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DockerUtils.java create mode 100644 security/keycloak/src/test/java/io/quarkus/ts/security/DevModeKeycloakDevServiceUserExperienceIT.java create mode 100644 security/keycloak/src/test/java/io/quarkus/ts/security/DockerUtils.java create mode 100644 sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMariadbDevServicesUserExperienceIT.java create mode 100644 sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMariadbIT.java create mode 100644 sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMssqlDevServicesUserExperienceIT.java create mode 100644 sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMssqlIT.java create mode 100644 sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMysqlDevServiceUserExperienceIT.java create mode 100644 sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMysqlIT.java create mode 100644 sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModePostgresqlDevServiceUserExperienceIT.java create mode 100644 sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DockerUtils.java create mode 100644 sql-db/sql-app/src/test/resources/container-license-acceptance.txt diff --git a/messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DevModeAmqpDevServiceUserExperienceIT.java b/messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DevModeAmqpDevServiceUserExperienceIT.java new file mode 100644 index 000000000..c7182bd59 --- /dev/null +++ b/messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DevModeAmqpDevServiceUserExperienceIT.java @@ -0,0 +1,43 @@ +package io.quarkus.ts.messaging.amqpreactive; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import com.github.dockerjava.api.model.Image; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.services.DevModeQuarkusApplication; + +@Tag("QUARKUS-959") +@QuarkusScenario +public class DevModeAmqpDevServiceUserExperienceIT { + + private static final String AMQP_VERSION = "0.1.3"; + private static final String AMQP_IMAGE = "quay.io/artemiscloud/activemq-artemis-broker"; + + /** + * AMQP must be started using DEV services when running in DEV mode + */ + @DevModeQuarkusApplication + static RestService app = new RestService() + .withProperty("quarkus.amqp.devservices.image-name", String.format("%s:%s", AMQP_IMAGE, AMQP_VERSION)) + .onPreStart(s -> DockerUtils.removeImage(AMQP_IMAGE, AMQP_VERSION)); + + @Test + public void verifyIfUserIsInformedAboutAmqpDevServicePulling() { + app.logs().assertContains("Pulling docker image: quay.io/artemiscloud/activemq-artemis-broker"); + app.logs().assertContains("Please be patient; this may take some time but only needs to be done once"); + app.logs().assertContains("Starting to pull image"); + app.logs().assertContains("Dev Services for AMQP started"); + } + + @Test + public void verifyAmqpImage() { + Image postgresImg = DockerUtils.getImage(AMQP_IMAGE, AMQP_VERSION); + Assertions.assertFalse(postgresImg.getId().isEmpty(), String.format("%s:%s not found. " + + "Notice that user set his own custom image by 'quarkus.keycloak.devservices.image-name' property", + AMQP_IMAGE, AMQP_VERSION)); + } +} diff --git a/messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DevModeAmqpIT.java b/messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DevModeAmqpIT.java index 4aa446dee..0166e82ea 100644 --- a/messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DevModeAmqpIT.java +++ b/messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DevModeAmqpIT.java @@ -1,9 +1,13 @@ package io.quarkus.ts.messaging.amqpreactive; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + import io.quarkus.test.bootstrap.RestService; import io.quarkus.test.scenarios.QuarkusScenario; import io.quarkus.test.services.DevModeQuarkusApplication; +@Tag("QUARKUS-959") @QuarkusScenario public class DevModeAmqpIT extends BaseAmqpIT { @@ -12,4 +16,9 @@ public class DevModeAmqpIT extends BaseAmqpIT { */ @DevModeQuarkusApplication static RestService app = new RestService(); + + @Test + public void amqpContainerShouldBeStarted() { + app.logs().assertContains("Creating container for image: quay.io/artemiscloud/activemq-artemis-broker"); + } } diff --git a/messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DockerUtils.java b/messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DockerUtils.java new file mode 100644 index 000000000..ea36c6833 --- /dev/null +++ b/messaging/amqp-reactive/src/test/java/io/quarkus/ts/messaging/amqpreactive/DockerUtils.java @@ -0,0 +1,71 @@ +package io.quarkus.ts.messaging.amqpreactive; + +import java.util.List; +import java.util.Optional; + +import org.testcontainers.DockerClientFactory; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.model.Image; + +// TODO this DockerUtils must be removed once this changes will be released +// https://github.com/quarkus-qe/quarkus-test-framework/blob/main/quarkus-test-images/src/main/java/io/quarkus/test/utils/DockerUtils.java +public class DockerUtils { + + private static final DockerClient DOCKER_CLIENT = DockerClientFactory.instance().client();; + + /** + * Returns true if docker images contains expectedVersion. + * + * @param image docker images + * @param expectedVersion expected docker image version + */ + public static boolean isVersion(Image image, String expectedVersion) { + boolean exist = false; + String[] tags = Optional.ofNullable(image.getRepoTags()).orElse(new String[] {}); + for (String tag : tags) { + if (tag.contains(expectedVersion)) { + exist = true; + break; + } + } + + return exist; + } + + /** + * Returns true if docker image is removed. + * + * @param name docker image name + * @param version docker image version + */ + public static boolean removeImage(String name, String version) { + boolean removed = false; + Image image = getImage(name, version); + if (isVersion(image, version)) { + String id = image.getId().substring(image.getId().lastIndexOf(":") + 1); + DOCKER_CLIENT.removeImageCmd(id).withForce(true).exec(); + removed = true; + } + return removed; + } + + /** + * Returns an image based on the provided image name and version. If no image is found then a default empty image. + * is returned + * + * @param name docker image name + * @param version docker image version + */ + public static Image getImage(String name, String version) { + Image result = new Image(); + List images = DOCKER_CLIENT.listImagesCmd().withImageNameFilter(name).exec(); + for (Image image : images) { + if (isVersion(image, version)) { + result = image; + break; + } + } + return result; + } +} diff --git a/messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DevModeKafkaStreamIT.java b/messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DevModeKafkaStreamIT.java index 366aa85db..ed4f910bf 100644 --- a/messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DevModeKafkaStreamIT.java +++ b/messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DevModeKafkaStreamIT.java @@ -1,12 +1,14 @@ package io.quarkus.ts.messaging.kafka; import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; import io.quarkus.test.bootstrap.RestService; import io.quarkus.test.scenarios.QuarkusScenario; import io.quarkus.test.services.DevModeQuarkusApplication; @Tag("QUARKUS-1026") +@Tag("QUARKUS-959") @QuarkusScenario public class DevModeKafkaStreamIT extends BaseKafkaStreamTest { @@ -21,4 +23,9 @@ public class DevModeKafkaStreamIT extends BaseKafkaStreamTest { protected String getAppUrl() { return app.getHost() + ":" + app.getPort(); } + + @Test + public void kafkaContainerShouldBeStarted() { + app.logs().assertContains("Creating container for image: vectorized/redpanda"); + } } diff --git a/messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DevModeRedPandaDevServiceUserExperienceIT.java b/messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DevModeRedPandaDevServiceUserExperienceIT.java new file mode 100644 index 000000000..7fd14da55 --- /dev/null +++ b/messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DevModeRedPandaDevServiceUserExperienceIT.java @@ -0,0 +1,41 @@ +package io.quarkus.ts.messaging.kafka; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import com.github.dockerjava.api.model.Image; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.services.DevModeQuarkusApplication; + +@Tag("QUARKUS-959") +@QuarkusScenario +public class DevModeRedPandaDevServiceUserExperienceIT { + + private static final String RED_PANDA_VERSION = "latest"; + private static final String RED_PANDA_IMAGE = "vectorized/redpanda"; + + @DevModeQuarkusApplication + static RestService app = new RestService() + .withProperty("quarkus.kafka.devservices.enabled", Boolean.TRUE.toString()) + .withProperty("quarkus.kafka.devservices.image-name", String.format("%s:%s", RED_PANDA_IMAGE, RED_PANDA_VERSION)) + .onPreStart(s -> DockerUtils.removeImage(RED_PANDA_IMAGE, RED_PANDA_VERSION)); + + @Test + public void verifyIfUserIsInformedAboutRedPandaDevServicePulling() { + app.logs().assertContains("Pulling docker image: vectorized/redpanda"); + app.logs().assertContains("Please be patient; this may take some time but only needs to be done once"); + app.logs().assertContains("Starting to pull image"); + app.logs().assertContains("Dev Services for Kafka started"); + } + + @Test + public void verifyRedPandaImage() { + Image postgresImg = DockerUtils.getImage(RED_PANDA_IMAGE, RED_PANDA_VERSION); + Assertions.assertFalse(postgresImg.getId().isEmpty(), String.format("%s:%s not found. " + + "Notice that user set his own custom image by 'quarkus.datasource.devservices.image-name' property", + RED_PANDA_IMAGE, RED_PANDA_VERSION)); + } +} diff --git a/messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DockerUtils.java b/messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DockerUtils.java new file mode 100644 index 000000000..56ca412a8 --- /dev/null +++ b/messaging/kafka-streams-reactive-messaging/src/test/java/io/quarkus/ts/messaging/kafka/DockerUtils.java @@ -0,0 +1,71 @@ +package io.quarkus.ts.messaging.kafka; + +import java.util.List; +import java.util.Optional; + +import org.testcontainers.DockerClientFactory; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.model.Image; + +// TODO this DockerUtils must be removed once this changes will be released +// https://github.com/quarkus-qe/quarkus-test-framework/blob/main/quarkus-test-images/src/main/java/io/quarkus/test/utils/DockerUtils.java +public class DockerUtils { + + private static final DockerClient DOCKER_CLIENT = DockerClientFactory.instance().client();; + + /** + * Returns true if docker images contains expectedVersion. + * + * @param image docker images + * @param expectedVersion expected docker image version + */ + public static boolean isVersion(Image image, String expectedVersion) { + boolean exist = false; + String[] tags = Optional.ofNullable(image.getRepoTags()).orElse(new String[] {}); + for (String tag : tags) { + if (tag.contains(expectedVersion)) { + exist = true; + break; + } + } + + return exist; + } + + /** + * Returns true if docker image is removed. + * + * @param name docker image name + * @param version docker image version + */ + public static boolean removeImage(String name, String version) { + boolean removed = false; + Image image = getImage(name, version); + if (isVersion(image, version)) { + String id = image.getId().substring(image.getId().lastIndexOf(":") + 1); + DOCKER_CLIENT.removeImageCmd(id).withForce(true).exec(); + removed = true; + } + return removed; + } + + /** + * Returns an image based on the provided image name and version. If no image is found then a default empty image. + * is returned + * + * @param name docker image name + * @param version docker image version + */ + public static Image getImage(String name, String version) { + Image result = new Image(); + List images = DOCKER_CLIENT.listImagesCmd().withImageNameFilter(name).exec(); + for (Image image : images) { + if (isVersion(image, version)) { + result = image; + break; + } + } + return result; + } +} diff --git a/security/keycloak/src/test/java/io/quarkus/ts/security/DevModeKeycloakDevServiceUserExperienceIT.java b/security/keycloak/src/test/java/io/quarkus/ts/security/DevModeKeycloakDevServiceUserExperienceIT.java new file mode 100644 index 000000000..502047a73 --- /dev/null +++ b/security/keycloak/src/test/java/io/quarkus/ts/security/DevModeKeycloakDevServiceUserExperienceIT.java @@ -0,0 +1,45 @@ +package io.quarkus.ts.security; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import com.github.dockerjava.api.model.Image; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.scenarios.annotations.DisabledOnNative; +import io.quarkus.test.services.DevModeQuarkusApplication; + +@Tag("QUARKUS-959") +@QuarkusScenario +public class DevModeKeycloakDevServiceUserExperienceIT { + + private static final String KEYCLOAK_VERSION = "13.0.1"; + private static final String KEYCLOAK_IMAGE = "quay.io/keycloak/keycloak"; + + /** + * Keycloak must be started using DEV services when running in DEV mode + */ + @DevModeQuarkusApplication + static RestService app = new RestService() + .withProperty("quarkus.keycloak.devservices.image-name", String.format("%s:%s", KEYCLOAK_IMAGE, KEYCLOAK_VERSION)) + .onPreStart(s -> DockerUtils.removeImage(KEYCLOAK_IMAGE, KEYCLOAK_VERSION)); + + @Test + public void verifyIfUserIsInformedAboutKeycloakDevServicePulling() { + app.logs().assertContains("Pulling docker image: quay.io/keycloak/keycloak"); + app.logs().assertContains("Please be patient; this may take some time but only needs to be done once"); + app.logs().assertContains("Starting to pull image"); + // TODO https://github.com/quarkusio/quarkus/issues/19485 + //app.logs().assertContains("Dev Services for Keycloak started"); + } + + @Test + public void verifyKeycloakImage() { + Image postgresImg = DockerUtils.getImage(KEYCLOAK_IMAGE, KEYCLOAK_VERSION); + Assertions.assertFalse(postgresImg.getId().isEmpty(), String.format("%s:%s not found. " + + "Notice that user set his own custom image by 'quarkus.keycloak.devservices.image-name' property", + KEYCLOAK_IMAGE, KEYCLOAK_VERSION)); + } +} diff --git a/security/keycloak/src/test/java/io/quarkus/ts/security/DevModeOidcSecurityIT.java b/security/keycloak/src/test/java/io/quarkus/ts/security/DevModeOidcSecurityIT.java index 2b0a0e412..e01198ac6 100644 --- a/security/keycloak/src/test/java/io/quarkus/ts/security/DevModeOidcSecurityIT.java +++ b/security/keycloak/src/test/java/io/quarkus/ts/security/DevModeOidcSecurityIT.java @@ -10,6 +10,7 @@ import io.quarkus.test.scenarios.QuarkusScenario; import io.quarkus.test.services.DevModeQuarkusApplication; +@Tag("QUARKUS-959") @Tag("QUARKUS-1026") @QuarkusScenario public class DevModeOidcSecurityIT { diff --git a/security/keycloak/src/test/java/io/quarkus/ts/security/DockerUtils.java b/security/keycloak/src/test/java/io/quarkus/ts/security/DockerUtils.java new file mode 100644 index 000000000..38ea73789 --- /dev/null +++ b/security/keycloak/src/test/java/io/quarkus/ts/security/DockerUtils.java @@ -0,0 +1,71 @@ +package io.quarkus.ts.security; + +import java.util.List; +import java.util.Optional; + +import org.testcontainers.DockerClientFactory; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.model.Image; + +// TODO this DockerUtils must be removed once this changes will be released +// https://github.com/quarkus-qe/quarkus-test-framework/blob/main/quarkus-test-images/src/main/java/io/quarkus/test/utils/DockerUtils.java +public class DockerUtils { + + private static final DockerClient DOCKER_CLIENT = DockerClientFactory.instance().client();; + + /** + * Returns true if docker images contains expectedVersion. + * + * @param image docker images + * @param expectedVersion expected docker image version + */ + public static boolean isVersion(Image image, String expectedVersion) { + boolean exist = false; + String[] tags = Optional.ofNullable(image.getRepoTags()).orElse(new String[] {}); + for (String tag : tags) { + if (tag.contains(expectedVersion)) { + exist = true; + break; + } + } + + return exist; + } + + /** + * Returns true if docker image is removed. + * + * @param name docker image name + * @param version docker image version + */ + public static boolean removeImage(String name, String version) { + boolean removed = false; + Image image = getImage(name, version); + if (isVersion(image, version)) { + String id = image.getId().substring(image.getId().lastIndexOf(":") + 1); + DOCKER_CLIENT.removeImageCmd(id).withForce(true).exec(); + removed = true; + } + return removed; + } + + /** + * Returns an image based on the provided image name and version. If no image is found then a default empty image. + * is returned + * + * @param name docker image name + * @param version docker image version + */ + public static Image getImage(String name, String version) { + Image result = new Image(); + List images = DOCKER_CLIENT.listImagesCmd().withImageNameFilter(name).exec(); + for (Image image : images) { + if (isVersion(image, version)) { + result = image; + break; + } + } + return result; + } +} diff --git a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMariadbDevServicesUserExperienceIT.java b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMariadbDevServicesUserExperienceIT.java new file mode 100644 index 000000000..738168bab --- /dev/null +++ b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMariadbDevServicesUserExperienceIT.java @@ -0,0 +1,46 @@ +package io.quarkus.ts.sqldb.sqlapp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import com.github.dockerjava.api.model.Image; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.services.DevModeQuarkusApplication; +import io.quarkus.test.utils.SocketUtils; + +@Tag("QUARKUS-959") +@QuarkusScenario +public class DevModeMariadbDevServicesUserExperienceIT { + + private static final String MARIA_DB_VERSION = "5.5.49"; + private static final String MARIA_DB_NAME = "mariadb"; + + @DevModeQuarkusApplication + static RestService app = new RestService() + .withProperty("quarkus.datasource.db-kind", "mariadb") + .withProperty("quarkus.datasource.devservices.port", Integer.toString(SocketUtils.findAvailablePort())) + .withProperty("quarkus.datasource.devservices.image-name", MARIA_DB_NAME + ":" + MARIA_DB_VERSION) + .withProperty("quarkus.hibernate-orm.dialect", "org.hibernate.dialect.MariaDB102Dialect") + .withProperty("quarkus.hibernate-orm.database.generation", "none") + .onPreStart(s -> DockerUtils.removeImage(MARIA_DB_NAME, MARIA_DB_VERSION)); + + @Test + public void verifyIfUserIsInformedAboutMariadbDevServicePulling() { + app.logs().assertContains("Pulling docker image: mariadb"); + app.logs().assertContains("Please be patient; this may take some time but only needs to be done once"); + app.logs().assertContains("Starting to pull image"); + // TODO https://github.com/quarkusio/quarkus/issues/19573 + //app.logs().assertContains("Dev Services for mariadb started"); + } + + @Test + public void verifyMysqlImage() { + Image postgresImg = DockerUtils.getImage(MARIA_DB_NAME, MARIA_DB_VERSION); + Assertions.assertFalse(postgresImg.getId().isEmpty(), String.format("%s:%s not found. " + + "Notice that user set his own custom image by 'quarkus.datasource.devservices.image-name' property", + MARIA_DB_NAME, MARIA_DB_VERSION)); + } +} diff --git a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMariadbIT.java b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMariadbIT.java new file mode 100644 index 000000000..1ccefbbea --- /dev/null +++ b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMariadbIT.java @@ -0,0 +1,22 @@ +package io.quarkus.ts.sqldb.sqlapp; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.scenarios.annotations.DisabledOnNative; +import io.quarkus.test.services.DevModeQuarkusApplication; + +@Tag("QUARKUS-959") +@QuarkusScenario +public class DevModeMariadbIT extends AbstractSqlDatabaseIT { + + @DevModeQuarkusApplication + static RestService app = new RestService().withProperties("mariadb_app.properties"); + + @Test + public void mariadbContainerShouldBeStarted() { + app.logs().assertContains("Creating container for image: mariadb"); + } +} diff --git a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMssqlDevServicesUserExperienceIT.java b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMssqlDevServicesUserExperienceIT.java new file mode 100644 index 000000000..7efaff9e1 --- /dev/null +++ b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMssqlDevServicesUserExperienceIT.java @@ -0,0 +1,47 @@ +package io.quarkus.ts.sqldb.sqlapp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import com.github.dockerjava.api.model.Image; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.services.DevModeQuarkusApplication; +import io.quarkus.test.utils.SocketUtils; + +@Tag("QUARKUS-959") +@QuarkusScenario +public class DevModeMssqlDevServicesUserExperienceIT { + + private static final String MSSQL_VERSION = "2017-CU12"; + private static final String MSSQL_NAME = "mcr.microsoft.com/mssql/server"; + + @DevModeQuarkusApplication + static RestService app = new RestService() + .withProperty("quarkus.datasource.db-kind", "mssql") + .withProperty("quarkus.datasource.devservices.port", Integer.toString(SocketUtils.findAvailablePort())) + .withProperty("quarkus.datasource.devservices.image-name", MSSQL_NAME + ":" + MSSQL_VERSION) + .withProperty("quarkus.hibernate-orm.dialect", "org.hibernate.dialect.SQLServer2012Dialect") + .withProperty("quarkus.datasource.jdbc.driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver") + .withProperty("quarkus.hibernate-orm.database.generation", "none") + .onPreStart(s -> DockerUtils.removeImage(MSSQL_NAME, MSSQL_VERSION)); + + @Test + public void verifyIfUserIsInformedAboutMssqlDevServicePulling() { + app.logs().assertContains("Pulling docker image: " + MSSQL_NAME + ":" + MSSQL_VERSION); + app.logs().assertContains("Please be patient; this may take some time but only needs to be done once"); + app.logs().assertContains("Starting to pull image"); + //TODO https://github.com/quarkusio/quarkus/issues/19573 + //app.logs().assertContains("Dev Services for Mssql started"); + } + + @Test + public void verifyMssqlImage() { + Image postgresImg = DockerUtils.getImage(MSSQL_NAME, MSSQL_VERSION); + Assertions.assertFalse(postgresImg.getId().isEmpty(), String.format("%s:%s not found. " + + "Notice that user set his own custom image by 'quarkus.datasource.devservices.image-name' property", + MSSQL_NAME, MSSQL_VERSION)); + } +} diff --git a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMssqlIT.java b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMssqlIT.java new file mode 100644 index 000000000..cbcf745f7 --- /dev/null +++ b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMssqlIT.java @@ -0,0 +1,22 @@ +package io.quarkus.ts.sqldb.sqlapp; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.scenarios.annotations.DisabledOnNative; +import io.quarkus.test.services.DevModeQuarkusApplication; + +@Tag("QUARKUS-959") +@QuarkusScenario +public class DevModeMssqlIT extends AbstractSqlDatabaseIT { + + @DevModeQuarkusApplication + static RestService app = new RestService().withProperties("mssql.properties"); + + @Test + public void mmsqlContainerShouldBeStarted() { + app.logs().assertContains("Creating container for image: mcr.microsoft.com/mssql/server"); + } +} diff --git a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMysqlDevServiceUserExperienceIT.java b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMysqlDevServiceUserExperienceIT.java new file mode 100644 index 000000000..198060b52 --- /dev/null +++ b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMysqlDevServiceUserExperienceIT.java @@ -0,0 +1,46 @@ +package io.quarkus.ts.sqldb.sqlapp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import com.github.dockerjava.api.model.Image; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.services.DevModeQuarkusApplication; +import io.quarkus.test.utils.SocketUtils; + +@Tag("QUARKUS-959") +@QuarkusScenario +public class DevModeMysqlDevServiceUserExperienceIT { + + private static final String MYSQL_VERSION = "5.7.32"; + private static final String MYSQL_NAME = "mysql"; + + @DevModeQuarkusApplication + static RestService app = new RestService() + .withProperty("quarkus.datasource.db-kind", "mysql") + .withProperty("quarkus.datasource.devservices.port", Integer.toString(SocketUtils.findAvailablePort())) + .withProperty("quarkus.datasource.devservices.image-name", MYSQL_NAME + ":" + MYSQL_VERSION) + .withProperty("quarkus.hibernate-orm.dialect", "org.hibernate.dialect.MariaDB102Dialect") + .withProperty("quarkus.hibernate-orm.database.generation", "none") + .onPreStart(s -> DockerUtils.removeImage(MYSQL_NAME, MYSQL_VERSION)); + + @Test + public void verifyIfUserIsInformedAboutMysqlDevServicePulling() { + app.logs().assertContains("Pulling docker image: mysql"); + app.logs().assertContains("Please be patient; this may take some time but only needs to be done once"); + app.logs().assertContains("Starting to pull image"); + // TODO https://github.com/quarkusio/quarkus/issues/19573 + //app.logs().assertContains("Dev Services for Mysql started"); + } + + @Test + public void verifyMysqlImage() { + Image postgresImg = DockerUtils.getImage(MYSQL_NAME, MYSQL_VERSION); + Assertions.assertFalse(postgresImg.getId().isEmpty(), String.format("%s:%s not found. " + + "Notice that user set his own custom image by 'quarkus.datasource.devservices.image-name' property", + MYSQL_NAME, MYSQL_VERSION)); + } +} diff --git a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMysqlIT.java b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMysqlIT.java new file mode 100644 index 000000000..e70a2b7b2 --- /dev/null +++ b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModeMysqlIT.java @@ -0,0 +1,22 @@ +package io.quarkus.ts.sqldb.sqlapp; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.scenarios.annotations.DisabledOnNative; +import io.quarkus.test.services.DevModeQuarkusApplication; + +@Tag("QUARKUS-959") +@QuarkusScenario +public class DevModeMysqlIT extends AbstractSqlDatabaseIT { + + @DevModeQuarkusApplication + static RestService app = new RestService().withProperties("mysql.properties"); + + @Test + public void mysqlContainerShouldBeStarted() { + app.logs().assertContains("Creating container for image: mysql"); + } +} diff --git a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModePostgresqlDevServiceUserExperienceIT.java b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModePostgresqlDevServiceUserExperienceIT.java new file mode 100644 index 000000000..a92902d1b --- /dev/null +++ b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModePostgresqlDevServiceUserExperienceIT.java @@ -0,0 +1,45 @@ +package io.quarkus.ts.sqldb.sqlapp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import com.github.dockerjava.api.model.Image; + +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.services.DevModeQuarkusApplication; +import io.quarkus.test.utils.SocketUtils; + +@Tag("QUARKUS-959") +@QuarkusScenario +public class DevModePostgresqlDevServiceUserExperienceIT { + + private static final String POSTGRESQL_VERSION = "9.6.23"; + private static final String POSTGRES_NAME = "postgres"; + + @DevModeQuarkusApplication + static RestService app = new RestService() + .withProperty("quarkus.datasource.db-kind", "postgresql") + .withProperty("quarkus.datasource.devservices.port", Integer.toString(SocketUtils.findAvailablePort())) + .withProperty("quarkus.datasource.devservices.image-name", POSTGRES_NAME + ":" + POSTGRESQL_VERSION) + .withProperty("quarkus.hibernate-orm.database.generation", "none") + .onPreStart(s -> DockerUtils.removeImage(POSTGRES_NAME, POSTGRESQL_VERSION)); + + @Test + public void verifyIfUserIsInformedAboutPostgresqlDevServicePulling() { + app.logs().assertContains("Pulling docker image: postgres"); + app.logs().assertContains("Please be patient; this may take some time but only needs to be done once"); + app.logs().assertContains("Starting to pull image"); + // TODO https://github.com/quarkusio/quarkus/issues/19573 + //app.logs().assertContains("Dev Services for postgres started"); + } + + @Test + public void verifyPostgresqlImage() { + Image postgresImg = DockerUtils.getImage(POSTGRES_NAME, POSTGRESQL_VERSION); + Assertions.assertFalse(postgresImg.getId().isEmpty(), String.format("%s:%s not found. " + + "Notice that user set his own custom image by 'quarkus.datasource.devservices.image-name' property", + POSTGRES_NAME, POSTGRESQL_VERSION)); + } +} diff --git a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModePostgresqlIT.java b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModePostgresqlIT.java index bf0dc37a1..a6e7fe793 100644 --- a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModePostgresqlIT.java +++ b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DevModePostgresqlIT.java @@ -1,15 +1,22 @@ package io.quarkus.ts.sqldb.sqlapp; import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; import io.quarkus.test.bootstrap.RestService; import io.quarkus.test.scenarios.QuarkusScenario; import io.quarkus.test.services.DevModeQuarkusApplication; +@Tag("QUARKUS-959") @Tag("QUARKUS-1026") @QuarkusScenario public class DevModePostgresqlIT extends AbstractSqlDatabaseIT { @DevModeQuarkusApplication static RestService app = new RestService().withProperties("postgresql.properties"); + + @Test + public void postgresqlContainerShouldBeStarted() { + app.logs().assertContains("Creating container for image: postgres"); + } } \ No newline at end of file diff --git a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DockerUtils.java b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DockerUtils.java new file mode 100644 index 000000000..4cc8c0978 --- /dev/null +++ b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/DockerUtils.java @@ -0,0 +1,71 @@ +package io.quarkus.ts.sqldb.sqlapp; + +import java.util.List; +import java.util.Optional; + +import org.testcontainers.DockerClientFactory; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.model.Image; + +// TODO this DockerUtils must be removed once this changes will be released +// https://github.com/quarkus-qe/quarkus-test-framework/blob/main/quarkus-test-images/src/main/java/io/quarkus/test/utils/DockerUtils.java +public class DockerUtils { + + private static final DockerClient DOCKER_CLIENT = DockerClientFactory.instance().client();; + + /** + * Returns true if docker images contains expectedVersion. + * + * @param image docker images + * @param expectedVersion expected docker image version + */ + public static boolean isVersion(Image image, String expectedVersion) { + boolean exist = false; + String[] tags = Optional.ofNullable(image.getRepoTags()).orElse(new String[] {}); + for (String tag : tags) { + if (tag.contains(expectedVersion)) { + exist = true; + break; + } + } + + return exist; + } + + /** + * Returns true if docker image is removed. + * + * @param name docker image name + * @param version docker image version + */ + public static boolean removeImage(String name, String version) { + boolean removed = false; + Image image = getImage(name, version); + if (isVersion(image, version)) { + String id = image.getId().substring(image.getId().lastIndexOf(":") + 1); + DOCKER_CLIENT.removeImageCmd(id).withForce(true).exec(); + removed = true; + } + return removed; + } + + /** + * Returns an image based on the provided image name and version. If no image is found then a default empty image. + * is returned + * + * @param name docker image name + * @param version docker image version + */ + public static Image getImage(String name, String version) { + Image result = new Image(); + List images = DOCKER_CLIENT.listImagesCmd().withImageNameFilter(name).exec(); + for (Image image : images) { + if (isVersion(image, version)) { + result = image; + break; + } + } + return result; + } +} diff --git a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/OpenShiftMssqlDatabaseIT.java b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/OpenShiftMssqlDatabaseIT.java index 738cc159e..53f139a90 100644 --- a/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/OpenShiftMssqlDatabaseIT.java +++ b/sql-db/sql-app/src/test/java/io/quarkus/ts/sqldb/sqlapp/OpenShiftMssqlDatabaseIT.java @@ -15,5 +15,9 @@ public class OpenShiftMssqlDatabaseIT extends AbstractSqlDatabaseIT { static DefaultService mssql = new DefaultService(); @QuarkusApplication - static RestService app = new RestService().withProperties("mssql.properties"); + static RestService app = new RestService() + .withProperties("mssql.properties") + .withProperty("quarkus.datasource.username", "sa") + .withProperty("quarkus.datasource.password", "My1337p@ssworD") + .withProperty("quarkus.datasource.jdbc.url", "jdbc:sqlserver://mssql:1433;databaseName=mydb"); } diff --git a/sql-db/sql-app/src/test/resources/container-license-acceptance.txt b/sql-db/sql-app/src/test/resources/container-license-acceptance.txt new file mode 100644 index 000000000..33a4fedac --- /dev/null +++ b/sql-db/sql-app/src/test/resources/container-license-acceptance.txt @@ -0,0 +1,2 @@ +mcr.microsoft.com/mssql/server:2017-CU12 +mcr.microsoft.com/mssql/server:2019-CU10-ubuntu-20.04 \ No newline at end of file diff --git a/sql-db/sql-app/src/test/resources/mssql.properties b/sql-db/sql-app/src/test/resources/mssql.properties index 827e87639..b8b9100ce 100644 --- a/sql-db/sql-app/src/test/resources/mssql.properties +++ b/sql-db/sql-app/src/test/resources/mssql.properties @@ -1,6 +1,4 @@ quarkus.datasource.db-kind=mssql +quarkus.hibernate-orm.dialect=org.hibernate.dialect.SQLServer2012Dialect quarkus.hibernate-orm.sql-load-script=mssql_import.sql -quarkus.hibernate-orm.database.generation=drop-and-create -quarkus.datasource.username=sa -quarkus.datasource.password=My1337p@ssworD -quarkus.datasource.jdbc.url=jdbc:sqlserver://mssql:1433;databaseName=mydb \ No newline at end of file +quarkus.hibernate-orm.database.generation=drop-and-create \ No newline at end of file