1+ /*
2+ * Copyright 2023-2026 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.test.integration
6+
7+ import kotlinx.rpc.RpcServer
8+ import kotlinx.rpc.grpc.annotations.Grpc
9+ import kotlinx.rpc.grpc.codec.codec
10+ import kotlinx.rpc.grpc.test.AllPrimitives
11+ import kotlinx.rpc.grpc.test.Enum
12+ import kotlinx.rpc.grpc.test.UnknownFieldsAll
13+ import kotlinx.rpc.grpc.test.UnknownFieldsSubset
14+ import kotlinx.rpc.grpc.test.asInternal
15+ import kotlinx.rpc.grpc.test.invoke
16+ import kotlinx.rpc.grpc.test.presence
17+ import kotlinx.rpc.protobuf.ProtobufConfig
18+ import kotlinx.rpc.registerService
19+ import kotlinx.rpc.withService
20+ import kotlin.test.Test
21+ import kotlin.test.assertEquals
22+ import kotlin.test.assertFalse
23+ import kotlin.test.assertNull
24+ import kotlin.test.assertTrue
25+
26+
27+ @Grpc(protoServiceName = " Service" )
28+ private interface ClientTestService {
29+ suspend fun serverTest (message : UnknownFieldsAll ): UnknownFieldsAll
30+ suspend fun clientTest (message : UnknownFieldsAll ): UnknownFieldsSubset
31+ }
32+
33+ @Grpc(protoServiceName = " Service" )
34+ private interface ServerTestService {
35+ suspend fun serverTest (message : UnknownFieldsSubset ): UnknownFieldsSubset
36+ suspend fun clientTest (message : UnknownFieldsAll ): UnknownFieldsAll
37+ }
38+
39+ private object ServerServiceImpl : ServerTestService {
40+ override suspend fun serverTest (message : UnknownFieldsSubset ): UnknownFieldsSubset = message
41+ override suspend fun clientTest (message : UnknownFieldsAll ): UnknownFieldsAll = message
42+ }
43+
44+ class GrpcCodecConfigTest : GrpcTestBase () {
45+
46+ override fun RpcServer.registerServices () {
47+ registerService<ServerTestService > { ServerServiceImpl }
48+ }
49+
50+ private val unknownFieldsAllMessage = UnknownFieldsAll {
51+ field1 = 123
52+ intMissing = 456
53+ allPrimitivesMissing = AllPrimitives {
54+ int32 = 7
55+ }
56+ enumMissing = Enum .ONE
57+ testOneof = UnknownFieldsAll .TestOneof .OneofString (" oneof value" )
58+ }
59+
60+
61+ @Test
62+ fun `test protobuf discardUnknownFields codec config in server config` () = runGrpcTest(
63+ serverConfiguration = { codecConfig = ProtobufConfig (discardUnknownFields = true ) }
64+ ) { client ->
65+ val service = client.withService<ClientTestService >()
66+ val message = unknownFieldsAllMessage
67+ val response = service.serverTest(message)
68+
69+ // the server should have discarded unknown fields
70+ response.run {
71+ assertEquals(message.field1, field1)
72+ assertFalse(response.presence.hasIntMissing)
73+ assertFalse(response.presence.hasAllPrimitivesMissing)
74+ assertFalse(response.presence.hasEnumMissing)
75+ assertNull(response.testOneof)
76+ }
77+ }
78+
79+ @Test
80+ fun `test unknown fields presents by default - server` () = runGrpcTest { client ->
81+ val service = client.withService<ClientTestService >()
82+ val message = unknownFieldsAllMessage
83+ val response = service.serverTest(message)
84+
85+ // the server should have preserved unknown fields
86+ assertEquals(message, response)
87+ }
88+
89+ @Test
90+ fun `test protobuf discardUnknownFields codec config in client config` () = runGrpcTest(
91+ clientConfiguration = { codecConfig = ProtobufConfig (discardUnknownFields = true ) }
92+ ) { client ->
93+ val service = client.withService<ClientTestService >()
94+ val message = unknownFieldsAllMessage
95+ val response = service.clientTest(message)
96+
97+ // the client should have discarded unknown fields
98+ assertEquals(0 , response.asInternal()._unknownFields .size)
99+ }
100+
101+
102+ @Test
103+ fun `test unknown fields presents by default - client` () = runGrpcTest { client ->
104+ val service = client.withService<ClientTestService >()
105+ val message = unknownFieldsAllMessage
106+ val response = service.clientTest(message)
107+
108+ // the server should have preserved unknown fields
109+ assertTrue(response.asInternal()._unknownFields .size > 0 )
110+
111+ // encode and decode as UnknownFieldsAll
112+ val codec = codec<UnknownFieldsAll >()
113+ val decoded = codec.decode(codec.encode(message))
114+ // should have preserved all fields
115+ assertEquals(message, decoded)
116+ }
117+
118+
119+ }
0 commit comments