From de31eed9b439012fbc853bb7864f1b6e19c8bd18 Mon Sep 17 00:00:00 2001 From: Lars Johansson <lars.johansson@ess.eu> Date: Wed, 27 Sep 2023 15:20:21 +0200 Subject: [PATCH] Add code coverage for integration tests with Docker --- Dockerfile.integrationtest | 13 ++++ docker-compose-integrationtest.yml | 6 +- pom.xml | 66 +++++++++++++++++++ .../openepics/names/docker/HealthcheckIT.java | 27 +++++++- .../org/openepics/names/docker/ITUtil.java | 8 ++- .../org/openepics/names/docker/NamesIT.java | 24 ++++++- .../org/openepics/names/docker/ReportIT.java | 25 ++++++- .../names/docker/StructuresDeviceGroupIT.java | 25 ++++++- .../names/docker/StructuresDeviceTypeIT.java | 25 ++++++- .../names/docker/StructuresDisciplineIT.java | 25 ++++++- .../names/docker/StructuresSubsystemIT.java | 25 ++++++- .../names/docker/StructuresSystemGroupIT.java | 25 ++++++- .../names/docker/StructuresSystemIT.java | 25 ++++++- .../docker/complex/NamesInstanceIndexIT.java | 26 +++++++- .../names/docker/complex/NamesLegacyIT.java | 25 ++++++- .../NamesLegacyStructuresDeleteIT.java | 25 ++++++- .../NamesLegacyStructuresUpdateIT.java | 25 ++++++- .../names/docker/complex/NamesMultipleIT.java | 25 ++++++- .../docker/complex/StructuresLevel3IT.java | 25 ++++++- .../docker/complex/StructuresMultipleIT.java | 25 ++++++- .../resources/INTEGRATIONTEST_DOCKER_RUN.md | 25 ++++++- 21 files changed, 497 insertions(+), 23 deletions(-) create mode 100644 Dockerfile.integrationtest diff --git a/Dockerfile.integrationtest b/Dockerfile.integrationtest new file mode 100644 index 00000000..273fc766 --- /dev/null +++ b/Dockerfile.integrationtest @@ -0,0 +1,13 @@ +# ------------------------------------------------------------------------------ +# Copyright (C) 2021 European Spallation Source ERIC. +# ------------------------------------------------------------------------------ + +FROM openjdk:17 + +# deployment unit +COPY target/naming-backend-*.jar /naming/naming-backend.jar + +# code coverage +COPY target/jacoco/jacocoagent.jar /naming/jacocoagent.jar + +CMD ["java", "-jar", "/naming/naming-backend.jar", "--spring.config.name=application"] diff --git a/docker-compose-integrationtest.yml b/docker-compose-integrationtest.yml index b7801292..b84cd633 100644 --- a/docker-compose-integrationtest.yml +++ b/docker-compose-integrationtest.yml @@ -5,7 +5,9 @@ version: '3.7' services: naming: - build: ./ + build: + context: . + dockerfile: Dockerfile.integrationtest networks: - naming-net ports: @@ -13,7 +15,7 @@ services: depends_on: postgres: condition: service_healthy - command: "java -jar /naming/naming-backend.jar" + command: "java -javaagent:/naming/jacocoagent.jar=destfile=/naming/jacoco.exec,output=file,append=false -jar /naming/naming-backend.jar" postgres: image: "postgres:9.6.7" diff --git a/pom.xml b/pom.xml index 54c5aa76..26555465 100644 --- a/pom.xml +++ b/pom.xml @@ -82,6 +82,12 @@ <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> + <dependency> + <groupId>org.jacoco</groupId> + <artifactId>org.jacoco.agent</artifactId> + <version>0.8.10</version> + <scope>runtime</scope> + </dependency> <dependency> <groupId>org.springframework.boot</groupId> @@ -137,6 +143,66 @@ <skipITs>${skipITs}</skipITs> </configuration> </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy</id> + <phase>package</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>org.jacoco</groupId> + <artifactId>org.jacoco.agent</artifactId> + <classifier>runtime</classifier> + <outputDirectory>${project.build.directory}/jacoco</outputDirectory> + <destFileName>jacocoagent.jar</destFileName> + </artifactItem> + </artifactItems> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <version>0.8.10</version> + <executions> + <execution> + <id>merge</id> + <phase>verify</phase> + <goals> + <goal>merge</goal> + </goals> + <configuration> + <fileSets> + <fileSet> + <directory>${project.build.directory}</directory> + <includes> + <include>jacoco*.exec</include> + </includes> + </fileSet> + </fileSets> + <destFile>${project.build.directory}/site/jacoco/jacoco.exec</destFile> + </configuration> + </execution> + <execution> + <id>report</id> + <phase>verify</phase> + <goals> + <goal>report</goal> + </goals> + <configuration> + <dataFile>${project.build.directory}/site/jacoco/jacoco.exec</dataFile> + <outputDirectory>${project.build.directory}/site/jacoco</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> </plugins> </build> </project> diff --git a/src/test/java/org/openepics/names/docker/HealthcheckIT.java b/src/test/java/org/openepics/names/docker/HealthcheckIT.java index 09ca51b8..4c61926e 100644 --- a/src/test/java/org/openepics/names/docker/HealthcheckIT.java +++ b/src/test/java/org/openepics/names/docker/HealthcheckIT.java @@ -24,19 +24,24 @@ import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; +import java.util.Optional; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> - * Purpose of this class is to test healthcheck endpoint. + * Purpose of this class is to test healthcheck endpoints. * In practice, it means means to have Naming and PostgreSQL up and running. * </p> * @@ -50,6 +55,24 @@ class HealthcheckIT { new DockerComposeContainer<>(new File("docker-compose-integrationtest.yml")) .waitingFor(ITUtil.NAMING, Wait.forLogMessage(".*Started NamingApplication.*", 1)); + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + HealthcheckIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void readHealthcheck() { try { diff --git a/src/test/java/org/openepics/names/docker/ITUtil.java b/src/test/java/org/openepics/names/docker/ITUtil.java index 315f9d9e..25fcdd23 100644 --- a/src/test/java/org/openepics/names/docker/ITUtil.java +++ b/src/test/java/org/openepics/names/docker/ITUtil.java @@ -54,7 +54,7 @@ public class ITUtil { static final String HTTP = "http://"; static final String HEADER_JSON = "'Content-Type: application/json'"; - static final String IP_PORT_NAMING = "127.0.0.1:8080"; + static final String IP_PORT_NAMING = "127.0.0.1:8080"; static final String API_V1_HISTORY = "/api/v1/history"; static final String API_V1_NAMES = "/api/v1/names"; @@ -78,6 +78,12 @@ public class ITUtil { private static final String CURLY_BRACE_END = "}"; private static final String HTTP_REPLY = "HTTP"; + // code coverage + + public static final String JACOCO_EXEC_PATH = "/naming/jacoco.exec"; + public static final String JACOCO_TARGET_PREFIX = "target/jacoco_"; + public static final String JACOCO_TARGET_SUFFIX = ".exec"; + /** * This class is not to be instantiated. */ diff --git a/src/test/java/org/openepics/names/docker/NamesIT.java b/src/test/java/org/openepics/names/docker/NamesIT.java index 509dabd2..3835c001 100644 --- a/src/test/java/org/openepics/names/docker/NamesIT.java +++ b/src/test/java/org/openepics/names/docker/NamesIT.java @@ -25,8 +25,10 @@ import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.rest.beans.Type; @@ -41,16 +43,18 @@ import org.openepics.names.rest.beans.element.StructureElementCommandCreate; import org.openepics.names.rest.beans.response.ResponsePageNameElements; import org.openepics.names.util.NameCommand; import org.openepics.names.util.NameElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.api.DockerClient; /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test names endpoints. @@ -169,6 +173,24 @@ class NamesIT { deviceTypeTT = approvedStructureElement.getUuid(); } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + NamesIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void equivalenceName() { // purpose diff --git a/src/test/java/org/openepics/names/docker/ReportIT.java b/src/test/java/org/openepics/names/docker/ReportIT.java index 53e0b27c..735e60b5 100644 --- a/src/test/java/org/openepics/names/docker/ReportIT.java +++ b/src/test/java/org/openepics/names/docker/ReportIT.java @@ -24,16 +24,21 @@ import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; +import java.util.Optional; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test report endpoints. @@ -49,6 +54,24 @@ class ReportIT { new DockerComposeContainer<>(new File("docker-compose-integrationtest.yml")) .waitingFor(ITUtil.NAMING, Wait.forLogMessage(".*Started NamingApplication.*", 1)); + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + ReportIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void readReportAbout() { try { diff --git a/src/test/java/org/openepics/names/docker/StructuresDeviceGroupIT.java b/src/test/java/org/openepics/names/docker/StructuresDeviceGroupIT.java index 86fbba77..f36928ba 100644 --- a/src/test/java/org/openepics/names/docker/StructuresDeviceGroupIT.java +++ b/src/test/java/org/openepics/names/docker/StructuresDeviceGroupIT.java @@ -24,8 +24,10 @@ import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.net.HttpURLConnection; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.rest.beans.Type; @@ -37,14 +39,17 @@ import org.openepics.names.rest.beans.element.StructureElementCommandUpdate; import org.openepics.names.rest.beans.response.ResponsePageStructureElements; import org.openepics.names.util.StructureCommand; import org.openepics.names.util.StructureElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test structures endpoints and device group. @@ -117,6 +122,24 @@ class StructuresDeviceGroupIT { discipline2Uuid = approvedStructureElement.getUuid(); } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + StructuresDeviceGroupIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void equivalenceMnemonic() { // purpose diff --git a/src/test/java/org/openepics/names/docker/StructuresDeviceTypeIT.java b/src/test/java/org/openepics/names/docker/StructuresDeviceTypeIT.java index 7fab4faa..5fb65b4d 100644 --- a/src/test/java/org/openepics/names/docker/StructuresDeviceTypeIT.java +++ b/src/test/java/org/openepics/names/docker/StructuresDeviceTypeIT.java @@ -24,8 +24,10 @@ import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.net.HttpURLConnection; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.rest.beans.Type; @@ -37,14 +39,17 @@ import org.openepics.names.rest.beans.element.StructureElementCommandUpdate; import org.openepics.names.rest.beans.response.ResponsePageStructureElements; import org.openepics.names.util.StructureCommand; import org.openepics.names.util.StructureElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test structures endpoints and device type. @@ -117,6 +122,24 @@ class StructuresDeviceTypeIT { deviceGroupUuid = approvedStructureElement.getUuid(); } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + StructuresDeviceTypeIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void equivalenceMnemonic() { // purpose diff --git a/src/test/java/org/openepics/names/docker/StructuresDisciplineIT.java b/src/test/java/org/openepics/names/docker/StructuresDisciplineIT.java index 15d0bbf7..91b917ae 100644 --- a/src/test/java/org/openepics/names/docker/StructuresDisciplineIT.java +++ b/src/test/java/org/openepics/names/docker/StructuresDisciplineIT.java @@ -24,8 +24,10 @@ import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.net.HttpURLConnection; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.openepics.names.rest.beans.Type; import org.openepics.names.rest.beans.element.StructureElement; @@ -36,14 +38,17 @@ import org.openepics.names.rest.beans.element.StructureElementCommandUpdate; import org.openepics.names.rest.beans.response.ResponsePageStructureElements; import org.openepics.names.util.StructureCommand; import org.openepics.names.util.StructureElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test structures endpoints and discipline. @@ -91,6 +96,24 @@ class StructuresDisciplineIT { new DockerComposeContainer<>(new File("docker-compose-integrationtest.yml")) .waitingFor(ITUtil.NAMING, Wait.forLogMessage(".*Started NamingApplication.*", 1)); + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + StructuresDisciplineIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void equivalenceMnemonic() { // purpose diff --git a/src/test/java/org/openepics/names/docker/StructuresSubsystemIT.java b/src/test/java/org/openepics/names/docker/StructuresSubsystemIT.java index ff4d4cd5..d3f92308 100644 --- a/src/test/java/org/openepics/names/docker/StructuresSubsystemIT.java +++ b/src/test/java/org/openepics/names/docker/StructuresSubsystemIT.java @@ -24,8 +24,10 @@ import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.net.HttpURLConnection; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.rest.beans.Type; @@ -37,14 +39,17 @@ import org.openepics.names.rest.beans.element.StructureElementCommandUpdate; import org.openepics.names.rest.beans.response.ResponsePageStructureElements; import org.openepics.names.util.StructureCommand; import org.openepics.names.util.StructureElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test structures endpoints and subsystem. @@ -117,6 +122,24 @@ class StructuresSubsystemIT { systemUuid = approvedStructureElement.getUuid(); } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + StructuresSubsystemIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void equivalenceMnemonic() { // purpose diff --git a/src/test/java/org/openepics/names/docker/StructuresSystemGroupIT.java b/src/test/java/org/openepics/names/docker/StructuresSystemGroupIT.java index 8c0f4836..cc81eb88 100644 --- a/src/test/java/org/openepics/names/docker/StructuresSystemGroupIT.java +++ b/src/test/java/org/openepics/names/docker/StructuresSystemGroupIT.java @@ -25,8 +25,10 @@ import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.net.HttpURLConnection; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.openepics.names.rest.beans.Type; import org.openepics.names.rest.beans.element.StructureElement; @@ -37,14 +39,17 @@ import org.openepics.names.rest.beans.element.StructureElementCommandUpdate; import org.openepics.names.rest.beans.response.ResponsePageStructureElements; import org.openepics.names.util.StructureCommand; import org.openepics.names.util.StructureElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test structures endpoints and system group. @@ -90,6 +95,24 @@ class StructuresSystemGroupIT { new DockerComposeContainer<>(new File("docker-compose-integrationtest.yml")) .waitingFor(ITUtil.NAMING, Wait.forLogMessage(".*Started NamingApplication.*", 1)); + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + StructuresSystemGroupIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void equivalenceMnemonic() { // purpose diff --git a/src/test/java/org/openepics/names/docker/StructuresSystemIT.java b/src/test/java/org/openepics/names/docker/StructuresSystemIT.java index 0a8134c3..55ab21b7 100644 --- a/src/test/java/org/openepics/names/docker/StructuresSystemIT.java +++ b/src/test/java/org/openepics/names/docker/StructuresSystemIT.java @@ -24,8 +24,10 @@ import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.net.HttpURLConnection; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.rest.beans.Type; @@ -37,14 +39,17 @@ import org.openepics.names.rest.beans.element.StructureElementCommandUpdate; import org.openepics.names.rest.beans.response.ResponsePageStructureElements; import org.openepics.names.util.StructureCommand; import org.openepics.names.util.StructureElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test structures endpoints and system. @@ -109,6 +114,24 @@ class StructuresSystemIT { systemGroupUuid = approvedStructureElement.getUuid(); } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + StructuresSystemIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void equivalenceMnemonic() { // purpose diff --git a/src/test/java/org/openepics/names/docker/complex/NamesInstanceIndexIT.java b/src/test/java/org/openepics/names/docker/complex/NamesInstanceIndexIT.java index f59ccf32..b26279e4 100644 --- a/src/test/java/org/openepics/names/docker/complex/NamesInstanceIndexIT.java +++ b/src/test/java/org/openepics/names/docker/complex/NamesInstanceIndexIT.java @@ -19,8 +19,11 @@ package org.openepics.names.docker.complex; import java.io.File; +import java.io.IOException; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.docker.ITUtil; @@ -34,14 +37,17 @@ import org.openepics.names.rest.beans.element.StructureElement; import org.openepics.names.rest.beans.element.StructureElementCommand; import org.openepics.names.rest.beans.element.StructureElementCommandCreate; import org.openepics.names.util.NameCommand; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test names endpoints and rules for disciplines P&ID and Scientific in particular. @@ -537,6 +543,24 @@ class NamesInstanceIndexIT { deviceType_BMD_TT = approvedStructureElement.getUuid(); } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + NamesInstanceIndexIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void checkCreateInstanceIndex_Cryo() { // purpose diff --git a/src/test/java/org/openepics/names/docker/complex/NamesLegacyIT.java b/src/test/java/org/openepics/names/docker/complex/NamesLegacyIT.java index 037e4243..21f72def 100644 --- a/src/test/java/org/openepics/names/docker/complex/NamesLegacyIT.java +++ b/src/test/java/org/openepics/names/docker/complex/NamesLegacyIT.java @@ -21,8 +21,10 @@ package org.openepics.names.docker.complex; import static org.junit.jupiter.api.Assertions.assertNotNull; import java.io.File; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.docker.ITUtil; @@ -35,14 +37,17 @@ import org.openepics.names.rest.beans.element.StructureElementCommandConfirm; import org.openepics.names.rest.beans.element.StructureElementCommandCreate; import org.openepics.names.rest.beans.response.ResponsePageStructureElements; import org.openepics.names.util.StructureElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test rules for legacy name. @@ -399,6 +404,24 @@ class NamesLegacyIT { // Sys23-Sub233:Di2-Dt233-233 } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + NamesLegacyIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void legacyNameSystemStructure() { // purpose diff --git a/src/test/java/org/openepics/names/docker/complex/NamesLegacyStructuresDeleteIT.java b/src/test/java/org/openepics/names/docker/complex/NamesLegacyStructuresDeleteIT.java index 950ae7c5..4522e1e1 100644 --- a/src/test/java/org/openepics/names/docker/complex/NamesLegacyStructuresDeleteIT.java +++ b/src/test/java/org/openepics/names/docker/complex/NamesLegacyStructuresDeleteIT.java @@ -19,8 +19,10 @@ package org.openepics.names.docker.complex; import java.io.File; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.docker.ITUtil; @@ -33,14 +35,17 @@ import org.openepics.names.rest.beans.element.StructureElementCommandConfirm; import org.openepics.names.rest.beans.element.StructureElementCommandCreate; import org.openepics.names.rest.beans.response.ResponsePageStructureElements; import org.openepics.names.util.StructureElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test rules for legacy name. @@ -435,6 +440,24 @@ class NamesLegacyStructuresDeleteIT { ITUtilNames.assertExists("Sys23-Sub233:Di2-Dt233-233", Boolean.TRUE); } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + NamesLegacyStructuresDeleteIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void deleteSystemStructure() { // purpose diff --git a/src/test/java/org/openepics/names/docker/complex/NamesLegacyStructuresUpdateIT.java b/src/test/java/org/openepics/names/docker/complex/NamesLegacyStructuresUpdateIT.java index 7a58a243..90ce56b4 100644 --- a/src/test/java/org/openepics/names/docker/complex/NamesLegacyStructuresUpdateIT.java +++ b/src/test/java/org/openepics/names/docker/complex/NamesLegacyStructuresUpdateIT.java @@ -19,8 +19,10 @@ package org.openepics.names.docker.complex; import java.io.File; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.docker.ITUtil; @@ -33,14 +35,17 @@ import org.openepics.names.rest.beans.element.StructureElementCommandCreate; import org.openepics.names.rest.beans.element.StructureElementCommandUpdate; import org.openepics.names.rest.beans.response.ResponsePageStructureElements; import org.openepics.names.util.StructureElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test rules for legacy name. @@ -436,6 +441,24 @@ class NamesLegacyStructuresUpdateIT { ITUtilNames.assertExists("Sys23-Sub233:Di2-Dt233-233", Boolean.TRUE); } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH , ITUtil.JACOCO_TARGET_PREFIX + NamesLegacyStructuresUpdateIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void updateSystemStructure() { // purpose diff --git a/src/test/java/org/openepics/names/docker/complex/NamesMultipleIT.java b/src/test/java/org/openepics/names/docker/complex/NamesMultipleIT.java index 9036727c..d407ee37 100644 --- a/src/test/java/org/openepics/names/docker/complex/NamesMultipleIT.java +++ b/src/test/java/org/openepics/names/docker/complex/NamesMultipleIT.java @@ -23,8 +23,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.fail; import java.io.File; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.docker.ITUtil; @@ -40,14 +42,17 @@ import org.openepics.names.rest.beans.element.StructureElement; import org.openepics.names.rest.beans.element.StructureElementCommandCreate; import org.openepics.names.util.NameCommand; import org.openepics.names.util.NameElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test names endpoints. @@ -130,6 +135,24 @@ class NamesMultipleIT { deviceType_Cryo_FS = approvedStructureElement.getUuid(); } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH, ITUtil.JACOCO_TARGET_PREFIX + NamesMultipleIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void checkCreate() { // purpose diff --git a/src/test/java/org/openepics/names/docker/complex/StructuresLevel3IT.java b/src/test/java/org/openepics/names/docker/complex/StructuresLevel3IT.java index d395e95b..8c2d1ae8 100644 --- a/src/test/java/org/openepics/names/docker/complex/StructuresLevel3IT.java +++ b/src/test/java/org/openepics/names/docker/complex/StructuresLevel3IT.java @@ -22,8 +22,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.fail; import java.io.File; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.docker.ITUtil; @@ -32,14 +34,17 @@ import org.openepics.names.rest.beans.Type; import org.openepics.names.rest.beans.element.StructureElement; import org.openepics.names.rest.beans.element.StructureElementCommandCreate; import org.openepics.names.util.StructureElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test structures endpoints. @@ -266,6 +271,24 @@ class StructuresLevel3IT { deviceGroupBMD = approvedStructureElement.getUuid(); } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH, ITUtil.JACOCO_TARGET_PREFIX + StructuresLevel3IT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void createSubsystem() { // purpose diff --git a/src/test/java/org/openepics/names/docker/complex/StructuresMultipleIT.java b/src/test/java/org/openepics/names/docker/complex/StructuresMultipleIT.java index 7576f787..a353e820 100644 --- a/src/test/java/org/openepics/names/docker/complex/StructuresMultipleIT.java +++ b/src/test/java/org/openepics/names/docker/complex/StructuresMultipleIT.java @@ -23,8 +23,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.fail; import java.io.File; +import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openepics.names.docker.ITUtil; @@ -37,14 +39,17 @@ import org.openepics.names.rest.beans.element.StructureElementCommandCreate; import org.openepics.names.rest.beans.element.StructureElementCommandUpdate; import org.openepics.names.util.StructureCommand; import org.openepics.names.util.StructureElementUtil; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import com.github.dockerjava.api.DockerClient; + /** * Integration tests for Naming and PostgreSQL that make use of existing dockerization - * with docker-compose.yml / Dockerfile. + * with docker-compose-integrationtest.yml / Dockerfile.integrationtest. * * <p> * Purpose of this class is to test structures endpoints. @@ -120,6 +125,24 @@ class StructuresMultipleIT { deviceTypeUuid = approvedStructureElement.getUuid(); } + @AfterAll + public static void extractJacocoReport() { + // extract jacoco report from container file system + // stop jvm to make data available + + Optional<ContainerState> container = ENVIRONMENT.getContainerByServiceName(ITUtil.NAMING); + if (container.isPresent()) { + ContainerState cs = container.get(); + DockerClient dc = cs.getDockerClient(); + dc.stopContainerCmd(cs.getContainerId()).exec(); + try { + cs.copyFileFromContainer(ITUtil.JACOCO_EXEC_PATH, ITUtil.JACOCO_TARGET_PREFIX + StructuresMultipleIT.class.getSimpleName() + ITUtil.JACOCO_TARGET_SUFFIX); + } catch (Exception e) { + // proceed if file cannot be copied + } + } + } + @Test void checkCreate() { // purpose diff --git a/src/test/resources/INTEGRATIONTEST_DOCKER_RUN.md b/src/test/resources/INTEGRATIONTEST_DOCKER_RUN.md index c19b8045..a3a1ac80 100644 --- a/src/test/resources/INTEGRATIONTEST_DOCKER_RUN.md +++ b/src/test/resources/INTEGRATIONTEST_DOCKER_RUN.md @@ -21,15 +21,16 @@ All or individual integration tests (including methods) can be run in IDE as JUn ##### Maven -All integration tests can be run via Maven. +To run all integration tests via Maven. ``` mvn failsafe:integration-test -DskipITs=false ``` -Individual integration tests (classes) can also be run via Maven. +To run individual integration tests (classes) via Maven. ``` +mvn test -Dtest=org.openepics.names.docker.HealthcheckIT mvn test -Dtest=org.openepics.names.docker.NamesIT mvn test -Dtest=org.openepics.names.docker.ReportIT mvn test -Dtest=org.openepics.names.docker.DeviceGroupIT @@ -47,6 +48,23 @@ mvn test -Dtest=org.openepics.names.docker.complex.StructuresLevel3IT mvn test -Dtest=org.openepics.names.docker.complex.StructuresMultipleIT ``` +##### Code coverage + +After integration tests have been run, run below command to process coverage data. This applies for all and individual integration tests (including methods). + +``` +mvn verify +``` + +Result is available in `target/site/jacoco` folder and includes code coverage execution data and reports. + +``` +index.html +jacoco.exec +jacoco.csv +jacoco.xml +``` + ### Note ##### Build @@ -64,4 +82,5 @@ mvn test -Dtest=org.openepics.names.docker.complex.StructuresMultipleIT ##### Performance -* It may take a minute to run a test. This includes time to set up the test environment, perform the test and tear down the test environment. Setting up the test environment takes most of that time. +* It may take a minute to run an integration test. This includes time to set up the test environment, perform the test and tear down the test environment. Setting up the test environment takes most of that time. +* It may take additional time to run an integration test with code coverage. -- GitLab