Explorar el Código

Add server executable for interop tests (#1897)

Gustavo Cairo hace 1 año
padre
commit
fd0f881842

+ 12 - 8
Package.swift

@@ -335,13 +335,6 @@ extension Target {
     ]
   )
 
-  static let grpcHTTP2TransportNIOPosixTests: Target = .testTarget(
-    name: "GRPCHTTP2TransportNIOPosixTests",
-    dependencies: [
-      .grpcHTTP2TransportNIOPosix
-    ]
-  )
-
   static let grpcHTTP2TransportNIOTransportServicesTests: Target = .testTarget(
     name: "GRPCHTTP2TransportNIOTransportServicesTests",
     dependencies: [
@@ -410,6 +403,17 @@ extension Target {
     ]
   )
 
+  static let interoperabilityTestsExecutable: Target = .executableTarget(
+    name: "interoperability-tests",
+    dependencies: [
+      .grpcCore,
+      .grpcHTTP2Core,
+      .grpcHTTP2TransportNIOPosix,
+      .interoperabilityTests,
+      .argumentParser
+    ]
+  )
+
   static let interopTestImplementation: Target = .target(
     name: "GRPCInteroperabilityTestsImplementation",
     dependencies: [
@@ -736,6 +740,7 @@ let package = Package(
     .grpcProtobuf,
     .grpcProtobufCodeGen,
     .interoperabilityTestImplementation,
+    .interoperabilityTestsExecutable,
     .performanceWorker,
 
     // v2 tests
@@ -744,7 +749,6 @@ let package = Package(
     .grpcCodeGenTests,
     .grpcInterceptorsTests,
     .grpcHTTP2CoreTests,
-    .grpcHTTP2TransportNIOPosixTests,
     .grpcHTTP2TransportNIOTransportServicesTests,
     .grpcProtobufTests,
     .grpcProtobufCodeGenTests,

+ 11 - 9
Sources/InteroperabilityTests/TestService.swift

@@ -18,8 +18,10 @@ import Foundation
 import GRPCCore
 
 @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
-internal struct TestService: Grpc_Testing_TestService.ServiceProtocol {
-  internal func unimplementedCall(
+public struct TestService: Grpc_Testing_TestService.ServiceProtocol {
+  public init() {}
+
+  public func unimplementedCall(
     request: ServerRequest.Single<Grpc_Testing_TestService.Method.UnimplementedCall.Input>
   ) async throws
     -> ServerResponse.Single<Grpc_Testing_TestService.Method.UnimplementedCall.Output>
@@ -28,7 +30,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol {
   }
 
   /// Server implements `emptyCall` which immediately returns the empty message.
-  internal func emptyCall(
+  public func emptyCall(
     request: ServerRequest.Single<Grpc_Testing_TestService.Method.EmptyCall.Input>
   ) async throws -> ServerResponse.Single<Grpc_Testing_TestService.Method.EmptyCall.Output> {
     let message = Grpc_Testing_TestService.Method.EmptyCall.Output()
@@ -46,7 +48,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol {
   ///
   /// If the server does not support the `responseType`, then it should fail the RPC with
   /// `INVALID_ARGUMENT`.
-  internal func unaryCall(
+  public func unaryCall(
     request: ServerRequest.Single<Grpc_Testing_TestService.Method.UnaryCall.Input>
   ) async throws -> ServerResponse.Single<Grpc_Testing_TestService.Method.UnaryCall.Output> {
     // If the request has a responseStatus set, the server should return that status.
@@ -93,7 +95,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol {
   /// long as the response payload is different for each request. In addition it adds cache control
   /// headers such that the response can be cached by proxies in the response path. Server should
   /// be behind a caching proxy for this test to pass. Currently we set the max-age to 60 seconds.
-  internal func cacheableUnaryCall(
+  public func cacheableUnaryCall(
     request: ServerRequest.Single<Grpc_Testing_TestService.Method.CacheableUnaryCall.Input>
   ) async throws
     -> ServerResponse.Single<Grpc_Testing_TestService.Method.CacheableUnaryCall.Output>
@@ -106,7 +108,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol {
   /// Each `StreamingOutputCallResponse` should have a payload body of size `ResponseParameter.size`
   /// bytes, as specified by its respective `ResponseParameter`. After sending all responses, it
   /// closes with OK.
-  internal func streamingOutputCall(
+  public func streamingOutputCall(
     request: ServerRequest.Single<
       Grpc_Testing_TestService.Method.StreamingOutputCall.Input
     >
@@ -132,7 +134,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol {
   /// Server implements `streamingInputCall` which upon half close immediately returns a
   /// `StreamingInputCallResponse` where `aggregatedPayloadSize` is the sum of all request payload
   /// bodies received.
-  internal func streamingInputCall(
+  public func streamingInputCall(
     request: ServerRequest.Stream<Grpc_Testing_TestService.Method.StreamingInputCall.Input>
   ) async throws
     -> ServerResponse.Single<Grpc_Testing_TestService.Method.StreamingInputCall.Output>
@@ -160,7 +162,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol {
   /// `StreamingOutputCallRequest`. Each `StreamingOutputCallResponse` should have a payload body
   /// of size `ResponseParameter.size` bytes, as specified by its respective `ResponseParameter`s.
   /// After receiving half close and sending all responses, it closes with OK.
-  internal func fullDuplexCall(
+  public func fullDuplexCall(
     request: ServerRequest.Stream<Grpc_Testing_TestService.Method.FullDuplexCall.Input>
   ) async throws
     -> ServerResponse.Stream<Grpc_Testing_TestService.Method.FullDuplexCall.Output>
@@ -199,7 +201,7 @@ internal struct TestService: Grpc_Testing_TestService.ServiceProtocol {
   /// This is not implemented as it is not described in the specification.
   ///
   /// See: https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md
-  internal func halfDuplexCall(
+  public func halfDuplexCall(
     request: ServerRequest.Stream<Grpc_Testing_TestService.Method.HalfDuplexCall.Input>
   ) async throws
     -> ServerResponse.Stream<Grpc_Testing_TestService.Method.HalfDuplexCall.Output>

+ 63 - 0
Sources/interoperability-tests/InteroperabilityTestsExecutable.swift

@@ -0,0 +1,63 @@
+/*
+ * Copyright 2024, gRPC Authors All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import ArgumentParser
+import GRPCCore
+import GRPCHTTP2Core
+import GRPCHTTP2TransportNIOPosix
+import InteroperabilityTests
+import NIOPosix
+
+@main
+@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
+struct InteroperabilityTestsExecutable: AsyncParsableCommand {
+  static var configuration = CommandConfiguration(
+    abstract: "gRPC Swift Interoperability Runner",
+    subcommands: [StartServer.self, ListTests.self]
+  )
+
+  struct StartServer: AsyncParsableCommand {
+    static var configuration = CommandConfiguration(
+      abstract: "Start the gRPC Swift interoperability test server."
+    )
+
+    @Option(help: "The port to listen on for new connections")
+    var port: Int
+
+    func run() async throws {
+      var transportConfig = HTTP2ServerTransport.Posix.Config.defaults
+      transportConfig.compression.enabledAlgorithms = .all
+      let transport = HTTP2ServerTransport.Posix(
+        address: .ipv4(host: "0.0.0.0", port: self.port),
+        config: transportConfig
+      )
+      let server = GRPCServer(transport: transport, services: [TestService()])
+      try await server.run()
+    }
+  }
+
+  struct ListTests: ParsableCommand {
+    static var configuration = CommandConfiguration(
+      abstract: "List all interoperability test names."
+    )
+
+    func run() throws {
+      for testCase in InteroperabilityTestCase.allCases {
+        print(testCase.name)
+      }
+    }
+  }
+}

+ 1 - 2
Tests/InProcessInteroperabilityTests/InProcessInteroperabilityTests.swift

@@ -16,10 +16,9 @@
 
 import GRPCCore
 import GRPCInProcessTransport
+import InteroperabilityTests
 import XCTest
 
-@testable import InteroperabilityTests
-
 @available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
 final class InProcessInteroperabilityTests: XCTestCase {
   func runInProcessTransport(