diff --git a/lib/taskana-test-api/src/main/java/pro/taskana/testapi/extensions/TestContainerExtension.java b/lib/taskana-test-api/src/main/java/pro/taskana/testapi/extensions/TestContainerExtension.java index 8683aa5df..52721ae8c 100644 --- a/lib/taskana-test-api/src/main/java/pro/taskana/testapi/extensions/TestContainerExtension.java +++ b/lib/taskana-test-api/src/main/java/pro/taskana/testapi/extensions/TestContainerExtension.java @@ -11,13 +11,10 @@ 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.junit.jupiter.api.extension.ExtensionContext.Store; import org.junit.jupiter.api.extension.InvocationInterceptor; import org.junit.jupiter.api.extension.ReflectiveInvocationContext; -import org.junit.platform.commons.support.AnnotationSupport; -import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.JdbcDatabaseContainer; import pro.taskana.common.internal.configuration.DB; @@ -25,12 +22,25 @@ import pro.taskana.testapi.CleanTaskanaContext; import pro.taskana.testapi.TaskanaEngineConfigurationModifier; import pro.taskana.testapi.WithServiceProvider; -public class TestContainerExtension implements AfterAllCallback, InvocationInterceptor { +public class TestContainerExtension implements InvocationInterceptor { public static final String STORE_DATA_SOURCE = "datasource"; - public static final String STORE_CONTAINER = "container"; public static final String STORE_SCHEMA_NAME = "schemaName"; + public static final DataSource DATA_SOURCE; + + public static final DB EXECUTION_DATABASE = retrieveDatabaseFromEnv(); + + static { + Optional> container = createDockerContainer(EXECUTION_DATABASE); + if (container.isPresent()) { + container.get().start(); + DATA_SOURCE = createDataSource(container.get()); + } else { + DATA_SOURCE = createDataSourceForH2(); + } + } + @Override public T interceptTestClassConstructor( Invocation invocation, @@ -40,18 +50,8 @@ public class TestContainerExtension implements AfterAllCallback, InvocationInter Class testClass = extensionContext.getRequiredTestClass(); if (isTopLevelClass(testClass) || isAnnotated(testClass, CleanTaskanaContext.class)) { Store store = getClassLevelStore(extensionContext); - DB db = retrieveDatabaseFromEnv(); - store.put(STORE_SCHEMA_NAME, determineSchemaName(db)); - - createDockerContainer(db) - .ifPresentOrElse( - container -> { - container.start(); - store.put(STORE_DATA_SOURCE, createDataSource(container)); - store.put(STORE_CONTAINER, container); - }, - () -> store.put(STORE_DATA_SOURCE, createDataSourceForH2())); - + store.put(STORE_SCHEMA_NAME, determineSchemaName()); + store.put(STORE_DATA_SOURCE, DATA_SOURCE); } else if (TaskanaEngineConfigurationModifier.class.isAssignableFrom(testClass) || isAnnotated(testClass, WithServiceProvider.class)) { // since the implementation of TaskanaEngineConfigurationModifier implies the generation of a @@ -66,24 +66,14 @@ public class TestContainerExtension implements AfterAllCallback, InvocationInter return invocation.proceed(); } - @Override - public void afterAll(ExtensionContext context) { - Class testClass = context.getRequiredTestClass(); - if (isTopLevelClass(testClass) - || AnnotationSupport.isAnnotated(testClass, CleanTaskanaContext.class)) { - Optional.ofNullable(getClassLevelStore(context).get(STORE_CONTAINER)) - .map(JdbcDatabaseContainer.class::cast) - .ifPresent(GenericContainer::stop); - } - } - private static void copyValue(String key, Store source, Store destination) { Object value = source.get(key); destination.put(key, value); } - private static String determineSchemaName(DB db) { - return db == DB.POSTGRES ? "taskana" : "TASKANA"; + private static String determineSchemaName() { + String uniqueId = "A" + UUID.randomUUID().toString().replace("-", "_"); + return EXECUTION_DATABASE == DB.POSTGRES ? uniqueId.toLowerCase() : uniqueId; } private static DB retrieveDatabaseFromEnv() { @@ -102,11 +92,7 @@ public class TestContainerExtension implements AfterAllCallback, InvocationInter 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 ", + "jdbc:h2:mem:taskana;LOCK_MODE=0;INIT=SET COLLATION DEFAULT_de_DE", "sa", "sa"); ds.setPoolTimeToWait(50); diff --git a/lib/taskana-test-api/src/test/java/pro/taskana/testapi/tests/TestContainerExtensionTest.java b/lib/taskana-test-api/src/test/java/pro/taskana/testapi/tests/TestContainerExtensionTest.java index 92e85d20a..dd4d73e40 100644 --- a/lib/taskana-test-api/src/test/java/pro/taskana/testapi/tests/TestContainerExtensionTest.java +++ b/lib/taskana-test-api/src/test/java/pro/taskana/testapi/tests/TestContainerExtensionTest.java @@ -2,7 +2,6 @@ package pro.taskana.testapi.tests; import static org.assertj.core.api.Assertions.assertThat; -import java.sql.Connection; import javax.sql.DataSource; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -23,12 +22,19 @@ class TestContainerExtensionTest { @TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration; @Test - void should_CreateNewDataSource_For_TopLevelTestClass() { + void should_CreateDataSource_For_TopLevelTestClass() { DataSource datasource = taskanaEngineConfiguration.getDatasource(); assertThat(datasource).isNotNull(); } + @Test + void should_CreateSchemaName_For_TopLevelTestClass() { + String schemaName = taskanaEngineConfiguration.getSchemaName(); + + assertThat(schemaName).isNotNull(); + } + @Nested @TestInstance(Lifecycle.PER_CLASS) class NestedTestClass { @@ -43,6 +49,15 @@ class TestContainerExtensionTest { assertThat(nestedDataSource).isSameAs(topLevelDataSource).isNotNull(); } + + @Test + void should_ReuseSchemaName_For_NestedTestClass() { + String nestedSchemaName = taskanaEngineConfiguration.getSchemaName(); + String topLevelSchemaName = + TestContainerExtensionTest.this.taskanaEngineConfiguration.getSchemaName(); + + assertThat(nestedSchemaName).isNotNull().isEqualTo(topLevelSchemaName); + } } @Nested @@ -64,6 +79,15 @@ class TestContainerExtensionTest { assertThat(nestedDataSource).isSameAs(topLevelDataSource).isNotNull(); } + + @Test + void should_ReuseSchemaName_For_NestedTestClassWhichImplementsConfigurationModifier() { + String nestedSchemaName = taskanaEngineConfiguration.getSchemaName(); + String topLevelSchemaName = + TestContainerExtensionTest.this.taskanaEngineConfiguration.getSchemaName(); + + assertThat(nestedSchemaName).isNotNull().isEqualTo(topLevelSchemaName); + } } @CleanTaskanaContext @@ -74,21 +98,21 @@ class TestContainerExtensionTest { @TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration; @Test - void should_CreateNewDataSource_For_NestedTestAnnotatedWithCleanTaskanaContext() - throws Exception { + void should_ReuseDataSource_For_NestedTestAnnotatedWithCleanTaskanaContext() { DataSource nestedDataSource = taskanaEngineConfiguration.getDatasource(); DataSource topLevelDataSource = TestContainerExtensionTest.this.taskanaEngineConfiguration.getDatasource(); - String nestedDataSourceUrl; - String topLevelDataSourceUrl; - try (Connection connection = nestedDataSource.getConnection()) { - nestedDataSourceUrl = connection.getMetaData().getURL(); - } - try (Connection connection = topLevelDataSource.getConnection()) { - topLevelDataSourceUrl = connection.getMetaData().getURL(); - } - assertThat(nestedDataSourceUrl).isNotEqualTo(topLevelDataSourceUrl).isNotNull(); + assertThat(nestedDataSource).isNotNull().isSameAs(topLevelDataSource); + } + + @Test + void should_GenerateNewSchemaName_For_NestedTestAnnotatedWithCleanTaskanaContext() { + String nestedSchemaName = taskanaEngineConfiguration.getSchemaName(); + String topLevelSchemaName = + TestContainerExtensionTest.this.taskanaEngineConfiguration.getSchemaName(); + + assertThat(nestedSchemaName).isNotNull().isNotEqualTo(topLevelSchemaName); } @CleanTaskanaContext @@ -99,31 +123,35 @@ class TestContainerExtensionTest { @TaskanaInject TaskanaEngineConfiguration taskanaEngineConfiguration; @Test - void should_CreateNewDataSource_For_NestedTestAnnotatedWithCleanTaskanaContext() - throws Exception { + void should_ReuseDataSource_For_NestedTestAnnotatedWithCleanTaskanaContext() { DataSource nestedNestedDataSource = taskanaEngineConfiguration.getDatasource(); DataSource nestedDataSource = - NestedTestClassAnnotatedWithCleanTaskanaContext.this.taskanaEngineConfiguration + NestedNestedTestClassAnnotatedWithCleanTaskanaContext.this.taskanaEngineConfiguration .getDatasource(); DataSource topLevelDataSource = TestContainerExtensionTest.this.taskanaEngineConfiguration.getDatasource(); - String nestedNestedDataSourceUrl; - String nestedDataSourceUrl; - String topLevelDataSourceUrl; - try (Connection connection = nestedNestedDataSource.getConnection()) { - nestedNestedDataSourceUrl = connection.getMetaData().getURL(); - } - try (Connection connection = nestedDataSource.getConnection()) { - nestedDataSourceUrl = connection.getMetaData().getURL(); - } - try (Connection connection = topLevelDataSource.getConnection()) { - topLevelDataSourceUrl = connection.getMetaData().getURL(); - } - assertThat(nestedNestedDataSourceUrl) - .isNotEqualTo(nestedDataSourceUrl) - .isNotEqualTo(topLevelDataSourceUrl) - .isNotNull(); + assertThat(nestedNestedDataSource) + .isNotNull() + .isSameAs(topLevelDataSource) + .isSameAs(nestedDataSource); + } + + @Test + void should_GenerateNewSchemaName_For_NestedTestAnnotatedWithCleanTaskanaContext() { + String nestedNestedSchemaName = taskanaEngineConfiguration.getSchemaName(); + String nestedSchemaName = + NestedTestClassAnnotatedWithCleanTaskanaContext.this.taskanaEngineConfiguration + .getSchemaName(); + String topLevelSchemaName = + TestContainerExtensionTest.this.taskanaEngineConfiguration.getSchemaName(); + + assertThat(nestedSchemaName).isNotNull().isNotEqualTo(topLevelSchemaName); + + assertThat(nestedNestedSchemaName) + .isNotNull() + .isNotEqualTo(nestedSchemaName) + .isNotEqualTo(topLevelSchemaName); } } } @@ -142,12 +170,21 @@ class TestContainerExtensionTest { } @Test - void should_CreateNewDataSource_For_NestedTestAnnotatedWithCleanTaskanaContext() { + void should_ReuseNewDataSource_For_NestedTestAnnotatedWithCleanTaskanaContext() { DataSource nestedDataSource = taskanaEngineConfiguration.getDatasource(); DataSource topLevelDataSource = TestContainerExtensionTest.this.taskanaEngineConfiguration.getDatasource(); - assertThat(nestedDataSource).isNotSameAs(topLevelDataSource).isNotNull(); + assertThat(nestedDataSource).isNotNull().isSameAs(topLevelDataSource); + } + + @Test + void should_GenerateNewSchemaName_For_NestedTestAnnotatedWithCleanTaskanaContext() { + String nestedSchemaName = taskanaEngineConfiguration.getSchemaName(); + String topLevelSchemaName = + TestContainerExtensionTest.this.taskanaEngineConfiguration.getSchemaName(); + + assertThat(nestedSchemaName).isNotNull().isNotEqualTo(topLevelSchemaName); } } @@ -168,5 +205,14 @@ class TestContainerExtensionTest { assertThat(nestedDataSource).isSameAs(topLevelDataSource).isNotNull(); } + + @Test + void should_ReuseSchemaName_For_NestedTestClassWithServiceProvider() { + String nestedSchemaName = taskanaEngineConfiguration.getSchemaName(); + String topLevelSchemaName = + TestContainerExtensionTest.this.taskanaEngineConfiguration.getSchemaName(); + + assertThat(nestedSchemaName).isNotNull().isEqualTo(topLevelSchemaName); + } } }