Skip to content

Commit ab9fb2e

Browse files
committed
Add tests
1 parent 18d7049 commit ab9fb2e

File tree

3 files changed

+148
-68
lines changed

3 files changed

+148
-68
lines changed

grpc/grpc-core/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ kotlin {
3636
commonTest {
3737
dependencies {
3838
implementation(libs.kotlin.test)
39+
implementation(libs.coroutines.test)
3940
}
4041
}
4142

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.rpc.grpc
6+
7+
import kotlinx.coroutines.CoroutineScope
8+
import kotlinx.coroutines.flow.flowOf
9+
import kotlinx.coroutines.flow.map
10+
import kotlinx.coroutines.flow.toList
11+
import kotlinx.io.Buffer
12+
import kotlinx.io.Source
13+
import kotlinx.io.readString
14+
import kotlinx.io.writeString
15+
import kotlinx.rpc.grpc.internal.GrpcChannel
16+
import kotlinx.rpc.grpc.internal.MessageCodec
17+
import kotlinx.rpc.grpc.internal.MethodDescriptor
18+
import kotlinx.rpc.grpc.internal.MethodType
19+
import kotlinx.rpc.grpc.internal.ServerMethodDefinition
20+
import kotlinx.rpc.grpc.internal.bidiStreamingServerMethodDefinition
21+
import kotlinx.rpc.grpc.internal.bidirectionalStreamingRpc
22+
import kotlinx.rpc.grpc.internal.clientStreamingRpc
23+
import kotlinx.rpc.grpc.internal.clientStreamingServerMethodDefinition
24+
import kotlinx.rpc.grpc.internal.methodDescriptor
25+
import kotlinx.rpc.grpc.internal.serverStreamingRpc
26+
import kotlinx.rpc.grpc.internal.serverStreamingServerMethodDefinition
27+
import kotlinx.rpc.grpc.internal.serviceDescriptor
28+
import kotlinx.rpc.grpc.internal.unaryRpc
29+
import kotlinx.rpc.grpc.internal.unaryServerMethodDefinition
30+
import kotlin.test.Test
31+
import kotlin.test.assertEquals
32+
33+
private const val PORT = 8082
34+
35+
class RawClientServerTest {
36+
@Test
37+
fun unaryCall() = runTest(
38+
methodName = "unary",
39+
type = MethodType.UNARY,
40+
methodDefinition = { descriptor ->
41+
unaryServerMethodDefinition(descriptor) { it + it }
42+
},
43+
) { channel, descriptor ->
44+
val response = unaryRpc(channel, descriptor, "Hello")
45+
46+
assertEquals("HelloHello", response)
47+
}
48+
49+
@Test
50+
fun serverStreamingCall() = runTest(
51+
methodName = "serverStreaming",
52+
type = MethodType.SERVER_STREAMING,
53+
methodDefinition = { descriptor ->
54+
serverStreamingServerMethodDefinition(descriptor) {
55+
flowOf(it, it)
56+
}
57+
}
58+
) { channel, descriptor ->
59+
val response = serverStreamingRpc(channel, descriptor, "Hello")
60+
61+
assertEquals(listOf("Hello", "Hello"), response.toList())
62+
}
63+
64+
@Test
65+
fun clientStreamingCall() = runTest(
66+
methodName = "clientStreaming",
67+
type = MethodType.CLIENT_STREAMING,
68+
methodDefinition = { descriptor ->
69+
clientStreamingServerMethodDefinition(descriptor) {
70+
it.toList().joinToString(separator = "")
71+
}
72+
}
73+
) { channel, descriptor ->
74+
val response = clientStreamingRpc(channel, descriptor, flowOf("Hello", "World"))
75+
76+
assertEquals("HelloWorld", response)
77+
}
78+
79+
@Test
80+
fun bidirectionalStreamingCall() = runTest(
81+
methodName = "bidirectionalStreaming",
82+
type = MethodType.BIDI_STREAMING,
83+
methodDefinition = { descriptor ->
84+
bidiStreamingServerMethodDefinition(descriptor) {
85+
it.map { str -> str + str }
86+
}
87+
}
88+
) { channel, descriptor ->
89+
val response = bidirectionalStreamingRpc(channel, descriptor, flowOf("Hello", "World"))
90+
.toList()
91+
92+
assertEquals(listOf("HelloHello", "WorldWorld"), response)
93+
}
94+
95+
private fun runTest(
96+
methodName: String,
97+
type: MethodType,
98+
methodDefinition: CoroutineScope.(MethodDescriptor<String, String>) -> ServerMethodDefinition<String, String>,
99+
block: suspend (GrpcChannel, MethodDescriptor<String, String>) -> Unit,
100+
) = kotlinx.coroutines.test.runTest {
101+
val clientChannel = ManagedChannelBuilder("localhost", PORT).apply {
102+
usePlaintext()
103+
}.buildChannel()
104+
105+
val descriptor = methodDescriptor(
106+
fullMethodName = "${SERVICE_NAME}/$methodName",
107+
requestCodec = simpleCodec,
108+
responseCodec = simpleCodec,
109+
type = type,
110+
schemaDescriptor = Unit,
111+
idempotent = true,
112+
safe = true,
113+
sampledToLocalTracing = true,
114+
)
115+
116+
val methods = listOf(descriptor)
117+
118+
val builder = ServerBuilder(PORT).addService(
119+
serverServiceDefinition(
120+
serviceDescriptor = serviceDescriptor(
121+
name = SERVICE_NAME,
122+
methods = methods,
123+
schemaDescriptor = Unit,
124+
),
125+
methods = methods.map { methodDefinition(it) },
126+
)
127+
)
128+
val server = Server(builder)
129+
server.start()
130+
131+
block(clientChannel.platformApi, descriptor)
132+
}
133+
134+
companion object {
135+
private const val SERVICE_NAME = "TestService"
136+
137+
private val simpleCodec = object : MessageCodec<String> {
138+
override fun encode(value: String): Source {
139+
return Buffer().apply { writeString(value) }
140+
}
141+
142+
override fun decode(stream: Source): String {
143+
return stream.readString()
144+
}
145+
}
146+
}
147+
}
Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,3 @@
11
/*
22
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
33
*/
4-
5-
package kotlinx.rpc.grpc.pb
6-
7-
import kotlinx.io.Buffer
8-
import kotlinx.rpc.grpc.test.common.*
9-
import kotlin.test.Test
10-
import kotlin.test.assertEquals
11-
12-
class ProtosTest {
13-
14-
private fun <T : Any> decodeEncode(
15-
msg: T,
16-
enc: T.(WireEncoder) -> Unit,
17-
dec: (WireDecoder) -> T?
18-
): T? {
19-
val buffer = Buffer()
20-
val encoder = WireEncoder(buffer)
21-
22-
msg.enc(encoder)
23-
encoder.flush()
24-
25-
return WireDecoder(buffer).use {
26-
dec(it)
27-
}
28-
}
29-
30-
31-
@Test
32-
fun testAllPrimitiveProto() {
33-
val msg = AllPrimitivesCommon {
34-
int32 = 12
35-
int64 = 1234567890123456789L
36-
uint32 = 12345u
37-
uint64 = 1234567890123456789uL
38-
sint32 = -12
39-
sint64 = -1234567890123456789L
40-
fixed32 = 12345u
41-
fixed64 = 1234567890123456789uL
42-
sfixed32 = -12345
43-
sfixed64 = -1234567890123456789L
44-
bool = true
45-
float = 1.0f
46-
double = 3.0
47-
string = "test"
48-
bytes = byteArrayOf(1, 2, 3)
49-
}
50-
51-
val decoded = decodeEncode(msg, { encodeWith(it) }, AllPrimitivesCommon::decodeWith)
52-
53-
assertEquals(msg.double, decoded?.double)
54-
}
55-
56-
@Test
57-
fun testRepeatedProto() {
58-
val msg = RepeatedCommon {
59-
listFixed32 = listOf(1, 2, 3).map { it.toUInt() }
60-
listInt32 = listOf(4, 5, 6)
61-
listString = listOf("a", "b", "c")
62-
}
63-
64-
val decoded = decodeEncode(msg, { encodeWith(it) }, RepeatedCommon::decodeWith)
65-
66-
assertEquals(msg.listInt32, decoded?.listInt32)
67-
assertEquals(msg.listFixed32, decoded?.listFixed32)
68-
assertEquals(msg.listString, decoded?.listString)
69-
}
70-
71-
}

0 commit comments

Comments
 (0)