From fa61e76c53a27b012844ec107d8093d33857d23c Mon Sep 17 00:00:00 2001 From: Adrian Paschkowski Date: Sun, 3 Dec 2023 17:57:38 +0100 Subject: [PATCH] Add a first test --- latte/build.gradle.kts | 9 ++ .../java/gg/beemo/latte/TestBrokerClient.kt | 90 ------------------- .../gg/beemo/latte/broker/BrokerSubclients.kt | 2 + .../java/gg/beemo/latte/util/MoshiAdapters.kt | 19 ++++ .../gg/beemo/latte/broker/BrokerClientTest.kt | 28 ++++++ .../gg/beemo/latte/broker/TestBrokerClient.kt | 34 +++++++ 6 files changed, 92 insertions(+), 90 deletions(-) delete mode 100644 latte/src/main/java/gg/beemo/latte/TestBrokerClient.kt create mode 100644 latte/src/test/kotlin/gg/beemo/latte/broker/BrokerClientTest.kt create mode 100644 latte/src/test/kotlin/gg/beemo/latte/broker/TestBrokerClient.kt diff --git a/latte/build.gradle.kts b/latte/build.gradle.kts index e524cf0..394d1b8 100644 --- a/latte/build.gradle.kts +++ b/latte/build.gradle.kts @@ -26,6 +26,11 @@ dependencies { implementation("org.jetbrains:annotations:24.1.0") compileOnly("org.apache.logging.log4j:log4j-api:2.22.0") + // JUnit testing framework + val junitVersion = "5.10.1" + testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion") + } repositories { @@ -36,4 +41,8 @@ kotlin { jvmToolchain(17) } +tasks.test { + useJUnitPlatform() +} + defaultTasks("build") diff --git a/latte/src/main/java/gg/beemo/latte/TestBrokerClient.kt b/latte/src/main/java/gg/beemo/latte/TestBrokerClient.kt deleted file mode 100644 index d78fa08..0000000 --- a/latte/src/main/java/gg/beemo/latte/TestBrokerClient.kt +++ /dev/null @@ -1,90 +0,0 @@ -package gg.beemo.latte - -import gg.beemo.latte.broker.BrokerClient -import gg.beemo.latte.broker.BrokerConnection -import gg.beemo.latte.broker.BrokerMessage -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.toList -import kotlin.time.Duration.Companion.seconds - -class Tea { - companion object { - val cluster: Cluster = Cluster() - } - - class Cluster { - suspend fun restartShard(id: ShardId) {} - } -} - -class ShardId -class RaidUser -data class ShardRestartRequest(val shardId: ShardId) -data class GreetingRequest(val name: String) -data class GreetingResponse(val greeting: String) - -// ------------------------------ - -class TestBrokerClient(connection: BrokerConnection) : BrokerClient(connection) { - - init { - consumer( - topic = "cluster.shard", - key = "restart", - ) { - Tea.cluster.restartShard(it.value.shardId) - } - } - - private val raidBanQueue = producer( - topic = "raid.bans", - key = "ban.enqueue", - ) - - private val greetingRpc = rpc( - topic = "rpc.greetings", - key = "greeting.requests", - ) { - delay(2.seconds) - return@rpc GreetingResponse("Hello, ${it.value.name}") - } - - private val nullRpc = rpc( - topic = "null", - key = "null", - ) { - if (it.value != null) { - throw IllegalStateException("nullRpc received non-null") - } - return@rpc null - } - - suspend fun enqueueRaidBan(user: RaidUser) { - raidBanQueue.send(user) - } - - suspend fun sendNull() { - val definitelyNull = nullRpc.call(null) - val value = definitelyNull.value - if (value != null) { - throw IllegalStateException("nullRpc returned non-null") - } - } - - suspend fun createGreeting(name: String): String { - val response = greetingRpc.call( - GreetingRequest(name), - services = setOf(CommonConfig.BrokerServices.TEA), - instances = setOf("0"), - timeout = 5.seconds, - ) - return response.value.greeting - } - - suspend fun collectGreetings(name: String): List { - val flow = greetingRpc.stream(GreetingRequest(name)) - return flow.map { it.value.greeting }.toList() - } - -} diff --git a/latte/src/main/java/gg/beemo/latte/broker/BrokerSubclients.kt b/latte/src/main/java/gg/beemo/latte/broker/BrokerSubclients.kt index 4efd24a..4c9ae09 100644 --- a/latte/src/main/java/gg/beemo/latte/broker/BrokerSubclients.kt +++ b/latte/src/main/java/gg/beemo/latte/broker/BrokerSubclients.kt @@ -3,6 +3,7 @@ package gg.beemo.latte.broker import com.squareup.moshi.JsonAdapter import com.squareup.moshi.Moshi import gg.beemo.latte.util.MoshiInstantAdapter +import gg.beemo.latte.util.MoshiUnitAdapter import gg.beemo.latte.util.SuspendingCountDownLatch import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.coroutineScope @@ -30,6 +31,7 @@ sealed class BaseSubclient( // https://github.com/square/moshi#custom-type-adapters @JvmStatic protected val moshi: Moshi = Moshi.Builder() + .add(MoshiUnitAdapter()) .add(MoshiInstantAdapter()) .build() } diff --git a/latte/src/main/java/gg/beemo/latte/util/MoshiAdapters.kt b/latte/src/main/java/gg/beemo/latte/util/MoshiAdapters.kt index 37b9915..de71274 100644 --- a/latte/src/main/java/gg/beemo/latte/util/MoshiAdapters.kt +++ b/latte/src/main/java/gg/beemo/latte/util/MoshiAdapters.kt @@ -1,18 +1,37 @@ package gg.beemo.latte.util +import com.squareup.moshi.FromJson import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonWriter +import com.squareup.moshi.ToJson import java.time.Instant class MoshiInstantAdapter : JsonAdapter() { + @FromJson override fun fromJson(reader: JsonReader): Instant? { return Instant.ofEpochMilli(reader.nextLong()) } + @ToJson override fun toJson(writer: JsonWriter, value: Instant?) { writer.value(value?.toEpochMilli()) } } + +class MoshiUnitAdapter : JsonAdapter() { + + @FromJson + override fun fromJson(reader: JsonReader): Unit? { + reader.skipValue() + return Unit + } + + @ToJson + override fun toJson(writer: JsonWriter, value: Unit?) { + writer.nullValue() + } + +} diff --git a/latte/src/test/kotlin/gg/beemo/latte/broker/BrokerClientTest.kt b/latte/src/test/kotlin/gg/beemo/latte/broker/BrokerClientTest.kt new file mode 100644 index 0000000..f983d1c --- /dev/null +++ b/latte/src/test/kotlin/gg/beemo/latte/broker/BrokerClientTest.kt @@ -0,0 +1,28 @@ +package gg.beemo.latte.broker + +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class BrokerClientTest { + + private val connection = LocalConnection() + private val client = TestBrokerClient(connection) + + @Test + fun `test greeting RPC`() { + runBlocking { + val response = client.greetingRpc.call(GreetingRequest("Beemo")) + Assertions.assertEquals("Hello, Beemo", response.value.greeting) + } + } + + @Test + fun `test null RPC`() { + runBlocking { + val response = client.nullRpc.call(null) + Assertions.assertNull(response.value) + } + } + +} diff --git a/latte/src/test/kotlin/gg/beemo/latte/broker/TestBrokerClient.kt b/latte/src/test/kotlin/gg/beemo/latte/broker/TestBrokerClient.kt new file mode 100644 index 0000000..1690736 --- /dev/null +++ b/latte/src/test/kotlin/gg/beemo/latte/broker/TestBrokerClient.kt @@ -0,0 +1,34 @@ +package gg.beemo.latte.broker + +import com.squareup.moshi.JsonClass +import kotlinx.coroutines.delay +import kotlin.time.Duration.Companion.seconds + + +@JsonClass(generateAdapter = true) +data class GreetingRequest(val name: String) + +@JsonClass(generateAdapter = true) +data class GreetingResponse(val greeting: String) + +class TestBrokerClient(connection: BrokerConnection) : BrokerClient(connection) { + + val greetingRpc = rpc( + topic = "rpc.greetings", + key = "greeting.requests", + ) { + delay(2.seconds) + return@rpc GreetingResponse("Hello, ${it.value.name}") + } + + val nullRpc = rpc( + topic = "null", + key = "null", + ) { + if (it.value != null) { + throw IllegalStateException("nullRpc received non-null") + } + return@rpc null + } + +}