update postgres test container

- update README.md
- update PostgresContainer
  - add TestExecutionListeners
  - remove ExtendWith
- update PostgresInitializer
  - cleanup
  - use properties for script and container
  - add afterTestClass
  - add beforeTestClass
  - extend TestExecutionListener
- remove PostgresExtension
- add debug logging to PostgresExecutor
- add ContainerUtils
- add dependencies
- extract function from PostgresExtension to PostgresExecutor
This commit is contained in:
2025-03-10 17:41:18 +01:00
parent 902a2a2c0b
commit 6aad7e3d63
7 changed files with 146 additions and 98 deletions

View File

@@ -1,32 +1,67 @@
package ltd.hlaeja.test.container
import io.github.oshai.kotlinlogging.KotlinLogging
import ltd.hlaeja.test.util.getProperty
import ltd.hlaeja.test.util.isResourceFile
import org.springframework.boot.test.util.TestPropertyValues
import org.springframework.context.ApplicationContextInitializer
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.core.io.ClassPathResource
import org.springframework.test.context.TestContext
import org.springframework.test.context.TestExecutionListener
import org.testcontainers.containers.PostgreSQLContainer
@Suppress("unused")
class PostgresInitializer : ApplicationContextInitializer<ConfigurableApplicationContext> {
private val log = KotlinLogging.logger {}
override fun initialize(applicationContext: ConfigurableApplicationContext) {
postgres().apply {
@Suppress("unused")
class PostgresInitializer : ApplicationContextInitializer<ConfigurableApplicationContext>, TestExecutionListener {
companion object {
const val SCRIPT_INIT = "container.postgres.init"
const val SCRIPT_BEFORE = "container.postgres.before"
const val SCRIPT_AFTER = "container.postgres.after"
const val POSTGRES_VERSION = "container.postgres.version"
const val POSTGRES_LATEST = "postgres:latest"
}
override fun initialize(
context: ConfigurableApplicationContext,
) {
postgres(context).apply {
TestPropertyValues.of(
"spring.r2dbc.url=r2dbc:pool:postgresql://$host:$firstMappedPort/$databaseName",
"spring.r2dbc.username=$username",
"spring.r2dbc.password=$password",
).applyTo(applicationContext)
).applyTo(context)
}
}
private fun postgres(): PostgreSQLContainer<*> = PostgreSQLContainer("postgres:17")
.withReuse(true)
.apply {
"postgres/schema.sql".let {
if (ClassPathResource(it).exists()) {
withInitScript(it)
}
}
start()
}
override fun beforeTestClass(
context: TestContext,
) {
context.testClass
.also { log.debug { "Starting execution before class: ${it.simpleName}" } }
.getAnnotation(PostgresContainer::class.java) ?: return
context.getProperty(SCRIPT_BEFORE)
?.let { context.applicationContext.getBean(PostgresExecutor::class.java).executeSqlFile(it) }
}
override fun afterTestClass(
context: TestContext,
) {
context.testClass
.also { log.debug { "Starting execution after class: ${it.simpleName}" } }
.getAnnotation(PostgresContainer::class.java) ?: return
context.getProperty(SCRIPT_AFTER)
?.let { context.applicationContext.getBean(PostgresExecutor::class.java).executeSqlFile(it) }
}
private fun postgres(
context: ConfigurableApplicationContext,
): PostgreSQLContainer<*> = PostgreSQLContainer(context.getProperty(POSTGRES_VERSION, POSTGRES_LATEST)).apply {
context.getProperty(SCRIPT_INIT)
?.isResourceFile()
?.let { lala -> withInitScript(lala.path) }
?: log.error { "Postgres init script not found" }
start()
}
}