generated from aura-ascend/template-library
Compare commits
2 Commits
56f62c9729
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b7974793b | |||
| d9c82b07e0 |
22
README.md
22
README.md
@@ -1,6 +1,20 @@
|
|||||||
# {library}
|
# Test Integration.
|
||||||
|
|
||||||
{description}
|
Library to test integration for aura ascend.
|
||||||
|
|
||||||
|
## Postgres Test Container
|
||||||
|
|
||||||
|
`@PostgresTestContainer` Annotation for integration tests.
|
||||||
|
|
||||||
|
Initialize Postgres test container using test container default properties, script located in `src/<test path>/resources/postgres/` folder.
|
||||||
|
|
||||||
|
### Properties For Test Container
|
||||||
|
|
||||||
|
| file | required | info |
|
||||||
|
|---------------------|:--------:|----------------------------------------------------------------|
|
||||||
|
| postgres/schema.sql | ✓ | Postgres init script containing all structure and functions |
|
||||||
|
| postgres/data.sql | | Postgres data script containing all data to populate database |
|
||||||
|
| postgres/reset.sql | | Postgres reset script containing all command to reset database |
|
||||||
|
|
||||||
## Publish library locally.
|
## Publish library locally.
|
||||||
|
|
||||||
@@ -25,8 +39,8 @@ To authenticate with Gradle to access repositories that require authentication,
|
|||||||
Here's how you can do it:
|
Here's how you can do it:
|
||||||
|
|
||||||
1. Open or create the `gradle.properties` file in your Gradle user home directory:
|
1. Open or create the `gradle.properties` file in your Gradle user home directory:
|
||||||
- On Unix-like systems (Linux, macOS), this directory is typically `~/.gradle/`.
|
- On Unix-like systems (Linux, macOS), this directory is typically `~/.gradle/`.
|
||||||
- On Windows, this directory is typically `C:\Users\<YourUsername>\.gradle\`.
|
- On Windows, this directory is typically `C:\Users\<YourUsername>\.gradle\`.
|
||||||
2. Add the following lines to the `gradle.properties` file:
|
2. Add the following lines to the `gradle.properties` file:
|
||||||
```properties
|
```properties
|
||||||
repository.<name>.user=your_user
|
repository.<name>.user=your_user
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
plugins {
|
plugins {
|
||||||
alias(aa.plugins.kotlin.jvm)
|
alias(aa.plugins.kotlin.jvm)
|
||||||
|
alias(aa.plugins.spring.dependency.management)
|
||||||
alias(aa.plugins.library)
|
alias(aa.plugins.library)
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation(aa.kotlinx.coroutines)
|
||||||
testImplementation(aa.kotlin.junit5)
|
implementation(aa.springboot.starter.r2dbc)
|
||||||
|
implementation(aa.springboot.starter.test)
|
||||||
testRuntimeOnly(aa.junit.platform.launcher)
|
implementation(aa.testcontainers.postgresql)
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "ltd.lulz.library"
|
group = "ltd.lulz.library"
|
||||||
description = "library template"
|
description = "library test integration"
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
version=0.1.0-SNAPSHOT
|
version=0.1.0-SNAPSHOT
|
||||||
catalog=0.1.0
|
catalog=0.2.0-SNAPSHOT
|
||||||
|
|||||||
@@ -34,4 +34,4 @@ pluginManagement.repositories {
|
|||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
|
|
||||||
rootProject.name = "library"
|
rootProject.name = "test-integration"
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
package ltd.lulz.library
|
|
||||||
|
|
||||||
class LulzLibrary
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package ltd.lulz.test.container
|
||||||
|
|
||||||
|
import ltd.lulz.test.container.extension.PostgresTestExtension
|
||||||
|
import ltd.lulz.test.container.postgres.PostgresTestListener
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
|
import org.springframework.test.context.ContextConfiguration
|
||||||
|
import org.springframework.test.context.TestExecutionListeners
|
||||||
|
import org.springframework.test.context.TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
@ExtendWith(PostgresTestExtension::class)
|
||||||
|
@ContextConfiguration(initializers = [PostgresTestExtension::class])
|
||||||
|
@TestExecutionListeners(listeners = [PostgresTestListener::class], mergeMode = MERGE_WITH_DEFAULTS)
|
||||||
|
annotation class PostgresTestContainer
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package ltd.lulz.test.container.extension
|
||||||
|
|
||||||
|
import ltd.lulz.test.container.postgres.TestContainerPostgres
|
||||||
|
import org.junit.jupiter.api.extension.BeforeAllCallback
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext
|
||||||
|
import org.springframework.boot.test.util.TestPropertyValues
|
||||||
|
import org.springframework.context.ApplicationContextInitializer
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext
|
||||||
|
|
||||||
|
class PostgresTestExtension : BeforeAllCallback, ApplicationContextInitializer<ConfigurableApplicationContext> {
|
||||||
|
|
||||||
|
override fun initialize(applicationContext: ConfigurableApplicationContext) {
|
||||||
|
TestPropertyValues.of(TestContainerPostgres.props()).applyTo(applicationContext.environment)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun beforeAll(context: ExtensionContext) {
|
||||||
|
if (!TestContainerPostgres.postgres.isRunning) {
|
||||||
|
TestContainerPostgres.postgres.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package ltd.lulz.test.container.postgres
|
||||||
|
|
||||||
|
import ltd.lulz.test.container.postgres.TestContainerPostgres.sqlFile
|
||||||
|
import ltd.lulz.test.container.util.hasAnnotation
|
||||||
|
import org.junit.jupiter.api.Nested
|
||||||
|
import org.springframework.test.context.TestContext
|
||||||
|
import org.springframework.test.context.TestExecutionListener
|
||||||
|
|
||||||
|
class PostgresTestListener : TestExecutionListener {
|
||||||
|
|
||||||
|
override fun beforeTestClass(
|
||||||
|
context: TestContext,
|
||||||
|
) {
|
||||||
|
if (context.testClass.hasAnnotation<Nested>()) return
|
||||||
|
sqlFile("postgres/data.sql", context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun afterTestClass(
|
||||||
|
context: TestContext,
|
||||||
|
) {
|
||||||
|
if (context.testClass.hasAnnotation<Nested>()) return
|
||||||
|
sqlFile("postgres/reset.sql", context)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package ltd.lulz.test.container.postgres
|
||||||
|
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import ltd.lulz.test.container.util.isResourceFile
|
||||||
|
import org.springframework.r2dbc.core.DatabaseClient
|
||||||
|
import org.springframework.r2dbc.core.await
|
||||||
|
import org.springframework.test.context.TestContext
|
||||||
|
import org.testcontainers.containers.PostgreSQLContainer
|
||||||
|
import org.testcontainers.utility.DockerImageName
|
||||||
|
|
||||||
|
object TestContainerPostgres {
|
||||||
|
|
||||||
|
val postgres = PostgreSQLContainer(DockerImageName.parse("postgres:18rc1-alpine"))
|
||||||
|
.withReuse(true)
|
||||||
|
.apply {
|
||||||
|
withDatabaseName("testdb")
|
||||||
|
withUsername("test")
|
||||||
|
withPassword("test")
|
||||||
|
"postgres/schema.sql".isResourceFile()?.let { withInitScript(it.path) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun props(): Map<String, String> = postgres.let {
|
||||||
|
mapOf(
|
||||||
|
"spring.r2dbc.url" to "r2dbc:postgresql://${it.host}:${it.firstMappedPort}/${it.databaseName}",
|
||||||
|
"spring.r2dbc.username" to it.username,
|
||||||
|
"spring.r2dbc.password" to it.password,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sqlFile(
|
||||||
|
sqlFile: String,
|
||||||
|
context: TestContext,
|
||||||
|
): Unit = runBlocking {
|
||||||
|
sqlFile.isResourceFile()
|
||||||
|
?.inputStream
|
||||||
|
?.use {
|
||||||
|
executeSqlStatements(
|
||||||
|
makeSqlStatements(it),
|
||||||
|
context.applicationContext.getBean(DatabaseClient::class.java),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("TooGenericExceptionThrown", "SqlSourceToSinkFlow")
|
||||||
|
private suspend fun executeSqlStatements(
|
||||||
|
statements: List<String>,
|
||||||
|
databaseClient: DatabaseClient,
|
||||||
|
) = try {
|
||||||
|
statements.forEach { databaseClient.sql(it).await() }
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw RuntimeException("Failed to execute SQL statements", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeSqlStatements(
|
||||||
|
inputStream: InputStream,
|
||||||
|
): List<String> = BufferedReader(InputStreamReader(inputStream))
|
||||||
|
.lines()
|
||||||
|
.filter { it.isNotEmpty() && !it.startsWith("--") }
|
||||||
|
.map { it.trim() }
|
||||||
|
.toList()
|
||||||
|
.joinToString(" ")
|
||||||
|
.split(';')
|
||||||
|
.filter { it.isNotBlank() }
|
||||||
|
.map { "${it.trim()};" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package ltd.lulz.test.container.util
|
||||||
|
|
||||||
|
import org.springframework.core.io.ClassPathResource
|
||||||
|
|
||||||
|
fun String.isResourceFile(): ClassPathResource? = ClassPathResource(this)
|
||||||
|
.let { resource ->
|
||||||
|
when {
|
||||||
|
resource.exists() && resource.isReadable -> resource
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : Annotation> Class<*>.hasAnnotation(): Boolean = getAnnotation(T::class.java) != null
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package ltd.lulz.library
|
|
||||||
|
|
||||||
import kotlin.test.Test
|
|
||||||
|
|
||||||
class LulzLibraryTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `Lulz Library Test`() {
|
|
||||||
// Placeholder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user