kotest-extensions-testcontainers icon indicating copy to clipboard operation
kotest-extensions-testcontainers copied to clipboard

Error running test containers for Postgres DB with

Open dmykhailov opened this issue 1 year ago • 1 comments

Running a basic code to use test container for postgres I am getting an error constructing Hikari datasource. Looks like the code breaks on the second .configure() attempt here

package com.devraccoon.dataaccess

import com.zaxxer.hikari.HikariDataSource
import io.kotest.core.extensions.MountableExtension
import io.kotest.core.extensions.install
import io.kotest.core.spec.style.DescribeSpec
import io.kotest.extensions.testcontainers.JdbcDatabaseContainerExtension
import io.kotest.extensions.testcontainers.toDataSource
import io.kotest.matchers.shouldBe
import org.testcontainers.containers.JdbcDatabaseContainer
import org.testcontainers.containers.PostgreSQLContainer
import java.sql.SQLException

class DatabaseAccessContainer : DescribeSpec({

    val postgresSqlContainer = PostgreSQLContainer<Nothing>("postgres:15.3").apply {
        withDatabaseName("test_db")
        withUsername("sa")
        withPassword("sa")
    }

    val ds = install(JdbcDatabaseContainerExtension(postgresSqlContainer)) {
        poolName = "connection_pool_for_tests"
        maximumPoolSize = 8
        idleTimeout = 3000
    }

    describe("database access") {
        it("should run a postgres test container") {
            try {
                val conn = ds.connection
                val statement = conn.createStatement()
                val resultSet = statement.executeQuery("SELECT 1 as DB;")

                while (resultSet.next()) {
                    resultSet.getInt("DB") shouldBe 1
                }

            } catch (ex: SQLException) {
                ex.printStackTrace()
            }

        }
    }
})

The code works as expected if I use a custom extension class without the second .configure() call:

class NoSecondConfigureJdbcDatabaseContainerExtension(private val container: JdbcDatabaseContainer<*>) : MountableExtension<HikariDataSource, HikariDataSource> {

    private var dataSource: HikariDataSource? = null

    override fun mount(configure: HikariDataSource.() -> Unit): HikariDataSource {
        if (!container.isRunning) {
            container.start()
            dataSource = container.toDataSource()
        }
//        dataSource?.configure()
        return dataSource ?: error("Datasource not initialized")
    }

}

...
   val ds = install(NoSecondConfigureJdbcDatabaseContainerExtension(postgresSqlContainer)) {
        poolName = "connection_pool_for_tests"
        maximumPoolSize = 8
        idleTimeout = 3000
    }
...

versions:

library("kotest-extensions-testcontainers", "io.kotest.extensions:kotest-extensions-testcontainers:2.0.2")
implementation("org.postgresql:postgresql:42.3.8")
implementation("org.flywaydb:flyway-core:8.2.0")
testImplementation(platform("org.testcontainers:testcontainers-bom:1.18.3"))
testImplementation("org.testcontainers:postgresql")

Error:

Caused by: java.lang.IllegalStateException: The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.
	at com.zaxxer.hikari.HikariConfig.checkIfSealed(HikariConfig.java:1095)
	at com.zaxxer.hikari.HikariConfig.setPoolName(HikariConfig.java:803)
	at com.devraccoon.dataaccess.DatabaseAccessContainer$1$ds$1.invoke(DatabaseAccessContainer.kt:23)
	at com.devraccoon.dataaccess.DatabaseAccessContainer$1$ds$1.invoke(DatabaseAccessContainer.kt:22)
	at io.kotest.extensions.testcontainers.JdbcDatabaseContainerExtension.mount(JdbcDatabaseContainerExtension.kt:91)
	at io.kotest.extensions.testcontainers.JdbcDatabaseContainerExtension.mount(JdbcDatabaseContainerExtension.kt:53)
	at io.kotest.core.extensions.MountableExtensionKt.install(MountableExtension.kt:69)
	at com.devraccoon.dataaccess.DatabaseAccessContainer$1.invoke(DatabaseAccessContainer.kt:22)
	at com.devraccoon.dataaccess.DatabaseAccessContainer$1.invoke(DatabaseAccessContainer.kt:14)
	at io.kotest.core.spec.style.DescribeSpec.<init>(describeSpec.kt:25)
	at com.devraccoon.dataaccess.DatabaseAccessContainer.<init>(DatabaseAccessContainer.kt:14)
	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:67)
	... 111 more

dmykhailov avatar Jul 11 '23 10:07 dmykhailov