-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Project/CI setup for the sdk-test-tool * Services implementation * No need to setup docker buildx/qemu * Use sdk-test-suite 1.1
- Loading branch information
1 parent
aa33ad4
commit f71f940
Showing
31 changed files
with
1,256 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Java services | ||
|
||
## Running the services | ||
|
||
The Java services can be run via: | ||
|
||
```shell | ||
SERVICES=<COMMA_SEPARATED_LIST_OF_SERVICES> gradle run | ||
``` | ||
|
||
For the list of supported services see [here](src/main/java/my/restate/e2e/services/Main.java). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.getCurrentArchitecture | ||
|
||
plugins { | ||
`java-conventions` | ||
`kotlin-conventions` | ||
alias(kotlinLibs.plugins.ksp) | ||
application | ||
id("com.google.cloud.tools.jib") version "3.2.1" | ||
} | ||
|
||
dependencies { | ||
ksp(project(":sdk-api-kotlin-gen")) | ||
|
||
implementation(project(":sdk-api-kotlin")) | ||
implementation(project(":sdk-http-vertx")) | ||
implementation(project(":sdk-serde-jackson")) | ||
implementation(project(":sdk-request-identity")) | ||
|
||
implementation(kotlinLibs.kotlinx.serialization.core) | ||
implementation(kotlinLibs.kotlinx.serialization.json) | ||
|
||
implementation(coreLibs.log4j.core) | ||
} | ||
|
||
// Configuration of jib container images parameters | ||
|
||
fun testHostArchitecture(): String { | ||
val currentArchitecture = getCurrentArchitecture() | ||
|
||
return if (currentArchitecture.isAmd64) { | ||
"amd64" | ||
} else { | ||
when (currentArchitecture.name) { | ||
"arm-v8", | ||
"aarch64", | ||
"arm64", | ||
"aarch_64" -> "arm64" | ||
else -> | ||
throw IllegalArgumentException("Not supported host architecture: $currentArchitecture") | ||
} | ||
} | ||
} | ||
|
||
fun testBaseImage(): String { | ||
return when (testHostArchitecture()) { | ||
"arm64" -> | ||
"eclipse-temurin:17-jre@sha256:61c5fee7a5c40a1ca93231a11b8caf47775f33e3438c56bf3a1ea58b7df1ee1b" | ||
"amd64" -> | ||
"eclipse-temurin:17-jre@sha256:ff7a89fe868ba504b09f93e3080ad30a75bd3d4e4e7b3e037e91705f8c6994b3" | ||
else -> | ||
throw IllegalArgumentException("No image for host architecture: ${testHostArchitecture()}") | ||
} | ||
} | ||
|
||
jib { | ||
to.image = "restatedev/java-test-services" | ||
from.image = testBaseImage() | ||
|
||
from { | ||
platforms { | ||
platform { | ||
architecture = testHostArchitecture() | ||
os = "linux" | ||
} | ||
} | ||
} | ||
} | ||
|
||
tasks.jar { manifest { attributes["Main-Class"] = "dev.restate.sdk.testservices.MainKt" } } | ||
|
||
application { mainClass.set("dev.restate.sdk.testservices.MainKt") } |
36 changes: 36 additions & 0 deletions
36
test-services/src/main/kotlin/dev/restate/sdk/testservices/AwakeableHolderImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright (c) 2023 - Restate Software, Inc., Restate GmbH | ||
// | ||
// This file is part of the Restate Java SDK, | ||
// which is released under the MIT license. | ||
// | ||
// You can find a copy of the license in file LICENSE in the root | ||
// directory of this repository or package, or at | ||
// https://github.com/restatedev/sdk-java/blob/main/LICENSE | ||
package dev.restate.sdk.testservices | ||
|
||
import dev.restate.sdk.common.StateKey | ||
import dev.restate.sdk.common.TerminalException | ||
import dev.restate.sdk.kotlin.KtStateKey | ||
import dev.restate.sdk.kotlin.ObjectContext | ||
import dev.restate.sdk.kotlin.resolve | ||
import dev.restate.sdktesting.contracts.AwakeableHolder | ||
|
||
class AwakeableHolderImpl : AwakeableHolder { | ||
companion object { | ||
private val ID_KEY: StateKey<String> = KtStateKey.json<String>("id") | ||
} | ||
|
||
override suspend fun hold(context: ObjectContext, id: String) { | ||
context.set(ID_KEY, id) | ||
} | ||
|
||
override suspend fun hasAwakeable(context: ObjectContext): Boolean { | ||
return context.get(ID_KEY) != null | ||
} | ||
|
||
override suspend fun unlock(context: ObjectContext, payload: String) { | ||
val awakeableId: String = | ||
context.get(ID_KEY) ?: throw TerminalException("No awakeable registered") | ||
context.awakeableHandle(awakeableId).resolve(payload) | ||
} | ||
} |
47 changes: 47 additions & 0 deletions
47
test-services/src/main/kotlin/dev/restate/sdk/testservices/BlockAndWaitWorkflowImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Copyright (c) 2023 - Restate Software, Inc., Restate GmbH | ||
// | ||
// This file is part of the Restate Java SDK, | ||
// which is released under the MIT license. | ||
// | ||
// You can find a copy of the license in file LICENSE in the root | ||
// directory of this repository or package, or at | ||
// https://github.com/restatedev/sdk-java/blob/main/LICENSE | ||
package dev.restate.sdk.testservices | ||
|
||
import dev.restate.sdk.common.DurablePromiseKey | ||
import dev.restate.sdk.common.StateKey | ||
import dev.restate.sdk.common.TerminalException | ||
import dev.restate.sdk.kotlin.KtSerdes | ||
import dev.restate.sdk.kotlin.KtStateKey | ||
import dev.restate.sdk.kotlin.SharedWorkflowContext | ||
import dev.restate.sdk.kotlin.WorkflowContext | ||
import dev.restate.sdktesting.contracts.BlockAndWaitWorkflow | ||
|
||
class BlockAndWaitWorkflowImpl : BlockAndWaitWorkflow { | ||
companion object { | ||
private val MY_DURABLE_PROMISE: DurablePromiseKey<String> = | ||
DurablePromiseKey.of("durable-promise", KtSerdes.json()) | ||
private val MY_STATE: StateKey<String> = KtStateKey.json("my-state") | ||
} | ||
|
||
override suspend fun run(context: WorkflowContext, input: String): String { | ||
context.set(MY_STATE, input) | ||
|
||
// Wait on unblock | ||
val output: String = context.promise(MY_DURABLE_PROMISE).awaitable().await() | ||
|
||
if (!context.promise(MY_DURABLE_PROMISE).peek().isReady) { | ||
throw TerminalException("Durable promise should be completed") | ||
} | ||
|
||
return output | ||
} | ||
|
||
override suspend fun unblock(context: SharedWorkflowContext, output: String) { | ||
context.promiseHandle(MY_DURABLE_PROMISE).resolve(output) | ||
} | ||
|
||
override suspend fun getState(context: SharedWorkflowContext): String? { | ||
return context.get(MY_STATE) | ||
} | ||
} |
71 changes: 71 additions & 0 deletions
71
test-services/src/main/kotlin/dev/restate/sdk/testservices/CancelTestImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Copyright (c) 2023 - Restate Software, Inc., Restate GmbH | ||
// | ||
// This file is part of the Restate Java SDK, | ||
// which is released under the MIT license. | ||
// | ||
// You can find a copy of the license in file LICENSE in the root | ||
// directory of this repository or package, or at | ||
// https://github.com/restatedev/sdk-java/blob/main/LICENSE | ||
package dev.restate.sdk.testservices | ||
|
||
import dev.restate.sdk.common.StateKey | ||
import dev.restate.sdk.common.TerminalException | ||
import dev.restate.sdk.kotlin.Awakeable | ||
import dev.restate.sdk.kotlin.KtStateKey | ||
import dev.restate.sdk.kotlin.ObjectContext | ||
import dev.restate.sdk.kotlin.awakeable | ||
import dev.restate.sdktesting.contracts.AwakeableHolderClient | ||
import dev.restate.sdktesting.contracts.BlockingOperation | ||
import dev.restate.sdktesting.contracts.CancelTest | ||
import dev.restate.sdktesting.contracts.CancelTestBlockingServiceClient | ||
import kotlin.time.Duration.Companion.days | ||
|
||
class CancelTestImpl { | ||
class RunnerImpl : CancelTest.Runner { | ||
companion object { | ||
private val CANCELED_STATE: StateKey<Boolean> = KtStateKey.json("canceled") | ||
} | ||
|
||
override suspend fun startTest(context: ObjectContext, operation: BlockingOperation) { | ||
val client = CancelTestBlockingServiceClient.fromContext(context, "") | ||
|
||
try { | ||
client.block(operation).await() | ||
} catch (e: TerminalException) { | ||
if (e.code == TerminalException.CANCELLED_CODE) { | ||
context.set(CANCELED_STATE, true) | ||
} else { | ||
throw e | ||
} | ||
} | ||
} | ||
|
||
override suspend fun verifyTest(context: ObjectContext): Boolean { | ||
return context.get(CANCELED_STATE) ?: false | ||
} | ||
} | ||
|
||
class BlockingService : CancelTest.BlockingService { | ||
override suspend fun block(context: ObjectContext, operation: BlockingOperation) { | ||
val self = CancelTestBlockingServiceClient.fromContext(context, "") | ||
val client = AwakeableHolderClient.fromContext(context, "cancel") | ||
|
||
val awakeable = context.awakeable<String>() | ||
client.hold(awakeable.id).await() | ||
awakeable.await() | ||
|
||
when (operation) { | ||
BlockingOperation.CALL -> self.block(operation).await() | ||
BlockingOperation.SLEEP -> context.sleep(1024.days) | ||
BlockingOperation.AWAKEABLE -> { | ||
val uncompletable: Awakeable<String> = context.awakeable<String>() | ||
uncompletable.await() | ||
} | ||
} | ||
} | ||
|
||
override suspend fun isUnlocked(context: ObjectContext) { | ||
// no-op | ||
} | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
test-services/src/main/kotlin/dev/restate/sdk/testservices/CounterImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright (c) 2023 - Restate Software, Inc., Restate GmbH | ||
// | ||
// This file is part of the Restate Java SDK, | ||
// which is released under the MIT license. | ||
// | ||
// You can find a copy of the license in file LICENSE in the root | ||
// directory of this repository or package, or at | ||
// https://github.com/restatedev/sdk-java/blob/main/LICENSE | ||
package dev.restate.sdk.testservices | ||
|
||
import dev.restate.sdk.common.StateKey | ||
import dev.restate.sdk.common.TerminalException | ||
import dev.restate.sdk.kotlin.KtStateKey | ||
import dev.restate.sdk.kotlin.ObjectContext | ||
import dev.restate.sdk.kotlin.SharedObjectContext | ||
import dev.restate.sdktesting.contracts.Counter | ||
import dev.restate.sdktesting.contracts.CounterUpdateResponse | ||
import org.apache.logging.log4j.LogManager | ||
import org.apache.logging.log4j.Logger | ||
|
||
class CounterImpl : Counter { | ||
|
||
companion object { | ||
private val logger: Logger = LogManager.getLogger(CounterImpl::class.java) | ||
|
||
private val COUNTER_KEY: StateKey<Long> = KtStateKey.json<Long>("counter") | ||
} | ||
|
||
override suspend fun reset(context: ObjectContext) { | ||
logger.info("Counter cleaned up") | ||
context.clear(COUNTER_KEY) | ||
} | ||
|
||
override suspend fun addThenFail(context: ObjectContext, value: Long) { | ||
var counter: Long = context.get(COUNTER_KEY) ?: 0L | ||
logger.info("Old counter value: {}", counter) | ||
|
||
counter += value | ||
context.set(COUNTER_KEY, counter) | ||
|
||
logger.info("New counter value: {}", counter) | ||
|
||
throw TerminalException(context.key()) | ||
} | ||
|
||
override suspend fun get(context: SharedObjectContext): Long { | ||
val counter: Long = context.get(COUNTER_KEY) ?: 0L | ||
logger.info("Get counter value: {}", counter) | ||
return counter | ||
} | ||
|
||
override suspend fun add(context: ObjectContext, value: Long): CounterUpdateResponse { | ||
val oldCount: Long = context.get(COUNTER_KEY) ?: 0L | ||
val newCount = oldCount + value | ||
context.set(COUNTER_KEY, newCount) | ||
|
||
logger.info("Old counter value: {}", oldCount) | ||
logger.info("New counter value: {}", newCount) | ||
|
||
return CounterUpdateResponse(oldCount, newCount) | ||
} | ||
} |
Oops, something went wrong.