Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ dependencies {
}

api(platform(libs.testcontainers.bom))
api("org.testcontainers:rabbitmq") {
api("org.testcontainers:testcontainers-rabbitmq") {
because("integration with rabbitmq")
}
api(libs.commons.compress) {
because("'1.24.0' version has CVE-2024-25710, CVE-2024-26308 vulnerabilities")
}
api("org.testcontainers:cassandra") {
api("org.testcontainers:testcontainers-cassandra") {
because("integration with cradle")
}
implementation("com.datastax.oss:java-driver-core") {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
kotlin.code.style=official
release_version=0.1.0
release_version=0.2.0

description=JUnit Jupiter extension for th2 integration testing
vcs_url=https://github.com/th2-net/junit-jupiter-integration
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ logback-core = { group = "ch.qos.logback", name = "logback-core", version.ref =
logback-classic = { group = "ch.qos.logback", name = "logback-classic", version.ref = "logback" }

junit-bom = { group = "org.junit", name = "junit-bom", version = "5.13.4" }
testcontainers-bom = { group = "org.testcontainers", name = "testcontainers-bom", version = "1.21.3" }
testcontainers-bom = { group = "org.testcontainers", name = "testcontainers-bom", version = "2.0.1" }

[plugins]
th2-publish = { id = "com.exactpro.th2.gradle.publish", version = "0.3.9" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,21 @@
package com.exactpro.th2.test.extension

import io.github.oshai.kotlinlogging.KotlinLogging
import org.apache.commons.lang3.RandomStringUtils
import org.junit.jupiter.api.extension.AfterEachCallback
import org.junit.jupiter.api.extension.BeforeAllCallback
import org.junit.jupiter.api.extension.BeforeEachCallback
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.api.extension.ExtensionContext.Namespace
import org.junit.jupiter.api.extension.ParameterContext
import org.junit.jupiter.api.extension.ParameterResolver
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils
import java.util.LinkedList

public class CleanupExtension : BeforeEachCallback, BeforeAllCallback, AfterEachCallback, ParameterResolver {
public class CleanupExtension :
BeforeEachCallback,
BeforeAllCallback,
AfterEachCallback,
ParameterResolver {
override fun beforeEach(context: ExtensionContext) {
context.getStore(NAMESPACE).put(AFTER_TEST_KEY, ClosableRegistry(Registry()))
}
Expand All @@ -46,9 +50,13 @@ public class CleanupExtension : BeforeEachCallback, BeforeAllCallback, AfterEach
internal val resources = LinkedList<Pair<String, AutoCloseable>>()

public fun add(resource: AutoCloseable) {
add(RandomStringUtils.randomAlphabetic(10), resource)
add(RandomStringUtils.insecure().nextAlphabetic(10), resource)
}
public fun add(name: String, resource: AutoCloseable) {

public fun add(
name: String,
resource: AutoCloseable,
) {
check(resources.find { it.first == name } == null) {
"duplicated resource $name"
}
Expand All @@ -58,8 +66,7 @@ public class CleanupExtension : BeforeEachCallback, BeforeAllCallback, AfterEach

private class ClosableRegistry(
val registry: Registry,
) : ExtensionContext.Store.CloseableResource {

) : AutoCloseable {
override fun close() {
registry.resources.descendingIterator().forEach { (name, resource) ->
runCatching {
Expand All @@ -72,11 +79,15 @@ public class CleanupExtension : BeforeEachCallback, BeforeAllCallback, AfterEach
}
}

override fun supportsParameter(parameterContext: ParameterContext, extensionContext: ExtensionContext): Boolean {
return parameterContext.parameter.type == Registry::class.java
}
override fun supportsParameter(
parameterContext: ParameterContext,
extensionContext: ExtensionContext,
): Boolean = parameterContext.parameter.type == Registry::class.java

override fun resolveParameter(parameterContext: ParameterContext, extensionContext: ExtensionContext): Any {
override fun resolveParameter(
parameterContext: ParameterContext,
extensionContext: ExtensionContext,
): Any {
val store = extensionContext.getStore(NAMESPACE)
// if we have registry for AFTER_TEST_KEY key it means the parameter is resolved for test method
// or in before
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import org.junit.jupiter.api.extension.AfterAllCallback
import org.junit.jupiter.api.extension.BeforeAllCallback
import org.junit.jupiter.api.extension.BeforeEachCallback
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.api.extension.ExtensionContext.Store.CloseableResource
import org.junit.jupiter.api.extension.ParameterContext
import org.junit.jupiter.api.extension.ParameterResolver
import org.junit.jupiter.api.extension.TestInstancePostProcessor
Expand Down Expand Up @@ -170,7 +169,7 @@ public class Th2CradleExtension :

private class ClosableCradleResource(
val manager: CradleManager,
) : CloseableResource {
) : AutoCloseable {
override fun close() {
LOGGER.info { "Closing cradle manager resolved as a parameter" }
manager.close()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Exactpro (Exactpro Systems Limited)
* Copyright 2023-2025 Exactpro (Exactpro Systems Limited)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,18 +25,23 @@ import com.exactpro.th2.common.schema.grpc.configuration.GrpcServiceConfiguratio
import com.exactpro.th2.common.schema.strategy.route.impl.RobinRoutingStrategy
import com.exactpro.th2.test.integration.ConfigurationWriter
import com.exactpro.th2.test.spec.GrpcSpec
import org.apache.commons.lang3.RandomStringUtils
import org.junit.jupiter.api.extension.BeforeAllCallback
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.api.extension.TestInstancePostProcessor
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils
import java.io.IOException
import java.net.ServerSocket
import kotlin.io.path.outputStream

public class Th2GrpcExtension : TestInstancePostProcessor, BeforeAllCallback {
public class Th2GrpcExtension :
TestInstancePostProcessor,
BeforeAllCallback {
private var spec: GrpcSpec? = null

override fun postProcessTestInstance(testInstance: Any, context: ExtensionContext) {
override fun postProcessTestInstance(
testInstance: Any,
context: ExtensionContext,
) {
val fields = testInstance::class.findFields<GrpcSpec>().ifEmpty { return }
spec = testInstance.getSingle(fields)
}
Expand Down Expand Up @@ -76,20 +81,25 @@ public class Th2GrpcExtension : TestInstancePostProcessor, BeforeAllCallback {
testPort: Int,
) = GrpcConfiguration(
serverConfiguration = GrpcServerConfiguration(port = appPort),
services = grpcSpec.clients.associate {
"${it.type.simpleName}-${RandomStringUtils.randomAlphabetic(5)}" to GrpcServiceConfiguration(
strategy = RobinRoutingStrategy().apply {
init(GrpcRawRobinStrategy(endpoints = listOf("test-endpoint")))
},
serviceClass = it.type,
endpoints = mapOf(
"test-endpoint" to GrpcEndpointConfiguration(
host = "localhost",
port = testPort,
attributes = it.attributes.toList(),
services =
grpcSpec.clients.associate {
"${it.type.simpleName}-${RandomStringUtils.insecure().nextAlphabetic(5)}" to
GrpcServiceConfiguration(
strategy =
RobinRoutingStrategy().apply {
init(GrpcRawRobinStrategy(endpoints = listOf("test-endpoint")))
},
serviceClass = it.type,
endpoints =
mapOf(
"test-endpoint" to
GrpcEndpointConfiguration(
host = "localhost",
port = testPort,
attributes = it.attributes.toList(),
),
),
),
)
)
},
)

Expand All @@ -99,23 +109,31 @@ public class Th2GrpcExtension : TestInstancePostProcessor, BeforeAllCallback {
testPort: Int,
) = GrpcConfiguration(
serverConfiguration = GrpcServerConfiguration(port = testPort),
services = grpcSpec.servers.associate {
"${it.simpleName}-${RandomStringUtils.randomAlphabetic(5)}" to GrpcServiceConfiguration(
strategy = RobinRoutingStrategy().apply {
init(GrpcRawRobinStrategy(endpoints = listOf("test-endpoint")))
},
serviceClass = it,
endpoints = mapOf(
"test-endpoint" to GrpcEndpointConfiguration(
host = "localhost",
port = appPort,
services =
grpcSpec.servers.associate {
"${it.simpleName}-${RandomStringUtils.insecure().nextAlphabetic(5)}" to
GrpcServiceConfiguration(
strategy =
RobinRoutingStrategy().apply {
init(GrpcRawRobinStrategy(endpoints = listOf("test-endpoint")))
},
serviceClass = it,
endpoints =
mapOf(
"test-endpoint" to
GrpcEndpointConfiguration(
host = "localhost",
port = appPort,
),
),
),
)
)
},
)

private fun findFreePort(start: Int = 1025, end: Int = 30000): Int {
private fun findFreePort(
start: Int = 1025,
end: Int = 30000,
): Int {
for (port in start..end) {
try {
ServerSocket(port).use {
Expand Down