Skip to content

Commit 332efa3

Browse files
committed
fix: dynamically select port for DDB Local
1 parent 557b8fa commit 332efa3

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

hll/dynamodb-mapper/dynamodb-mapper/build.gradle.kts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer
99
import com.google.devtools.ksp.gradle.KspTaskJvm
1010
import com.google.devtools.ksp.gradle.KspTaskMetadata
1111
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
12+
import java.net.ServerSocket
1213
import java.nio.file.Files
1314
import java.nio.file.StandardCopyOption
15+
import kotlin.properties.Delegates
1416

1517
description = "High level DynamoDbMapper client"
1618
extra["displayName"] = "AWS :: SDK :: Kotlin :: HLL :: DynamoDbMapper"
@@ -128,29 +130,41 @@ if (project.NATIVE_ENABLED) {
128130
}
129131

130132
open class DynamoDbLocalInstance : DefaultTask() {
131-
private val port = 44212 // Keep in sync with DdbLocalTest.kt
133+
private var port: Int by Delegates.notNull()
134+
135+
@OutputFile
136+
val portFile = project.objects.fileProperty()
132137

133138
@Internal
134139
var runner: DynamoDBProxyServer? = null
135140
private set
136141

137142
@TaskAction
138143
fun exec() {
139-
println("Running DynamoDB local instance on port $port")
144+
port = ServerSocket(0).use { it.localPort }
145+
146+
println("Starting DynamoDB local instance on port $port")
140147
runner = ServerRunner
141148
.createServerFromCommandLineArgs(arrayOf("-inMemory", "-port", port.toString(), "-disableTelemetry"))
142149
.also { it.start() }
150+
151+
portFile.asFile.get().writeText(port.toString())
143152
}
144153

145154
fun stop() {
155+
runCatching { portFile.asFile.get().delete() }.onFailure { t -> println("Failed to delete $portFile: $t") }
156+
146157
runner?.let {
147158
println("Stopping DynamoDB local instance on port $port")
148159
it.stop()
149160
}
150161
}
151162
}
152163

153-
val startDdbLocal = task<DynamoDbLocalInstance>("startDdbLocal")
164+
val startDdbLocal = task<DynamoDbLocalInstance>("startDdbLocal") {
165+
portFile.set(file("build/ddblocal/port.info")) // Keep in sync with DdbLocalTest.kt
166+
outputs.upToDateWhen { false } // Always run this task even if a portFile already exists
167+
}
154168

155169
tasks.withType<Test> {
156170
dependsOn(startDdbLocal)

hll/dynamodb-mapper/dynamodb-mapper/jvm/test/aws/sdk/kotlin/hll/dynamodbmapper/testutils/DdbLocalTest.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@ import aws.smithy.kotlin.runtime.net.Scheme
2020
import aws.smithy.kotlin.runtime.net.url.Url
2121
import io.kotest.core.spec.style.AnnotationSpec
2222
import kotlinx.coroutines.runBlocking
23+
import java.io.File
2324
import kotlin.test.assertContains
2425
import kotlin.test.assertEquals
2526
import kotlin.test.assertNotNull
2627

27-
private const val DDB_LOCAL_PORT = 44212 // Keep in sync with build.gradle.kts
28-
2928
/**
3029
* The base class for test classes which need DynamoDB Local running. This class provides a few convenience declarations
3130
* for subclasses:
@@ -50,11 +49,14 @@ abstract class DdbLocalTest : AnnotationSpec() {
5049
private val requestInterceptor = RequestCapturingInterceptor(this@DdbLocalTest.requests)
5150

5251
private val ddbHolder = lazy {
52+
val portFile = File("build/ddblocal/port.info").absoluteFile // Keep in sync with build.gradle.kts
53+
val port = portFile.readText().toInt()
54+
5355
DynamoDbClient {
5456
endpointUrl = Url {
5557
scheme = Scheme.HTTP
5658
host = Host.Domain("localhost")
57-
port = DDB_LOCAL_PORT
59+
this.port = port
5860
}
5961

6062
region = "DUMMY"

0 commit comments

Comments
 (0)