TSK-1685: added testcontainers extension
This commit is contained in:
parent
af47d1ad14
commit
c742407288
|
@ -250,11 +250,11 @@ jobs:
|
|||
- H2
|
||||
include:
|
||||
- module: taskana-core
|
||||
database: POSTGRES_10
|
||||
database: POSTGRES
|
||||
- module: taskana-core
|
||||
database: DB2_11_1
|
||||
database: DB2
|
||||
- module: taskana-rest-spring-example-boot
|
||||
database: DB2_11_1
|
||||
database: DB2
|
||||
steps:
|
||||
- name: Git checkout
|
||||
uses: actions/checkout@v2.3.4
|
||||
|
@ -281,6 +281,8 @@ jobs:
|
|||
run: ./mvnw -B validate -pl :taskana-rest-spring
|
||||
- name: Test
|
||||
run: ./mvnw -B verify -pl :${{matrix.module}} -Dcheckstyle.skip
|
||||
env:
|
||||
db.type: ${{ matrix.database }}
|
||||
- name: Upload JaCoCo Report
|
||||
if: matrix.database == 'H2'
|
||||
uses: actions/upload-artifact@v2
|
||||
|
|
|
@ -106,6 +106,28 @@
|
|||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>db2</artifactId>
|
||||
<version>${version.testcontainers}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${version.testcontainers}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- TEST DEPENDENCIES -->
|
||||
<dependency>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package org.junit.rules;
|
||||
|
||||
// Testcontainers currently requires junit4 as a runtime dependency.
|
||||
// Because we use junit5 we have to use this workaround to "simulate" the classes testcontainers
|
||||
// requires in the classpath. They are not used unless a junit4 runtime is used.
|
||||
// See: https://github.com/testcontainers/testcontainers-java/issues/970#issuecomment-625044008
|
||||
@SuppressWarnings("unused")
|
||||
public interface TestRule {}
|
|
@ -0,0 +1,8 @@
|
|||
package org.junit.runners.model;
|
||||
|
||||
// Testcontainers currently requires junit4 as a runtime dependency.
|
||||
// Because we use junit5 we have to use this workaround to "simulate" the classes testcontainers
|
||||
// requires in the classpath. They are not used unless a junit4 runtime is used.
|
||||
// See: https://github.com/testcontainers/testcontainers-java/issues/970#issuecomment-625044008
|
||||
@SuppressWarnings("unused")
|
||||
public interface Statement {}
|
|
@ -0,0 +1,136 @@
|
|||
package pro.taskana.common.test.config;
|
||||
|
||||
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import javax.sql.DataSource;
|
||||
import org.apache.ibatis.datasource.pooled.PooledDataSource;
|
||||
import org.junit.jupiter.api.extension.AfterAllCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.testcontainers.containers.Db2Container;
|
||||
import org.testcontainers.containers.JdbcDatabaseContainer;
|
||||
import org.testcontainers.containers.PostgreSQLContainer;
|
||||
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
|
||||
import org.testcontainers.utility.DockerImageName;
|
||||
|
||||
import pro.taskana.common.internal.configuration.DB;
|
||||
|
||||
public class TestContainerExtension implements AfterAllCallback {
|
||||
|
||||
private final DataSource dataSource;
|
||||
private final String schemaName;
|
||||
private final JdbcDatabaseContainer<?> container;
|
||||
|
||||
public TestContainerExtension() {
|
||||
DB db = getTestDatabase();
|
||||
Optional<JdbcDatabaseContainer<?>> container = createDockerContainer(db);
|
||||
if (container.isPresent()) {
|
||||
this.container = container.get();
|
||||
this.container.start();
|
||||
dataSource = createDataSource(this.container);
|
||||
} else {
|
||||
dataSource = createDataSourceForH2();
|
||||
this.container = null;
|
||||
}
|
||||
schemaName = determineSchemaName(db);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext context) {
|
||||
if (container != null) {
|
||||
container.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public DataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
public String getSchemaName() {
|
||||
return schemaName;
|
||||
}
|
||||
|
||||
private DB getTestDatabase() {
|
||||
String property = System.getenv("db.type");
|
||||
DB db;
|
||||
try {
|
||||
db = DB.valueOf(property);
|
||||
} catch (Exception ex) {
|
||||
db = DB.H2;
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
private static String determineSchemaName(DB db) {
|
||||
return db == DB.POSTGRES ? "taskana" : "TASKANA";
|
||||
}
|
||||
|
||||
private static DataSource createDataSource(JdbcDatabaseContainer<?> container) {
|
||||
PooledDataSource ds =
|
||||
new PooledDataSource(
|
||||
Thread.currentThread().getContextClassLoader(),
|
||||
container.getDriverClassName(),
|
||||
container.getJdbcUrl(),
|
||||
container.getUsername(),
|
||||
container.getPassword());
|
||||
ds.setPoolTimeToWait(50);
|
||||
ds.forceCloseAll(); // otherwise, the MyBatis pool is not initialized correctly
|
||||
return ds;
|
||||
}
|
||||
|
||||
private static Optional<JdbcDatabaseContainer<?>> createDockerContainer(DB db) {
|
||||
switch (db) {
|
||||
case DB2:
|
||||
return Optional.of(
|
||||
new Db2Container(
|
||||
DockerImageName.parse("taskana/db2:11.1")
|
||||
.asCompatibleSubstituteFor("ibmcom/db2"))
|
||||
.waitingFor(
|
||||
new LogMessageWaitStrategy()
|
||||
.withRegEx(".*DB2START processing was successful.*")
|
||||
.withStartupTimeout(Duration.of(60, SECONDS)))
|
||||
.withUsername("db2inst1")
|
||||
.withPassword("db2inst1-pwd")
|
||||
.withDatabaseName("TSKDB"));
|
||||
case POSTGRES:
|
||||
return Optional.of(
|
||||
new PostgreSQLContainer<>(DockerImageName.parse("postgres:10"))
|
||||
.withUsername("postgres")
|
||||
.withPassword("postgres")
|
||||
.withDatabaseName("postgres")
|
||||
.withCommand(
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"localedef -i de_DE -c -f UTF-8 -A /usr/share/locale/locale.alias de_DE.UTF-8 "
|
||||
+ "&& export LANG=de_DE.UTF-8 "
|
||||
+ "&& ./docker-entrypoint.sh postgres -c fsync=off")
|
||||
.waitingFor(
|
||||
new LogMessageWaitStrategy()
|
||||
.withRegEx(".*Datenbanksystem ist bereit, um Verbindungen anzunehmen.*\\s")
|
||||
.withTimes(2)
|
||||
.withStartupTimeout(Duration.of(60, SECONDS))));
|
||||
default:
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private static DataSource createDataSourceForH2() {
|
||||
PooledDataSource ds =
|
||||
new PooledDataSource(
|
||||
Thread.currentThread().getContextClassLoader(),
|
||||
"org.h2.Driver",
|
||||
"jdbc:h2:mem:"
|
||||
+ UUID.randomUUID()
|
||||
+ ";LOCK_MODE=0;"
|
||||
+ "INIT=CREATE SCHEMA IF NOT EXISTS TASKANA\\;"
|
||||
+ "SET COLLATION DEFAULT_de_DE ",
|
||||
"sa",
|
||||
"sa");
|
||||
ds.setPoolTimeToWait(50);
|
||||
ds.forceCloseAll(); // otherwise, the MyBatis pool is not initialized correctly
|
||||
|
||||
return ds;
|
||||
}
|
||||
}
|
|
@ -19,8 +19,8 @@ export TOP_PID=$$
|
|||
#H
|
||||
#H database:
|
||||
#H - H2
|
||||
#H - DB2_11_1
|
||||
#H - POSTGRES_10
|
||||
#H - DB2 | DB2_11_1
|
||||
#H - POSTGRES | POSTGRES_10
|
||||
# Arguments:
|
||||
# $1: exit code
|
||||
function helpAndExit() {
|
||||
|
@ -34,10 +34,10 @@ function helpAndExit() {
|
|||
function mapDBToDockerComposeServiceName() {
|
||||
[[ -z "$1" || "$1" == "H2" ]] && return
|
||||
case "$1" in
|
||||
DB2_11_1)
|
||||
DB2|DB2_11_1)
|
||||
echo "taskana-db2_11-1"
|
||||
;;
|
||||
POSTGRES_10)
|
||||
POSTGRES|POSTGRES_10)
|
||||
echo "taskana-postgres_10"
|
||||
;;
|
||||
*)
|
||||
|
@ -54,7 +54,7 @@ function main() {
|
|||
H2)
|
||||
[[ -f "$propFile" ]] && rm "$propFile"
|
||||
;;
|
||||
DB2_11_1)
|
||||
DB2|DB2_11_1)
|
||||
docker-compose -f $scriptDir/docker-compose.yml up -d "$(mapDBToDockerComposeServiceName "$1")"
|
||||
|
||||
echo 'jdbcDriver=com.ibm.db2.jcc.DB2Driver' > $propFile
|
||||
|
@ -63,7 +63,7 @@ function main() {
|
|||
echo 'dbPassword=db2inst1-pwd' >> $propFile
|
||||
echo 'schemaName=TASKANA' >> $propFile
|
||||
;;
|
||||
POSTGRES_10)
|
||||
POSTGRES|POSTGRES_10)
|
||||
docker-compose -f $scriptDir/docker-compose.yml up -d "$(mapDBToDockerComposeServiceName "$1")"
|
||||
|
||||
echo 'jdbcDriver=org.postgresql.Driver' > $propFile
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
package acceptance;
|
||||
|
||||
import org.junit.jupiter.api.extension.AfterAllCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||
import org.junit.jupiter.api.extension.ParameterResolver;
|
||||
|
||||
import pro.taskana.common.test.config.DataSourceGenerator;
|
||||
import pro.taskana.common.test.config.TestContainerExtension;
|
||||
|
||||
public class TaskanaIntegrationTestExtension implements ParameterResolver {
|
||||
public class TaskanaIntegrationTestExtension implements ParameterResolver, AfterAllCallback {
|
||||
|
||||
private final TaskanaDependencyInjectionExtension dependencyInjectionExtension;
|
||||
private final TestContainerExtension testContainerExtension;
|
||||
|
||||
public TaskanaIntegrationTestExtension() throws Exception {
|
||||
testContainerExtension = new TestContainerExtension();
|
||||
dependencyInjectionExtension =
|
||||
new TaskanaDependencyInjectionExtension(DataSourceGenerator.getDataSource());
|
||||
new TaskanaDependencyInjectionExtension(testContainerExtension.getDataSource());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -29,4 +32,9 @@ public class TaskanaIntegrationTestExtension implements ParameterResolver {
|
|||
throws ParameterResolutionException {
|
||||
return dependencyInjectionExtension.resolveParameter(parameterContext, extensionContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext context) {
|
||||
testContainerExtension.afterAll(context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
taskana/db2:11.1
|
1
pom.xml
1
pom.xml
|
@ -88,6 +88,7 @@
|
|||
<version.jacoco>0.8.7</version.jacoco>
|
||||
<version.slf4j-test>1.2.0</version.slf4j-test>
|
||||
<version.auto-restdocs>2.0.11</version.auto-restdocs>
|
||||
<version.testcontainers>1.16.0</version.testcontainers>
|
||||
|
||||
<!-- AspectJ dependencies -->
|
||||
<version.aspectj-maven-plugin>1.14.0</version.aspectj-maven-plugin>
|
||||
|
|
Loading…
Reference in New Issue