From 3ac8fd02d0380cea9cbc67d68a8db9ddc08ac554 Mon Sep 17 00:00:00 2001 From: Stefana Dranca Date: Fri, 8 Mar 2024 13:59:33 +0000 Subject: [PATCH 1/3] Echo Metadata in TestService Motivation: We want to be able to test that the server receives metadata and can send both initial and trailing metadata. Modifications: - added extensions for server requests that extract the initial and trailing metadata that should be echoed - added the initial and trailing metadata n the server responses Result: The interop tests will test that the server sends metadata as initial and trailing. --- .../InteroperabilityTests/TestService.swift | 67 +++++++++++++++++-- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/Sources/InteroperabilityTests/TestService.swift b/Sources/InteroperabilityTests/TestService.swift index bb522fec5..5b3dc5168 100644 --- a/Sources/InteroperabilityTests/TestService.swift +++ b/Sources/InteroperabilityTests/TestService.swift @@ -32,7 +32,12 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { request: ServerRequest.Single ) async throws -> ServerResponse.Single { let message = Grpc_Testing_TestService.Method.EmptyCall.Output() - return ServerResponse.Single(message: message) + let (initialMetadata, trailingMetadata) = request.extractInitialAndTrailingMetadata() + return ServerResponse.Single( + message: message, + metadata: initialMetadata, + trailingMetadata: trailingMetadata + ) } /// Server implements `unaryCall` which immediately returns a `SimpleResponse` with a payload @@ -72,7 +77,13 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { } } - return ServerResponse.Single(message: responseMessage) + let (initialMetadata, trailingMetadata) = request.extractInitialAndTrailingMetadata() + + return ServerResponse.Single( + message: responseMessage, + metadata: initialMetadata, + trailingMetadata: trailingMetadata + ) } /// Server gets the default `SimpleRequest` proto as the request. The content of the request is @@ -102,7 +113,8 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { ) async throws -> ServerResponse.Stream { - return ServerResponse.Stream { writer in + let (initialMetadata, trailingMetadata) = request.extractInitialAndTrailingMetadata() + return ServerResponse.Stream(metadata: initialMetadata) { writer in for responseParameter in request.message.responseParameters { let response = Grpc_Testing_StreamingOutputCallResponse.with { response in response.payload = Grpc_Testing_Payload.with { payload in @@ -113,7 +125,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { // We convert the `intervalUs` value from microseconds to nanoseconds. try await Task.sleep(nanoseconds: UInt64(responseParameter.intervalUs) * 1000) } - return [:] + return trailingMetadata } } @@ -135,7 +147,12 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { $0.aggregatedPayloadSize = Int32(aggregatedPayloadSize) } - return ServerResponse.Single(message: responseMessage) + let (initialMetadata, trailingMetadata) = request.extractInitialAndTrailingMetadata() + return ServerResponse.Single( + message: responseMessage, + metadata: initialMetadata, + trailingMetadata: trailingMetadata + ) } /// Server implements `fullDuplexCall` by replying, in order, with one @@ -148,7 +165,8 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { ) async throws -> ServerResponse.Stream { - return ServerResponse.Stream { writer in + let (initialMetadata, trailingMetadata) = request.extractInitialAndTrailingMetadata() + return ServerResponse.Stream(metadata: initialMetadata) { writer in for try await message in request.messages { // If a request message has a responseStatus set, the server should return that status. // If the code is an error code, the server will throw an error containing that code @@ -174,7 +192,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { try await writer.write(response) } } - return [:] + return trailingMetadata } } @@ -189,3 +207,38 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { throw RPCError(code: .unimplemented, message: "The RPC is not implemented.") } } + +extension ServerRequest.Single { + fileprivate func extractInitialAndTrailingMetadata() -> (Metadata, Metadata) { + var initialMetadata = Metadata() + var trailingMetadata = Metadata() + + for value in self.metadata[stringValues: "x-grpc-test-echo-initia"] { + initialMetadata.addString(value, forKey: "x-grpc-test-echo-initia") + } + + for value in self.metadata[binaryValues: "x-grpc-test-echo-trailing-bin"] { + trailingMetadata.addBinary(value, forKey: "x-grpc-test-echo-trailing-bin") + } + + return (initialMetadata, trailingMetadata) + } +} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension ServerRequest.Stream { + fileprivate func extractInitialAndTrailingMetadata() -> (Metadata, Metadata) { + var initialMetadata = Metadata() + var trailingMetadata = Metadata() + + for value in self.metadata[stringValues: "x-grpc-test-echo-initia"] { + initialMetadata.addString(value, forKey: "x-grpc-test-echo-initia") + } + + for value in self.metadata[binaryValues: "x-grpc-test-echo-trailing-bin"] { + trailingMetadata.addBinary(value, forKey: "x-grpc-test-echo-trailing-bin") + } + + return (initialMetadata, trailingMetadata) + } +} From 15d157e17c5addecbdfecdea1b618741d15e8837 Mon Sep 17 00:00:00 2001 From: Stefana Dranca Date: Fri, 8 Mar 2024 14:07:16 +0000 Subject: [PATCH 2/3] fixed missing l --- Sources/InteroperabilityTests/TestService.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/InteroperabilityTests/TestService.swift b/Sources/InteroperabilityTests/TestService.swift index 5b3dc5168..3f0a85d8a 100644 --- a/Sources/InteroperabilityTests/TestService.swift +++ b/Sources/InteroperabilityTests/TestService.swift @@ -213,8 +213,8 @@ extension ServerRequest.Single { var initialMetadata = Metadata() var trailingMetadata = Metadata() - for value in self.metadata[stringValues: "x-grpc-test-echo-initia"] { - initialMetadata.addString(value, forKey: "x-grpc-test-echo-initia") + for value in self.metadata[stringValues: "x-grpc-test-echo-initial"] { + initialMetadata.addString(value, forKey: "x-grpc-test-echo-initial") } for value in self.metadata[binaryValues: "x-grpc-test-echo-trailing-bin"] { @@ -231,8 +231,8 @@ extension ServerRequest.Stream { var initialMetadata = Metadata() var trailingMetadata = Metadata() - for value in self.metadata[stringValues: "x-grpc-test-echo-initia"] { - initialMetadata.addString(value, forKey: "x-grpc-test-echo-initia") + for value in self.metadata[stringValues: "x-grpc-test-echo-initial"] { + initialMetadata.addString(value, forKey: "x-grpc-test-echo-initial") } for value in self.metadata[binaryValues: "x-grpc-test-echo-trailing-bin"] { From 6d208dc41adb0045d1a4e3f1cbe3881895a9de35 Mon Sep 17 00:00:00 2001 From: Stefana Dranca Date: Mon, 11 Mar 2024 10:36:44 +0000 Subject: [PATCH 3/3] added Metadata extension --- .../InteroperabilityTests/TestService.swift | 38 +++++-------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/Sources/InteroperabilityTests/TestService.swift b/Sources/InteroperabilityTests/TestService.swift index 3f0a85d8a..d20796c35 100644 --- a/Sources/InteroperabilityTests/TestService.swift +++ b/Sources/InteroperabilityTests/TestService.swift @@ -32,7 +32,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { request: ServerRequest.Single ) async throws -> ServerResponse.Single { let message = Grpc_Testing_TestService.Method.EmptyCall.Output() - let (initialMetadata, trailingMetadata) = request.extractInitialAndTrailingMetadata() + let (initialMetadata, trailingMetadata) = request.metadata.makeInitialAndTrailingMetadata() return ServerResponse.Single( message: message, metadata: initialMetadata, @@ -77,7 +77,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { } } - let (initialMetadata, trailingMetadata) = request.extractInitialAndTrailingMetadata() + let (initialMetadata, trailingMetadata) = request.metadata.makeInitialAndTrailingMetadata() return ServerResponse.Single( message: responseMessage, @@ -113,7 +113,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { ) async throws -> ServerResponse.Stream { - let (initialMetadata, trailingMetadata) = request.extractInitialAndTrailingMetadata() + let (initialMetadata, trailingMetadata) = request.metadata.makeInitialAndTrailingMetadata() return ServerResponse.Stream(metadata: initialMetadata) { writer in for responseParameter in request.message.responseParameters { let response = Grpc_Testing_StreamingOutputCallResponse.with { response in @@ -147,7 +147,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { $0.aggregatedPayloadSize = Int32(aggregatedPayloadSize) } - let (initialMetadata, trailingMetadata) = request.extractInitialAndTrailingMetadata() + let (initialMetadata, trailingMetadata) = request.metadata.makeInitialAndTrailingMetadata() return ServerResponse.Single( message: responseMessage, metadata: initialMetadata, @@ -165,7 +165,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { ) async throws -> ServerResponse.Stream { - let (initialMetadata, trailingMetadata) = request.extractInitialAndTrailingMetadata() + let (initialMetadata, trailingMetadata) = request.metadata.makeInitialAndTrailingMetadata() return ServerResponse.Stream(metadata: initialMetadata) { writer in for try await message in request.messages { // If a request message has a responseStatus set, the server should return that status. @@ -208,34 +208,14 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol { } } -extension ServerRequest.Single { - fileprivate func extractInitialAndTrailingMetadata() -> (Metadata, Metadata) { +extension Metadata { + fileprivate func makeInitialAndTrailingMetadata() -> (Metadata, Metadata) { var initialMetadata = Metadata() var trailingMetadata = Metadata() - - for value in self.metadata[stringValues: "x-grpc-test-echo-initial"] { + for value in self[stringValues: "x-grpc-test-echo-initial"] { initialMetadata.addString(value, forKey: "x-grpc-test-echo-initial") } - - for value in self.metadata[binaryValues: "x-grpc-test-echo-trailing-bin"] { - trailingMetadata.addBinary(value, forKey: "x-grpc-test-echo-trailing-bin") - } - - return (initialMetadata, trailingMetadata) - } -} - -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension ServerRequest.Stream { - fileprivate func extractInitialAndTrailingMetadata() -> (Metadata, Metadata) { - var initialMetadata = Metadata() - var trailingMetadata = Metadata() - - for value in self.metadata[stringValues: "x-grpc-test-echo-initial"] { - initialMetadata.addString(value, forKey: "x-grpc-test-echo-initial") - } - - for value in self.metadata[binaryValues: "x-grpc-test-echo-trailing-bin"] { + for value in self[binaryValues: "x-grpc-test-echo-trailing-bin"] { trailingMetadata.addBinary(value, forKey: "x-grpc-test-echo-trailing-bin") }