diff --git a/build.gradle.kts b/build.gradle.kts
index b856f1a..b95e532 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -42,9 +42,11 @@ dependencies {
api(libs.kafka.client)
api(libs.hikari)
+ testImplementation(libs.logback)
testImplementation(libs.kotest.assertions.core)
testImplementation(libs.kotest.runner.junit5)
testImplementation(libs.jedis)
testImplementation(libs.testcontainers.mysql)
+ testImplementation(libs.testcontainers.redis)
testImplementation(libs.mysql.connector.java)
}
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
index 6c5c44e..6167448 100644
--- a/buildSrc/build.gradle.kts
+++ b/buildSrc/build.gradle.kts
@@ -1,7 +1,14 @@
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+
plugins {
`kotlin-dsl`
}
+kotlin {
+ jvmToolchain(11)
+ compilerOptions.jvmTarget.set(JvmTarget.JVM_11)
+}
+
repositories {
mavenCentral()
}
diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts
new file mode 100644
index 0000000..7913224
--- /dev/null
+++ b/buildSrc/settings.gradle.kts
@@ -0,0 +1 @@
+rootProject.name="buildSrc"
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index ab72ccd..dbde34d 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -9,12 +9,14 @@ jedis = { module = "redis.clients:jedis", version = "4.3.1" }
mysql-connector-java = { module = "mysql:mysql-connector-java", version = "8.0.33" }
kafka-client = { module = "org.apache.kafka:kafka-clients", version = "3.5.1" }
elastic-client = { module = "co.elastic.clients:elasticsearch-java", version = "7.17.21" }
+logback = { module = "ch.qos.logback:logback-classic", version = "1.5.6" }
testcontainers-elastic = { module = "org.testcontainers:elasticsearch", version.ref = "testcontainers" }
testcontainers-mysql = { module = "org.testcontainers:mysql", version.ref = "testcontainers" }
testcontainers-kafka = { module = "org.testcontainers:kafka", version.ref = "testcontainers" }
testcontainers-jdbc = { module = "org.testcontainers:jdbc", version.ref = "testcontainers" }
testcontainers-core = { module = "org.testcontainers:testcontainers", version.ref = "testcontainers" }
+testcontainers-redis = { module = "com.redis:testcontainers-redis", version = "1.7.0" }
kotest-runner-junit5 = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" }
kotest-assertions-core = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" }
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index ac72c34..a441313 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/src/main/java/io/kotest/extensions/testcontainers/RuntimeSqlException.java b/src/main/java/io/kotest/extensions/testcontainers/RuntimeSqlException.java
deleted file mode 100644
index 01553cf..0000000
--- a/src/main/java/io/kotest/extensions/testcontainers/RuntimeSqlException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package io.kotest.extensions.testcontainers;
-
-@Deprecated
-class RuntimeSqlException extends RuntimeException {
-
- private static final long serialVersionUID = 5224696788505678598L;
-
- public RuntimeSqlException() {
- super();
- }
-
- public RuntimeSqlException(String message) {
- super(message);
- }
-
- public RuntimeSqlException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public RuntimeSqlException(Throwable cause) {
- super(cause);
- }
-
-}
diff --git a/src/main/java/io/kotest/extensions/testcontainers/ScriptRunner.java b/src/main/java/io/kotest/extensions/testcontainers/ScriptRunner.java
deleted file mode 100644
index 444d7c1..0000000
--- a/src/main/java/io/kotest/extensions/testcontainers/ScriptRunner.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright 2009-2021 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package io.kotest.extensions.testcontainers;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.BufferedReader;
-import java.io.Reader;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * This is an internal testing utility.
- * You are welcome to use this class for your own purposes,
- * but if there is some feature/enhancement you need for your own usage,
- * please make and modify your own copy instead of sending us an enhancement request.
- *
- * @author Clinton Begin
- * @deprecated
- */
-@Deprecated
-public class ScriptRunner {
-
- private static final String LINE_SEPARATOR = System.lineSeparator();
-
- private static final String DEFAULT_DELIMITER = ";";
-
- private static final Pattern DELIMITER_PATTERN = Pattern.compile("^\\s*((--)|(//))?\\s*(//)?\\s*@DELIMITER\\s+([^\\s]+)", Pattern.CASE_INSENSITIVE);
-
- private final Connection connection;
-
- private boolean stopOnError;
- private boolean throwWarning;
- private boolean autoCommit;
- private boolean sendFullScript;
- private boolean removeCRs;
- private boolean escapeProcessing = true;
-
- private static final Logger LOGGER = LoggerFactory.getLogger(ScriptRunner.class);
-
- private String delimiter = DEFAULT_DELIMITER;
- private boolean fullLineDelimiter;
-
- public ScriptRunner(Connection connection) {
- this.connection = connection;
- }
-
- public void setStopOnError(boolean stopOnError) {
- this.stopOnError = stopOnError;
- }
-
- public void setThrowWarning(boolean throwWarning) {
- this.throwWarning = throwWarning;
- }
-
- public void setAutoCommit(boolean autoCommit) {
- this.autoCommit = autoCommit;
- }
-
- public void setSendFullScript(boolean sendFullScript) {
- this.sendFullScript = sendFullScript;
- }
-
- public void setRemoveCRs(boolean removeCRs) {
- this.removeCRs = removeCRs;
- }
-
- /**
- * Sets the escape processing.
- *
- * @param escapeProcessing the new escape processing
- * @since 3.1.1
- */
- public void setEscapeProcessing(boolean escapeProcessing) {
- this.escapeProcessing = escapeProcessing;
- }
-
- public void setDelimiter(String delimiter) {
- this.delimiter = delimiter;
- }
-
- public void setFullLineDelimiter(boolean fullLineDelimiter) {
- this.fullLineDelimiter = fullLineDelimiter;
- }
-
- public void runScript(Reader reader) {
- setAutoCommit();
-
- try {
- if (sendFullScript) {
- executeFullScript(reader);
- } else {
- executeLineByLine(reader);
- }
- } finally {
- rollbackConnection();
- }
- }
-
- private void executeFullScript(Reader reader) {
- StringBuilder script = new StringBuilder();
- try {
- BufferedReader lineReader = new BufferedReader(reader);
- String line;
- while ((line = lineReader.readLine()) != null) {
- script.append(line);
- script.append(LINE_SEPARATOR);
- }
- String command = script.toString();
- LOGGER.debug(command);
- executeStatement(command);
- commitConnection();
- } catch (Exception e) {
- String message = "Error executing: " + script + ". Cause: " + e;
- LOGGER.error(message);
- throw new RuntimeSqlException(message, e);
- }
- }
-
- private void executeLineByLine(Reader reader) {
- StringBuilder command = new StringBuilder();
- try {
- BufferedReader lineReader = new BufferedReader(reader);
- String line;
- while ((line = lineReader.readLine()) != null) {
- handleLine(command, line);
- }
- commitConnection();
- checkForMissingLineTerminator(command);
- } catch (Exception e) {
- String message = "Error executing: " + command + ". Cause: " + e;
- LOGGER.error(message);
- throw new RuntimeSqlException(message, e);
- }
- }
-
- private void setAutoCommit() {
- try {
- if (autoCommit != connection.getAutoCommit()) {
- connection.setAutoCommit(autoCommit);
- }
- } catch (Exception t) {
- throw new RuntimeSqlException("Could not set AutoCommit to " + autoCommit + ". Cause: " + t, t);
- }
- }
-
- private void commitConnection() {
- try {
- if (!connection.getAutoCommit()) {
- connection.commit();
- }
- } catch (Exception t) {
- throw new RuntimeSqlException("Could not commit transaction. Cause: " + t, t);
- }
- }
-
- private void rollbackConnection() {
- try {
- if (!connection.getAutoCommit()) {
- connection.rollback();
- }
- } catch (Exception t) {
- // ignore
- }
- }
-
- private void checkForMissingLineTerminator(StringBuilder command) {
- if (command != null && command.toString().trim().length() > 0) {
- throw new RuntimeSqlException("Line missing end-of-line terminator (" + delimiter + ") => " + command);
- }
- }
-
- private void handleLine(StringBuilder command, String line) throws SQLException {
- String trimmedLine = line.trim();
- if (lineIsComment(trimmedLine)) {
- Matcher matcher = DELIMITER_PATTERN.matcher(trimmedLine);
- if (matcher.find()) {
- delimiter = matcher.group(5);
- }
- LOGGER.debug(trimmedLine);
- } else if (commandReadyToExecute(trimmedLine)) {
- command.append(line, 0, line.lastIndexOf(delimiter));
- command.append(LINE_SEPARATOR);
- LOGGER.debug(command.toString());
- executeStatement(command.toString());
- command.setLength(0);
- } else if (trimmedLine.length() > 0) {
- command.append(line);
- command.append(LINE_SEPARATOR);
- }
- }
-
- private boolean lineIsComment(String trimmedLine) {
- return trimmedLine.startsWith("//") || trimmedLine.startsWith("--");
- }
-
- private boolean commandReadyToExecute(String trimmedLine) {
- // issue #561 remove anything after the delimiter
- return !fullLineDelimiter && trimmedLine.contains(delimiter) || fullLineDelimiter && trimmedLine.equals(delimiter);
- }
-
- private void executeStatement(String command) throws SQLException {
- try (Statement statement = connection.createStatement()) {
- statement.setEscapeProcessing(escapeProcessing);
- String sql = command;
- if (removeCRs) {
- sql = sql.replace("\r\n", "\n");
- }
- try {
- boolean hasResults = statement.execute(sql);
- while (!(!hasResults && statement.getUpdateCount() == -1)) {
- checkWarnings(statement);
- printResults(statement, hasResults);
- hasResults = statement.getMoreResults();
- }
- } catch (SQLWarning e) {
- throw e;
- } catch (SQLException e) {
- if (stopOnError) {
- throw e;
- } else {
- String message = "Error executing: " + command + ". Cause: " + e;
- LOGGER.error(message);
- }
- }
- }
- }
-
- private void checkWarnings(Statement statement) throws SQLException {
- if (!throwWarning) {
- return;
- }
- // In Oracle, CREATE PROCEDURE, FUNCTION, etc. returns warning
- // instead of throwing exception if there is compilation error.
- SQLWarning warning = statement.getWarnings();
- if (warning != null) {
- throw warning;
- }
- }
-
- private void printResults(Statement statement, boolean hasResults) {
- if (!hasResults) {
- return;
- }
- try (ResultSet rs = statement.getResultSet()) {
- ResultSetMetaData md = rs.getMetaData();
- int cols = md.getColumnCount();
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < cols; i++) {
- String name = md.getColumnLabel(i + 1);
- sb.append(name + "\t");
- }
- sb.append(System.lineSeparator());
- while (rs.next()) {
- for (int i = 0; i < cols; i++) {
- String value = rs.getString(i + 1);
- sb.append(value + "\t");
- }
- sb.append(System.lineSeparator());
- LOGGER.debug(sb.toString());
- }
- } catch (SQLException e) {
- LOGGER.error("Error printing results: " + e.getMessage());
- }
- }
-}
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/ContainerExtension.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/ContainerExtension.kt
index 4778a81..f25f3a3 100644
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/ContainerExtension.kt
+++ b/src/main/kotlin/io/kotest/extensions/testcontainers/ContainerExtension.kt
@@ -56,14 +56,14 @@ import org.testcontainers.containers.GenericContainer
class ContainerExtension>(
private val container: T,
private val mode: ContainerLifecycleMode = ContainerLifecycleMode.Project,
- private val beforeStart: () -> Unit = {},
- private val afterStart: () -> Unit = {},
+ private val beforeStart: T.() -> Unit = {},
+ private val afterStart: T.() -> Unit = {},
private val beforeTest: suspend (TestCase) -> Unit = { _ -> },
private val afterTest: suspend (TestCase) -> Unit = { _ -> },
private val beforeSpec: suspend (Spec) -> Unit = { _ -> },
private val afterSpec: suspend (Spec) -> Unit = { _ -> },
- private val beforeShutdown: () -> Unit = {},
- private val afterShutdown: () -> Unit = {},
+ private val beforeShutdown: suspend T.() -> Unit = {},
+ private val afterShutdown: suspend T.() -> Unit = {},
) : MountableExtension,
AfterProjectListener,
BeforeTestListener,
@@ -75,14 +75,14 @@ class ContainerExtension>(
* Mounts the container, starting it if necessary. The [configure] block will be invoked
* every time the container is mounted, and after the container has started.
*/
- override fun mount(configure: T.() -> Unit): T {
- if (!container.isRunning) {
+ override fun mount(configure: T.() -> Unit): T = container.apply{
+ if (!isRunning) {
beforeStart()
- container.start()
+ start()
afterStart()
}
- container.configure()
- return container
+
+ configure()
}
override suspend fun beforeTest(testCase: TestCase) {
@@ -108,9 +108,9 @@ class ContainerExtension>(
private suspend fun close() {
withContext(Dispatchers.IO) {
- beforeShutdown()
+ container.beforeShutdown()
container.stop()
- afterShutdown()
+ container.afterShutdown()
}
}
}
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/DockerComposeContainersExtension.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/DockerComposeContainersExtension.kt
deleted file mode 100644
index 494fade..0000000
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/DockerComposeContainersExtension.kt
+++ /dev/null
@@ -1,99 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import io.kotest.core.extensions.MountableExtension
-import io.kotest.core.listeners.AfterSpecListener
-import io.kotest.core.listeners.TestListener
-import io.kotest.core.spec.Spec
-import io.kotest.core.test.TestCase
-import io.kotest.core.test.TestResult
-import io.kotest.core.test.TestType
-import io.kotest.core.test.isRootTest
-import java.io.File
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.withContext
-import org.testcontainers.lifecycle.TestLifecycleAware
-import java.util.Optional
-import org.testcontainers.containers.DockerComposeContainer
-
-@Deprecated("use DockerComposeContainerExtension")
-class DockerComposeContainersExtension>(
- private val container: DockerComposeContainer,
- private val lifecycleMode: LifecycleMode = LifecycleMode.Spec,
-) : MountableExtension, TestListener, AfterSpecListener {
-
- companion object {
- operator fun invoke(composeFile: File): DockerComposeContainersExtension> =
- DockerComposeContainersExtension(DockerComposeContainer(composeFile))
-
- operator fun invoke(
- composeFile: File,
- lifecycleMode: LifecycleMode
- ): DockerComposeContainersExtension> =
- DockerComposeContainersExtension(DockerComposeContainer(composeFile), lifecycleMode)
- }
-
- override fun mount(configure: T.() -> Unit): T {
- @Suppress("UNCHECKED_CAST")
- (container as T).configure()
- if (lifecycleMode == LifecycleMode.Spec) {
- container.start()
- }
- return container
- }
-
- override suspend fun afterSpec(spec: Spec) {
- withContext(Dispatchers.IO) {
- stop()
- }
- }
-
- override suspend fun beforeAny(testCase: TestCase) {
- val every = lifecycleMode == LifecycleMode.EveryTest
- val root = lifecycleMode == LifecycleMode.Root && testCase.isRootTest()
- val leaf = lifecycleMode == LifecycleMode.Leaf && testCase.type == TestType.Test
- if (every || root || leaf) {
- lifecycleBeforeTest(testCase)
- start()
- }
- }
-
- override suspend fun afterAny(testCase: TestCase, result: TestResult) {
- val every = lifecycleMode == LifecycleMode.EveryTest
- val root = lifecycleMode == LifecycleMode.Root && testCase.isRootTest()
- val leaf = lifecycleMode == LifecycleMode.Leaf && testCase.type == TestType.Test
- if (every || root || leaf) {
- lifecycleAfterTest(testCase, result)
- stop()
- }
- }
-
- private suspend fun start() {
- withContext(Dispatchers.IO) {
- container.start()
- }
- }
-
- private suspend fun stop() {
- withContext(Dispatchers.IO) {
- container.stop()
- }
- }
-
- private suspend fun lifecycleBeforeTest(testCase: TestCase) {
- when (container) {
- is TestLifecycleAware -> withContext(Dispatchers.IO) {
- container.beforeTest(testCase.toTestDescription())
- }
- }
- }
-
- private suspend fun lifecycleAfterTest(testCase: TestCase, result: TestResult) {
- when (container) {
- is TestLifecycleAware -> withContext(Dispatchers.IO) {
- container.afterTest(
- testCase.toTestDescription(), Optional.ofNullable(result.errorOrNull)
- )
- }
- }
- }
-}
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/Extensions.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/Extensions.kt
index 637bfdc..57c3956 100644
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/Extensions.kt
+++ b/src/main/kotlin/io/kotest/extensions/testcontainers/Extensions.kt
@@ -1,6 +1,5 @@
package io.kotest.extensions.testcontainers
-import io.kotest.core.TestConfiguration
import org.testcontainers.lifecycle.Startable
fun T.perTest(): StartablePerTestListener = StartablePerTestListener(this)
@@ -8,25 +7,3 @@ fun T.perTest(): StartablePerTestListener = StartablePerTestL
fun T.perSpec(): StartablePerSpecListener = StartablePerSpecListener(this)
fun T.perProject(): StartablePerProjectListener = StartablePerProjectListener(this)
-
-@Deprecated("use perProject()")
-fun T.perProject(containerName: String): StartablePerProjectListener =
- StartablePerProjectListener(this)
-
-@Deprecated("use perTest")
-fun TestConfiguration.configurePerTest(startable: T): T {
- listener(StartablePerTestListener(startable))
- return startable
-}
-
-@Deprecated("use perSpec")
-fun TestConfiguration.configurePerSpec(startable: T): T {
- listener(StartablePerSpecListener(startable))
- return startable
-}
-
-@Deprecated("use perProject")
-fun TestConfiguration.configurePerProject(startable: T, containerName: String): T {
- listener(StartablePerProjectListener(startable))
- return startable
-}
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/JdbcDatabaseContainerExtension.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/JdbcDatabaseContainerExtension.kt
index 36d168c..ff10b53 100644
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/JdbcDatabaseContainerExtension.kt
+++ b/src/main/kotlin/io/kotest/extensions/testcontainers/JdbcDatabaseContainerExtension.kt
@@ -14,6 +14,7 @@ import io.kotest.core.test.TestResult
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.testcontainers.containers.JdbcDatabaseContainer
+import org.testcontainers.lifecycle.Startable
/**
* A Kotest [MountableExtension] for [JdbcDatabaseContainer]s which is started the first time they are
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtension.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtension.kt
deleted file mode 100644
index 4f45929..0000000
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtension.kt
+++ /dev/null
@@ -1,118 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import com.zaxxer.hikari.HikariDataSource
-import io.kotest.core.extensions.MountableExtension
-import io.kotest.core.listeners.AfterSpecListener
-import io.kotest.core.listeners.TestListener
-import io.kotest.core.spec.Spec
-import io.kotest.core.test.TestCase
-import io.kotest.core.test.TestResult
-import io.kotest.core.test.TestType
-import io.kotest.core.test.isRootTest
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.withContext
-import org.testcontainers.containers.JdbcDatabaseContainer
-import java.sql.Connection
-import javax.sql.DataSource
-
-/**
- * A Kotest [MountableExtension] for [JdbcDatabaseContainer]s that will launch the container
- * upon install, and close after the spec has completed.
- *
- * This extension will create a pooled [HikariDataSource] attached to the database and
- * return that to the user as the materialized value.
- *
- * The pool can be configured in the mount configure method.
- *
- * Note: This extension requires Kotest 5.0+
- *
- * @param container the specific test container type
- * @param lifecycleMode determines how the container should be reset between tests
- *
- * @since 1.1.0
- */
-@Deprecated("use JdbcDatabaseContainerExtension")
-class JdbcTestContainerExtension(
- private val container: JdbcDatabaseContainer,
- private val lifecycleMode: LifecycleMode = LifecycleMode.Spec,
-) : MountableExtension, AfterSpecListener, TestListener {
-
- private val ds = SettableDataSource(null)
- private var configure: TestContainerHikariConfig.() -> Unit = {}
-
- override fun mount(configure: TestContainerHikariConfig.() -> Unit): DataSource {
- this.configure = configure
- if (lifecycleMode == LifecycleMode.Spec) {
- container.start()
- ds.setDataSource(createDataSource())
- }
- return ds
- }
-
- private fun createDataSource(): HikariDataSource {
- val config = TestContainerHikariConfig()
- config.jdbcUrl = container.jdbcUrl
- config.username = container.username
- config.password = container.password
- config.configure()
- val ds = HikariDataSource(config)
- runInitScripts(ds.connection, config.dbInitScripts)
- return ds
- }
-
- override suspend fun afterSpec(spec: Spec) {
- withContext(Dispatchers.IO) {
- stop()
- }
- }
-
- override suspend fun beforeAny(testCase: TestCase) {
- val every = lifecycleMode == LifecycleMode.EveryTest
- val root = lifecycleMode == LifecycleMode.Root && testCase.isRootTest()
- val leaf = lifecycleMode == LifecycleMode.Leaf && testCase.type == TestType.Test
- if (every || root || leaf) {
- start()
- }
- }
-
- override suspend fun afterAny(testCase: TestCase, result: TestResult) {
- val every = lifecycleMode == LifecycleMode.EveryTest
- val root = lifecycleMode == LifecycleMode.Root && testCase.isRootTest()
- val leaf = lifecycleMode == LifecycleMode.Leaf && testCase.type == TestType.Test
- if (every || root || leaf) {
- stop()
- }
- }
-
- private suspend fun start() {
- withContext(Dispatchers.IO) {
- container.start()
- ds.setDataSource(createDataSource())
- }
- }
-
- private suspend fun stop() {
- withContext(Dispatchers.IO) {
- ds.setDataSource(null)
- container.stop()
- }
- }
-
- private fun runInitScripts(connection: Connection, dbInitScripts: List) {
-
- val scriptRunner = ScriptRunner(connection)
-
- if (dbInitScripts.isNotEmpty()) {
- dbInitScripts.forEach {
- val resourceList = ResourceLoader().resolveResource(it)
-
- resourceList
- .filter { resource -> resource.endsWith(".sql") }
- .forEach { resource ->
- scriptRunner.runScript(resource.loadToReader())
- }
- }
- }
- }
-}
-
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/LifecycleMode.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/LifecycleMode.kt
deleted file mode 100644
index 6cc4049..0000000
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/LifecycleMode.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-@Deprecated("To be removed")
-enum class LifecycleMode {
- Spec, EveryTest, Leaf, Root
-}
-
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/ResourceLoader.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/ResourceLoader.kt
deleted file mode 100644
index 2db4600..0000000
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/ResourceLoader.kt
+++ /dev/null
@@ -1,84 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import java.io.BufferedReader
-import java.nio.file.FileSystems
-import java.nio.file.Files
-import java.nio.file.Path
-import java.nio.file.Paths
-import java.util.stream.Collectors
-import kotlin.io.path.exists
-import kotlin.io.path.isDirectory
-import kotlin.io.path.isRegularFile
-import kotlin.io.path.name
-
-@Deprecated("use Flyway or another db migration tool")
-sealed interface Resource {
- data class Classpath(val resource: String) : Resource
- data class File(val path: Path) : Resource
-}
-
-@Deprecated("use Flyway or another db migration tool")
-fun Resource.endsWith(name: String): Boolean = when (this) {
- is Resource.Classpath -> this.resource.endsWith(name)
- is Resource.File -> this.path.name.endsWith(name)
-}
-
-@Deprecated("use Flyway or another db migration tool")
-fun Resource.loadToReader(): BufferedReader = when (this) {
- is Resource.Classpath -> javaClass.getResourceAsStream(this.resource)?.bufferedReader() ?: error("$this was not found on classpath")
- is Resource.File -> Files.newBufferedReader(this.path)
-}
-
-@Deprecated("use Flyway or another db migration tool")
-class ResourceLoader {
-
- private fun Path.getDirContentsOrItself(): List {
- return if (this.isDirectory()) {
- Files.newDirectoryStream(this)
- .use { stream -> stream.toList() }
- .filter { it.isRegularFile() }
- } else {
- listOf(this)
- }
- }
-
- private fun getFileResourcesFromPath(path: Path): List {
- if (!path.exists()) error("Resource $path does not exist on the classpath or on the local filesystem")
-
- return when (path.isRegularFile()) {
- true -> listOf(Resource.File(path))
- else -> Files.walk(path)
- .filter { it.isRegularFile() }
- .sorted()
- .map { Resource.File(it) }
- .collect(Collectors.toList())
- }
- }
-
- private fun getClasspathResourcesFromJar(resource: String) : List {
- val uri = javaClass.getResource(resource)!!.toURI()
- FileSystems.newFileSystem(uri, mutableMapOf()).use { fs ->
- val pathList = fs.getPath(resource).getDirContentsOrItself()
- return pathList.map { Resource.Classpath(it.toString()) }.sortedBy { it.toString() }
- }
- }
-
- fun resolveResource(resource: String): List {
- val url = javaClass.getResource(resource)
-
- return if (url == null) {
- //Not on classpath, check file system
- val path = Paths.get(resource)
- getFileResourcesFromPath(path)
-
- } else {
- //On Classpath
- when(url.protocol){
- "jar" -> getClasspathResourcesFromJar(resource)
- "file" -> getFileResourcesFromPath(Paths.get(url.toURI()))
- else -> error("Unhandled protocol: ${url.protocol}")
- }
- }
- }
-}
-
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/SharedJdbcDatabaseContainerExtension.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/SharedJdbcDatabaseContainerExtension.kt
deleted file mode 100644
index b7b80cd..0000000
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/SharedJdbcDatabaseContainerExtension.kt
+++ /dev/null
@@ -1,111 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import com.zaxxer.hikari.HikariConfig
-import com.zaxxer.hikari.HikariDataSource
-import io.kotest.core.extensions.MountableExtension
-import io.kotest.core.listeners.AfterProjectListener
-import io.kotest.core.listeners.AfterSpecListener
-import io.kotest.core.listeners.AfterTestListener
-import io.kotest.core.listeners.BeforeSpecListener
-import io.kotest.core.listeners.BeforeTestListener
-import io.kotest.core.spec.Spec
-import io.kotest.core.test.TestCase
-import io.kotest.core.test.TestResult
-import org.testcontainers.containers.JdbcDatabaseContainer
-import java.sql.Connection
-
-/**
- * A Kotest [MountableExtension] for [JdbcDatabaseContainer]s that are started the first time they are
- * installed in a test, and then shared throughout the same gradle module. The container is shutdown
- * after all specs have completed.
- *
- * If no spec is executed that installs a particular container, then that container is never started.
- *
- * This extension will create a pooled [HikariDataSource] attached to the database and
- * return that to the user as the materialized value.
- *
- * The Hikari pool can be configured in the constructor through the [configure] parameter, or through
- * the install method per spec. If the latter option is used, then only the configure function from
- * the install where the container is first started will be executed.
- *
- * Note: This extension requires Kotest 5.0+
- *
- * @param container the specific database test container type
- * @param beforeSpec a beforeSpec callback
- * @param afterSpec an afterSpec callback
- * @param beforeTest a beforeTest callback
- * @param afterTest a afterTest callback
- * @param afterStart called one time, after the container is started
- * @param configure a callback to configure the [HikariConfig] instance that is used to create the [HikariDataSource].
- *
- * @since 1.3.0
- */
-@Deprecated("use JdbcDatabaseContainerExtension")
-class SharedJdbcDatabaseContainerExtension(
- private val container: JdbcDatabaseContainer<*>,
- private val beforeTest: suspend (HikariDataSource) -> Unit = {},
- private val afterTest: suspend (HikariDataSource) -> Unit = {},
- private val beforeSpec: suspend (HikariDataSource) -> Unit = {},
- private val afterSpec: suspend (HikariDataSource) -> Unit = {},
- private val afterStart: (HikariDataSource) -> Unit = {},
- private val configure: TestContainerHikariConfig.() -> Unit = {},
-) : MountableExtension,
- AfterProjectListener,
- BeforeTestListener,
- BeforeSpecListener,
- AfterTestListener,
- AfterSpecListener {
-
- private var ds: HikariDataSource? = null
-
- override fun mount(configure: TestContainerHikariConfig.() -> Unit): HikariDataSource {
- if (!container.isRunning) {
- container.start()
- ds = createDataSource().apply(afterStart)
- }
- return ds ?: error("DataSource was not initialized")
- }
-
- override suspend fun afterProject() {
- if (container.isRunning) container.stop()
- }
-
- override suspend fun beforeTest(testCase: TestCase) {
- beforeTest(ds ?: error("DataSource was not initialized"))
- }
-
- override suspend fun afterTest(testCase: TestCase, result: TestResult) {
- afterTest(ds ?: error("DataSource was not initialized"))
- }
-
- override suspend fun beforeSpec(spec: Spec) {
- beforeSpec(ds ?: error("DataSource was not initialized"))
- }
-
- override suspend fun afterSpec(spec: Spec) {
- afterSpec(ds ?: error("DataSource was not initialized"))
- }
-
- private fun runInitScripts(connection: Connection, dbInitScripts: List) {
- if (dbInitScripts.isNotEmpty()) {
- val scriptRunner = ScriptRunner(connection)
- dbInitScripts.forEach { script ->
- ResourceLoader()
- .resolveResource(script)
- .filter { it.endsWith(".sql") }
- .forEach { scriptRunner.runScript(it.loadToReader()) }
- }
- }
- }
-
- private fun createDataSource(): HikariDataSource {
- val config = TestContainerHikariConfig()
- config.jdbcUrl = container.jdbcUrl
- config.username = container.username
- config.password = container.password
- config.configure()
- val ds = HikariDataSource(config)
- runInitScripts(ds.connection, config.dbInitScripts)
- return ds
- }
-}
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/SharedTestContainerExtension.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/SharedTestContainerExtension.kt
deleted file mode 100644
index e8084b6..0000000
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/SharedTestContainerExtension.kt
+++ /dev/null
@@ -1,102 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import io.kotest.core.extensions.MountableExtension
-import io.kotest.core.listeners.AfterProjectListener
-import io.kotest.core.listeners.AfterSpecListener
-import io.kotest.core.listeners.AfterTestListener
-import io.kotest.core.listeners.BeforeSpecListener
-import io.kotest.core.listeners.BeforeTestListener
-import io.kotest.core.spec.Spec
-import io.kotest.core.test.TestCase
-import io.kotest.core.test.TestResult
-import org.testcontainers.containers.GenericContainer
-
-/**
- * A Kotest [MountableExtension] for [GenericContainer]s that are started the first time they are
- * installed in a test, and then shared throughout the same gradle module. The container is shutdown
- * after all specs have completed.
- *
- * If no spec is executed that installs a particular container, then that container is never started.
- *
- * The returned materialized value can be adapted through the [mapper] parameter, to allow returning something other
- * than the raw container. For example, you could return a RedisClient that was preconnected to a redis container,
- * rather than returning the container itself.
- *
- * Note: This extension requires Kotest 5.0+
- *
- * @param container the specific database test container type
- * @param beforeSpec a beforeSpec callback, can be used to configure the container.
- * @param afterSpec an afterSpec callback, can be used to configure the container.
- * @param beforeTest a beforeTest callback, can be used to configure the container.
- * @param afterTest a afterTest callback, can be used to configure the container.
- * @param configure called one time after the container is started. Can configure the container without needing to
- * specify the configuration code at every use site.
- * @param mapper optional mapping function to adapt the materialized value.
- *
- * @since 1.3.0
- */
-@Deprecated("use ContainerExtension")
-class SharedTestContainerExtension, U>(
- private val container: T,
- private val beforeTest: suspend (T) -> Unit = {},
- private val afterTest: suspend (T) -> Unit = {},
- private val beforeSpec: suspend (T) -> Unit = {},
- private val afterSpec: suspend (T) -> Unit = {},
- private val configure: T.() -> Unit = {},
- private val mapper: T.() -> U,
-) : MountableExtension,
- AfterProjectListener,
- BeforeTestListener,
- BeforeSpecListener,
- AfterTestListener,
- AfterSpecListener {
-
- companion object {
- operator fun > invoke(
- container: T,
- beforeTest: (T) -> Unit = {},
- afterTest: (T) -> Unit = {},
- beforeSpec: (T) -> Unit = {},
- afterSpec: (T) -> Unit = {},
- configure: T.() -> Unit = {},
- ): SharedTestContainerExtension {
- return SharedTestContainerExtension(
- container,
- beforeTest,
- afterTest,
- beforeSpec,
- afterSpec,
- configure
- ) { this }
- }
- }
-
- override fun mount(configure: T.() -> Unit): U {
- if (!container.isRunning) {
- container.start()
- configure(container)
- this@SharedTestContainerExtension.configure(container)
- }
- return this@SharedTestContainerExtension.mapper(container)
- }
-
- override suspend fun afterProject() {
- if (container.isRunning) container.stop()
- }
-
- override suspend fun beforeTest(testCase: TestCase) {
- beforeTest(container)
- }
-
- override suspend fun afterTest(testCase: TestCase, result: TestResult) {
- afterTest(container)
- }
-
- override suspend fun beforeSpec(spec: Spec) {
- beforeSpec(container)
- }
-
- override suspend fun afterSpec(spec: Spec) {
- afterSpec(container)
- }
-}
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/StartablePerProjectListener.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/StartablePerProjectListener.kt
index 5abd6ee..8562daf 100644
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/StartablePerProjectListener.kt
+++ b/src/main/kotlin/io/kotest/extensions/testcontainers/StartablePerProjectListener.kt
@@ -21,9 +21,6 @@ import org.testcontainers.lifecycle.Startable
* */
class StartablePerProjectListener(private val startable: T) : TestListener, ProjectListener {
- @Deprecated("The containerName arg is no longer used")
- constructor(startable: T, containerName: String) : this(startable)
-
private val testLifecycleAwareListener = TestLifecycleAwareListener(startable)
override suspend fun beforeProject() {
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/TestContainerExtension.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/TestContainerExtension.kt
deleted file mode 100644
index 4a42eb2..0000000
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/TestContainerExtension.kt
+++ /dev/null
@@ -1,96 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import io.kotest.core.extensions.MountableExtension
-import io.kotest.core.listeners.AfterSpecListener
-import io.kotest.core.listeners.TestListener
-import io.kotest.core.spec.Spec
-import io.kotest.core.test.TestCase
-import io.kotest.core.test.TestResult
-import io.kotest.core.test.TestType
-import io.kotest.core.test.isRootTest
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.withContext
-import org.testcontainers.containers.GenericContainer
-import org.testcontainers.lifecycle.TestLifecycleAware
-import java.util.Optional
-
-@Deprecated("use ContainerExtension")
-class TestContainerExtension>(
- private val container: GenericContainer,
- private val lifecycleMode: LifecycleMode = LifecycleMode.Spec,
-) : MountableExtension, TestListener, AfterSpecListener {
-
- companion object {
- operator fun invoke(name: String): TestContainerExtension> =
- TestContainerExtension(GenericContainer(name))
-
- operator fun invoke(name: String, lifecycleMode: LifecycleMode): TestContainerExtension> =
- TestContainerExtension(GenericContainer(name), lifecycleMode)
- }
-
- override fun mount(configure: T.() -> Unit): T {
- (container as T).configure()
- if (lifecycleMode == LifecycleMode.Spec) {
- container.start()
- }
- return container
- }
-
- override suspend fun afterSpec(spec: Spec) {
- if (container.isRunning) {
- withContext(Dispatchers.IO) {
- stop()
- }
- }
- }
-
- override suspend fun beforeAny(testCase: TestCase) {
- val every = lifecycleMode == LifecycleMode.EveryTest
- val root = lifecycleMode == LifecycleMode.Root && testCase.isRootTest()
- val leaf = lifecycleMode == LifecycleMode.Leaf && testCase.type == TestType.Test
- if (every || root || leaf) {
- lifecycleBeforeTest(testCase)
- start()
- }
- }
-
- override suspend fun afterAny(testCase: TestCase, result: TestResult) {
- val every = lifecycleMode == LifecycleMode.EveryTest
- val root = lifecycleMode == LifecycleMode.Root && testCase.isRootTest()
- val leaf = lifecycleMode == LifecycleMode.Leaf && testCase.type == TestType.Test
- if (every || root || leaf) {
- lifecycleAfterTest(testCase, result)
- stop()
- }
- }
-
- private suspend fun start() {
- withContext(Dispatchers.IO) {
- container.start()
- }
- }
-
- private suspend fun stop() {
- withContext(Dispatchers.IO) {
- container.stop()
- }
- }
-
- private suspend fun lifecycleBeforeTest(testCase: TestCase) {
- when (container) {
- is TestLifecycleAware -> withContext(Dispatchers.IO) {
- container.beforeTest(testCase.toTestDescription())
- }
- }
- }
-
- private suspend fun lifecycleAfterTest(testCase: TestCase, result: TestResult) {
- when (container) {
- is TestLifecycleAware -> withContext(Dispatchers.IO) {
- container.afterTest(
- testCase.toTestDescription(), Optional.ofNullable(result.errorOrNull)
- )
- }
- }
- }
-}
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/TestContainerHikariConfig.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/TestContainerHikariConfig.kt
deleted file mode 100644
index 6cf1304..0000000
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/TestContainerHikariConfig.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import com.zaxxer.hikari.HikariConfig
-
-@Deprecated("use Flyway or another db migration tool")
-class TestContainerHikariConfig : HikariConfig() {
-
- var dbInitScripts: List = emptyList()
-
-}
diff --git a/src/main/kotlin/io/kotest/extensions/testcontainers/kafka/kafka.kt b/src/main/kotlin/io/kotest/extensions/testcontainers/kafka/kafka.kt
deleted file mode 100644
index d28449f..0000000
--- a/src/main/kotlin/io/kotest/extensions/testcontainers/kafka/kafka.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-package io.kotest.extensions.testcontainers.kafka
-
-import org.apache.kafka.clients.CommonClientConfigs
-import org.apache.kafka.clients.admin.AdminClient
-import org.apache.kafka.clients.consumer.KafkaConsumer
-import org.apache.kafka.clients.producer.KafkaProducer
-import org.apache.kafka.common.serialization.Deserializer
-import org.apache.kafka.common.serialization.Serializer
-import org.apache.kafka.common.serialization.StringDeserializer
-import org.apache.kafka.common.serialization.StringSerializer
-import org.testcontainers.containers.KafkaContainer
-import java.util.Properties
-import java.util.UUID
-
-@Deprecated("Use the kafka module")
-fun KafkaContainer.createStringStringProducer(
- configure: Properties.() -> Unit = {},
-): KafkaProducer {
- return createProducer(StringSerializer(), StringSerializer(), configure)
-}
-
-@Deprecated("Use the kafka module")
-fun KafkaContainer.createProducer(
- kserializer: Serializer,
- vserializer: Serializer,
- configure: Properties.() -> Unit = {},
-): KafkaProducer {
- val props = Properties()
- props[CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG] = bootstrapServers
- props.configure()
- return KafkaProducer(props, kserializer, vserializer)
-}
-
-@Deprecated("Use the kafka module")
-fun KafkaContainer.createStringStringConsumer(
- configure: Properties.() -> Unit = {},
-): KafkaConsumer {
- return createConsumer(StringDeserializer(), StringDeserializer(), configure)
-}
-
-@Deprecated("Use the kafka module")
-fun KafkaContainer.createConsumer(
- kserializer: Deserializer,
- vserializer: Deserializer,
- configure: Properties.() -> Unit = {},
-): KafkaConsumer {
- val props = Properties()
- props[CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG] = bootstrapServers
- props[CommonClientConfigs.GROUP_ID_CONFIG] = UUID.randomUUID().toString().replace("-", "")
- props.configure()
- return KafkaConsumer(props, kserializer, vserializer)
-}
-
-@Deprecated("Use the kafka module")
-fun KafkaContainer.createAdminClient(configure: Properties.() -> Unit = {}): AdminClient {
- val props = Properties()
- props[CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG] = bootstrapServers
- props.configure()
- return AdminClient.create(props)
-}
diff --git a/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerExtensionSpecTest.kt b/src/test/kotlin/io/kotest/extensions/testcontainers/ContainerExtensionSpecLifecycleTest.kt
similarity index 74%
rename from src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerExtensionSpecTest.kt
rename to src/test/kotlin/io/kotest/extensions/testcontainers/ContainerExtensionSpecLifecycleTest.kt
index 1f684a5..14e2226 100644
--- a/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerExtensionSpecTest.kt
+++ b/src/test/kotlin/io/kotest/extensions/testcontainers/ContainerExtensionSpecLifecycleTest.kt
@@ -1,14 +1,15 @@
package io.kotest.extensions.testcontainers
+import com.redis.testcontainers.RedisContainer
import io.kotest.core.extensions.install
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import redis.clients.jedis.JedisPool
-class TestContainerExtensionSpecTest : FunSpec() {
+class ContainerExtensionSpecLifecycleTest : FunSpec() {
init {
- val container = install(TestContainerExtension("redis:5.0.3-alpine", LifecycleMode.Spec)) {
+ val container = install(ContainerExtension(RedisContainer("7.2.5-alpine"), ContainerLifecycleMode.Spec)) {
startupAttempts = 2
withExposedPorts(6379)
}
diff --git a/src/test/kotlin/io/kotest/extensions/testcontainers/DockerComposeContainersExtensionTest.kt b/src/test/kotlin/io/kotest/extensions/testcontainers/DockerComposeContainersExtensionTest.kt
deleted file mode 100644
index 7f32acb..0000000
--- a/src/test/kotlin/io/kotest/extensions/testcontainers/DockerComposeContainersExtensionTest.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import io.kotest.core.extensions.install
-import io.kotest.core.spec.style.StringSpec
-import io.kotest.matchers.optional.shouldBePresent
-import io.kotest.matchers.string.shouldContain
-import java.io.File
-
-class DockerComposeContainersExtensionTest: StringSpec() {
- init {
-
- val container = install(DockerComposeContainersExtension(File("src/test/resources/docker-compose/docker-compose.yml"))) {
- }
-
- "should setup using docker-compose" {
- container.getContainerByServiceName("hello_world").shouldBePresent().logs shouldContain "Hello world"
- }
- }
-}
diff --git a/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtensionSpecTest.kt b/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcDatabaseContainerExtensionSpecTest.kt
similarity index 91%
rename from src/test/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtensionSpecTest.kt
rename to src/test/kotlin/io/kotest/extensions/testcontainers/JdbcDatabaseContainerExtensionSpecTest.kt
index 01296a7..a75f9ef 100644
--- a/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtensionSpecTest.kt
+++ b/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcDatabaseContainerExtensionSpecTest.kt
@@ -5,7 +5,7 @@ import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import org.testcontainers.containers.MySQLContainer
-class JdbcTestContainerExtensionSpecTest : FunSpec() {
+class JdbcDatabaseContainerExtensionSpecTest : FunSpec() {
init {
val mysql = MySQLContainer("mysql:8.0.26").apply {
@@ -15,7 +15,7 @@ class JdbcTestContainerExtensionSpecTest : FunSpec() {
withUrlParam("zeroDateTimeBehavior", "convertToNull")
}
- val ds = install(JdbcTestContainerExtension(mysql)) {
+ val ds = install(JdbcDatabaseContainerExtension(mysql)) {
maximumPoolSize = 8
minimumIdle = 4
}
diff --git a/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcMultiScriptContainerInitTest.kt b/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcMultiScriptContainerInitTest.kt
index c12b5cb..99a8c3c 100644
--- a/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcMultiScriptContainerInitTest.kt
+++ b/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcMultiScriptContainerInitTest.kt
@@ -4,6 +4,7 @@ import io.kotest.core.extensions.install
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import org.testcontainers.containers.MySQLContainer
+import org.testcontainers.utility.MountableFile.forClasspathResource
class JdbcMultiScriptContainerInitTest : FunSpec({
@@ -11,11 +12,16 @@ class JdbcMultiScriptContainerInitTest : FunSpec({
startupAttempts = 1
withUrlParam("connectionTimeZone", "Z")
withUrlParam("zeroDateTimeBehavior", "convertToNull")
+
+ val sqlInitDir = "/docker-entrypoint-initdb.d/"
+ withCopyToContainer(forClasspathResource("init.sql"), sqlInitDir + "000-init.sql")
+ withCopyToContainer(forClasspathResource("sql-changesets/001-people.sql"), sqlInitDir + "001-people.sql")
+ withCopyToContainer(forClasspathResource("sql-changesets/002-places.sql"), sqlInitDir + "002-places.sql")
}
- val ds = install(JdbcTestContainerExtension(mysql, LifecycleMode.Leaf)) {
+
+ val ds = install(JdbcDatabaseContainerExtension(mysql, ContainerLifecycleMode.Spec)) {
maximumPoolSize = 8
minimumIdle = 4
- dbInitScripts = listOf("/init.sql", "/sql-changesets")
}
@@ -41,24 +47,4 @@ class JdbcMultiScriptContainerInitTest : FunSpec({
}
}
-
- context("with fresh container init"){
- test("db should be reset per lifecycle mode") {
- ds.connection.use {
-
- var rsCount = it.createStatement().executeQuery("SELECT count(*) FROM hashtags")
- rsCount.next()
- rsCount.getLong(1) shouldBe 1
-
- rsCount = it.createStatement().executeQuery("SELECT count(*) FROM people")
- rsCount.next()
- rsCount.getLong(1) shouldBe 2
-
- rsCount = it.createStatement().executeQuery("SELECT count(*) FROM places")
- rsCount.next()
- rsCount.getLong(1) shouldBe 2
- }
- }
- }
-
})
diff --git a/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtensionLeafTest.kt b/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtensionLeafTest.kt
deleted file mode 100644
index 47d9f15..0000000
--- a/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtensionLeafTest.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-@file:Suppress("SqlResolve")
-
-package io.kotest.extensions.testcontainers
-
-import io.kotest.core.extensions.install
-import io.kotest.core.spec.style.DescribeSpec
-import io.kotest.matchers.shouldBe
-import org.testcontainers.containers.MySQLContainer
-
-class JdbcTestContainerExtensionLeafTest : DescribeSpec() {
- init {
-
- val mysql = MySQLContainer("mysql:8.0.26").apply {
- withInitScript("init.sql")
- startupAttempts = 1
- withUrlParam("connectionTimeZone", "Z")
- withUrlParam("zeroDateTimeBehavior", "convertToNull")
- }
-
- val ds = install(JdbcTestContainerExtension(mysql, LifecycleMode.Leaf)) {
- maximumPoolSize = 8
- minimumIdle = 4
- }
-
- describe("context") {
- mysql.isRunning shouldBe false
- it("should initialize per leaf") {
- ds.connection.use {
- val rs1 = it.createStatement().executeQuery("SELECT * FROM hashtags")
- rs1.next()
- rs1.getString("tag") shouldBe "startrek"
-
- it.createStatement().executeUpdate("INSERT INTO hashtags(tag) VALUES ('foo')")
-
- val rs2 = it.createStatement().executeQuery("SELECT count(*) FROM hashtags")
- rs2.next()
- rs2.getLong(1) shouldBe 2
- }
- }
-
- it("this root test should have a different container container") {
- ds.connection.use {
- val rs = it.createStatement().executeQuery("SELECT count(*) FROM hashtags")
- rs.next()
- rs.getLong(1) shouldBe 1
- }
- }
- }
- }
-}
diff --git a/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtensionRootTest.kt b/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtensionRootTest.kt
deleted file mode 100644
index 1166238..0000000
--- a/src/test/kotlin/io/kotest/extensions/testcontainers/JdbcTestContainerExtensionRootTest.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import io.kotest.core.extensions.install
-import io.kotest.core.spec.style.FunSpec
-import io.kotest.matchers.shouldBe
-import org.testcontainers.containers.MySQLContainer
-
-class JdbcTestContainerExtensionRootTest : FunSpec() {
- init {
-
- val mysql = MySQLContainer("mysql:8.0.26").apply {
- withInitScript("init.sql")
- startupAttempts = 1
- withUrlParam("connectionTimeZone", "Z")
- withUrlParam("zeroDateTimeBehavior", "convertToNull")
- }
-
- val ds = install(JdbcTestContainerExtension(mysql, LifecycleMode.Root)) {
- maximumPoolSize = 8
- minimumIdle = 4
- }
-
- test("should initialize per root") {
- ds.connection.use {
- val rs1 = it.createStatement().executeQuery("SELECT * FROM hashtags")
- rs1.next()
- rs1.getString("tag") shouldBe "startrek"
-
- it.createStatement().executeUpdate("INSERT INTO hashtags(tag) VALUES ('foo')")
-
- val rs2 = it.createStatement().executeQuery("SELECT count(*) FROM hashtags")
- rs2.next()
- rs2.getLong(1) shouldBe 2
- }
- }
-
- test("this root test should have a different container") {
- ds.connection.use {
- val rs = it.createStatement().executeQuery("SELECT count(*) FROM hashtags")
- rs.next()
- rs.getLong(1) shouldBe 1
- }
- }
- }
-}
diff --git a/src/test/kotlin/io/kotest/extensions/testcontainers/KafkaTestContainerExtensionTest.kt b/src/test/kotlin/io/kotest/extensions/testcontainers/KafkaTestContainerExtensionTest.kt
deleted file mode 100644
index d6abac3..0000000
--- a/src/test/kotlin/io/kotest/extensions/testcontainers/KafkaTestContainerExtensionTest.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import io.kotest.core.extensions.install
-import io.kotest.core.spec.style.FunSpec
-import io.kotest.extensions.testcontainers.kafka.createStringStringConsumer
-import io.kotest.extensions.testcontainers.kafka.createStringStringProducer
-import io.kotest.matchers.collections.shouldHaveSize
-import org.apache.kafka.clients.consumer.ConsumerConfig
-import org.apache.kafka.clients.producer.ProducerRecord
-import org.testcontainers.containers.KafkaContainer
-import org.testcontainers.utility.DockerImageName
-import java.time.Duration
-
-@Deprecated("To be removed")
-class KafkaTestContainerExtensionTest : FunSpec() {
- init {
-
- val kafka = install(TestContainerExtension(KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:6.2.1")))) {
- withEmbeddedZookeeper()
- withEnv("KAFKA_AUTO_CREATE_TOPICS_ENABLE", "true")
- withCreateContainerCmdModifier { it.withPlatform("linux/amd64") }
- }
-
- test("should setup kafka") {
-
- val producer = kafka.createStringStringProducer()
- producer.send(ProducerRecord("foo", "key", "bubble bobble"))
- producer.flush()
- producer.close()
-
- val consumer = kafka.createStringStringConsumer {
- this[ConsumerConfig.MAX_POLL_RECORDS_CONFIG] = 1
- this[ConsumerConfig.AUTO_OFFSET_RESET_CONFIG] = "earliest"
- }
-
- consumer.subscribe(listOf("foo"))
- val records = consumer.poll(Duration.ofSeconds(15))
- records.shouldHaveSize(1)
- consumer.close()
- }
- }
-}
diff --git a/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerExtensionLeafTest.kt b/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerExtensionLeafTest.kt
deleted file mode 100644
index 038d5bc..0000000
--- a/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerExtensionLeafTest.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import io.kotest.core.extensions.install
-import io.kotest.core.spec.style.DescribeSpec
-import io.kotest.matchers.shouldBe
-import redis.clients.jedis.JedisPool
-
-class TestContainerExtensionLeafTest : DescribeSpec() {
- init {
-
- val container = install(TestContainerExtension("redis:5.0.3-alpine", LifecycleMode.Leaf)) {
- startupAttempts = 1
- withExposedPorts(6379)
- }
-
- describe("context") {
- container.isRunning shouldBe false
- it("should initialize per leaf") {
- val jedis = JedisPool(container.host, container.firstMappedPort)
- jedis.resource.set("foo", "bar")
- jedis.resource.get("foo") shouldBe "bar"
- }
-
- it("this test should have a new container") {
- val jedis = JedisPool(container.host, container.firstMappedPort)
- jedis.resource.get("foo") shouldBe null
- }
- }
- }
-}
diff --git a/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerExtensionRootTest.kt b/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerExtensionRootTest.kt
deleted file mode 100644
index 9590618..0000000
--- a/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerExtensionRootTest.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package io.kotest.extensions.testcontainers
-
-import io.kotest.core.extensions.install
-import io.kotest.core.spec.style.FunSpec
-import io.kotest.matchers.shouldBe
-import redis.clients.jedis.JedisPool
-
-class TestContainerExtensionRootTest : FunSpec() {
- init {
-
- val container = install(TestContainerExtension("redis:5.0.3-alpine", LifecycleMode.Root)) {
- startupAttempts = 2
- withExposedPorts(6379)
- }
-
- test("should initialize per root") {
- val jedis = JedisPool(container.host, container.firstMappedPort)
- jedis.resource.set("foo", "bar")
- jedis.resource.get("foo") shouldBe "bar"
- }
-
- test("this root test should have a different container") {
- val jedis = JedisPool(container.host, container.firstMappedPort)
- jedis.resource.get("foo") shouldBe null
- }
- }
-}
diff --git a/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerIntegrationPerSpec.kt b/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerIntegrationPerSpec.kt
index e4104f0..87f55f9 100644
--- a/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerIntegrationPerSpec.kt
+++ b/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerIntegrationPerSpec.kt
@@ -5,7 +5,8 @@ import io.kotest.matchers.shouldBe
class TestContainerIntegrationPerSpec : StringSpec({
- val testStartable = configurePerSpec(TestStartable())
+ val testStartable = TestStartable()
+ listener(testStartable.perSpec())
"start count for first test should be one" {
testStartable.startCount shouldBe 1
diff --git a/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerIntegrationPerTest.kt b/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerIntegrationPerTest.kt
index 49b2c68..369e21c 100644
--- a/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerIntegrationPerTest.kt
+++ b/src/test/kotlin/io/kotest/extensions/testcontainers/TestContainerIntegrationPerTest.kt
@@ -5,7 +5,8 @@ import io.kotest.matchers.shouldBe
class TestContainerIntegrationPerTest : StringSpec({
- val testStartable = configurePerTest(TestStartable())
+ val testStartable = TestStartable()
+ listener(testStartable.perTest())
"start count for first test should be one" {
testStartable.startCount shouldBe 1