ReflectionServiceIntegrationTests.swift 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * Copyright 2023, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import Foundation
  17. import GRPC
  18. import GRPCReflectionService
  19. import NIOPosix
  20. import SwiftProtobuf
  21. import XCTest
  22. @testable import GRPCReflectionService
  23. final class ReflectionServiceIntegrationTests: GRPCTestCase {
  24. private var server: Server?
  25. private var channel: GRPCChannel?
  26. private let protos: [Google_Protobuf_FileDescriptorProto] = makeProtosWithDependencies()
  27. private let independentProto: Google_Protobuf_FileDescriptorProto = generateFileDescriptorProto(
  28. fileName: "independentBar",
  29. suffix: 5
  30. )
  31. private func setUpServerAndChannel() throws {
  32. let reflectionServiceProvider = try ReflectionService(
  33. fileDescriptors: self.protos + [self.independentProto]
  34. )
  35. let server = try Server.insecure(group: MultiThreadedEventLoopGroup.singleton)
  36. .withServiceProviders([reflectionServiceProvider])
  37. .withLogger(self.serverLogger)
  38. .bind(host: "127.0.0.1", port: 0)
  39. .wait()
  40. self.server = server
  41. let channel = try GRPCChannelPool.with(
  42. target: .hostAndPort("127.0.0.1", server.channel.localAddress!.port!),
  43. transportSecurity: .plaintext,
  44. eventLoopGroup: MultiThreadedEventLoopGroup.singleton
  45. ) {
  46. $0.backgroundActivityLogger = self.clientLogger
  47. }
  48. self.channel = channel
  49. }
  50. override func tearDown() {
  51. if let channel = self.channel {
  52. XCTAssertNoThrow(try channel.close().wait())
  53. }
  54. if let server = self.server {
  55. XCTAssertNoThrow(try server.close().wait())
  56. }
  57. super.tearDown()
  58. }
  59. func testFileByFileName() async throws {
  60. try self.setUpServerAndChannel()
  61. let client = Reflection_ServerReflectionAsyncClient(channel: self.channel!)
  62. let serviceReflectionInfo = client.makeServerReflectionInfoCall()
  63. try await serviceReflectionInfo.requestStream.send(
  64. .with {
  65. $0.host = "127.0.0.1"
  66. $0.fileByFilename = "bar1.proto"
  67. }
  68. )
  69. serviceReflectionInfo.requestStream.finish()
  70. var iterator = serviceReflectionInfo.responseStream.makeAsyncIterator()
  71. guard let message = try await iterator.next() else {
  72. return XCTFail("Could not get a response message.")
  73. }
  74. let receivedFileDescriptorProto =
  75. try Google_Protobuf_FileDescriptorProto(
  76. serializedData: (message.fileDescriptorResponse
  77. .fileDescriptorProto[0])
  78. )
  79. XCTAssertEqual(receivedFileDescriptorProto.name, "bar1.proto")
  80. XCTAssertEqual(receivedFileDescriptorProto.service.count, 1)
  81. guard let service = receivedFileDescriptorProto.service.first else {
  82. return XCTFail("The received file descriptor proto doesn't have any services.")
  83. }
  84. guard let method = service.method.first else {
  85. return XCTFail("The service of the received file descriptor proto doesn't have any methods.")
  86. }
  87. XCTAssertEqual(method.name, "testMethod1")
  88. XCTAssertEqual(message.fileDescriptorResponse.fileDescriptorProto.count, 4)
  89. }
  90. func testListServices() async throws {
  91. try self.setUpServerAndChannel()
  92. let client = Reflection_ServerReflectionAsyncClient(channel: self.channel!)
  93. let serviceReflectionInfo = client.makeServerReflectionInfoCall()
  94. try await serviceReflectionInfo.requestStream.send(
  95. .with {
  96. $0.host = "127.0.0.1"
  97. $0.listServices = "services"
  98. }
  99. )
  100. serviceReflectionInfo.requestStream.finish()
  101. var iterator = serviceReflectionInfo.responseStream.makeAsyncIterator()
  102. guard let message = try await iterator.next() else {
  103. return XCTFail("Could not get a response message.")
  104. }
  105. let receivedServices = message.listServicesResponse.service.map { $0.name }.sorted()
  106. let servicesNames = (self.protos + [self.independentProto]).serviceNames.sorted()
  107. XCTAssertEqual(receivedServices, servicesNames)
  108. }
  109. func testFileBySymbol() async throws {
  110. try self.setUpServerAndChannel()
  111. let client = Reflection_ServerReflectionAsyncClient(channel: self.channel!)
  112. let serviceReflectionInfo = client.makeServerReflectionInfoCall()
  113. try await serviceReflectionInfo.requestStream.send(
  114. .with {
  115. $0.host = "127.0.0.1"
  116. $0.fileContainingSymbol = "packagebar1.enumType1"
  117. }
  118. )
  119. serviceReflectionInfo.requestStream.finish()
  120. var iterator = serviceReflectionInfo.responseStream.makeAsyncIterator()
  121. guard let message = try await iterator.next() else {
  122. return XCTFail("Could not get a response message.")
  123. }
  124. let receivedData: [Google_Protobuf_FileDescriptorProto]
  125. do {
  126. receivedData = try message.fileDescriptorResponse.fileDescriptorProto.map {
  127. try Google_Protobuf_FileDescriptorProto(serializedData: $0)
  128. }
  129. } catch {
  130. return XCTFail("Could not serialize data received as a message.")
  131. }
  132. let fileToFind = self.protos[0]
  133. let dependentProtos = self.protos[1...]
  134. for fileDescriptorProto in receivedData {
  135. if fileDescriptorProto == fileToFind {
  136. XCTAssert(
  137. fileDescriptorProto.enumType.names.contains("enumType1"),
  138. """
  139. The response doesn't contain the serialized file descriptor proto \
  140. containing the \"packagebar1.enumType1\" symbol.
  141. """
  142. )
  143. } else {
  144. XCTAssert(
  145. dependentProtos.contains(fileDescriptorProto),
  146. """
  147. The \(fileDescriptorProto.name) is not a dependency of the \
  148. proto file containing the \"packagebar1.enumType1\" symbol.
  149. """
  150. )
  151. }
  152. }
  153. }
  154. }