UnaryServerHandlerTests.swift 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. * Copyright 2021, 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. @testable import GRPC
  17. import NIO
  18. import NIOHPACK
  19. import XCTest
  20. final class ResponseRecorder: GRPCServerResponseWriter {
  21. var metadata: HPACKHeaders?
  22. var messages: [ByteBuffer] = []
  23. var status: GRPCStatus?
  24. var trailers: HPACKHeaders?
  25. func sendMetadata(_ metadata: HPACKHeaders, promise: EventLoopPromise<Void>?) {
  26. XCTAssertNil(self.metadata)
  27. self.metadata = metadata
  28. promise?.succeed(())
  29. }
  30. func sendMessage(
  31. _ bytes: ByteBuffer,
  32. metadata: MessageMetadata,
  33. promise: EventLoopPromise<Void>?
  34. ) {
  35. self.messages.append(bytes)
  36. promise?.succeed(())
  37. }
  38. func sendEnd(status: GRPCStatus, trailers: HPACKHeaders, promise: EventLoopPromise<Void>?) {
  39. XCTAssertNil(self.status)
  40. XCTAssertNil(self.trailers)
  41. self.status = status
  42. self.trailers = trailers
  43. promise?.succeed(())
  44. }
  45. }
  46. class UnaryServerHandlerTests: GRPCTestCase {
  47. let eventLoop = EmbeddedEventLoop()
  48. let allocator = ByteBufferAllocator()
  49. private func makeCallHandlerContext(writer: GRPCServerResponseWriter) -> CallHandlerContext {
  50. return CallHandlerContext(
  51. errorDelegate: nil,
  52. logger: self.logger,
  53. encoding: .disabled,
  54. eventLoop: self.eventLoop,
  55. path: "/ignored",
  56. remoteAddress: nil,
  57. responseWriter: writer,
  58. allocator: self.allocator
  59. )
  60. }
  61. private func makeHandler(
  62. writer: GRPCServerResponseWriter,
  63. function: @escaping (String, StatusOnlyCallContext) -> EventLoopFuture<String>
  64. ) -> UnaryServerHandler<StringSerializer, StringDeserializer> {
  65. return UnaryServerHandler(
  66. context: self.makeCallHandlerContext(writer: writer),
  67. requestDeserializer: StringDeserializer(),
  68. responseSerializer: StringSerializer(),
  69. interceptors: [],
  70. userFunction: function
  71. )
  72. }
  73. private func echo(_ request: String, context: StatusOnlyCallContext) -> EventLoopFuture<String> {
  74. return context.eventLoop.makeSucceededFuture(request)
  75. }
  76. private func neverComplete(
  77. _ request: String,
  78. context: StatusOnlyCallContext
  79. ) -> EventLoopFuture<String> {
  80. let scheduled = context.eventLoop.scheduleTask(deadline: .distantFuture) {
  81. return request
  82. }
  83. return scheduled.futureResult
  84. }
  85. private func neverCalled(
  86. _ request: String,
  87. context: StatusOnlyCallContext
  88. ) -> EventLoopFuture<String> {
  89. XCTFail("Unexpected function invocation")
  90. return context.eventLoop.makeFailedFuture(GRPCError.InvalidState(""))
  91. }
  92. func testHappyPath() {
  93. let recorder = ResponseRecorder()
  94. let handler = self.makeHandler(writer: recorder, function: self.echo(_:context:))
  95. handler.receiveMetadata([:])
  96. assertThat(recorder.metadata, .is([:]))
  97. let buffer = ByteBuffer(string: "hello")
  98. handler.receiveMessage(buffer)
  99. handler.receiveEnd()
  100. handler.finish()
  101. assertThat(recorder.messages.first, .is(buffer))
  102. assertThat(recorder.status, .notNil(.hasCode(.ok)))
  103. assertThat(recorder.trailers, .is([:]))
  104. }
  105. func testThrowingDeserializer() {
  106. let recorder = ResponseRecorder()
  107. let handler = UnaryServerHandler(
  108. context: self.makeCallHandlerContext(writer: recorder),
  109. requestDeserializer: ThrowingStringDeserializer(),
  110. responseSerializer: StringSerializer(),
  111. interceptors: [],
  112. userFunction: self.neverCalled(_:context:)
  113. )
  114. handler.receiveMetadata([:])
  115. assertThat(recorder.metadata, .is([:]))
  116. let buffer = ByteBuffer(string: "hello")
  117. handler.receiveMessage(buffer)
  118. assertThat(recorder.messages, .isEmpty())
  119. assertThat(recorder.status, .notNil(.hasCode(.internalError)))
  120. }
  121. func testThrowingSerializer() {
  122. let recorder = ResponseRecorder()
  123. let handler = UnaryServerHandler(
  124. context: self.makeCallHandlerContext(writer: recorder),
  125. requestDeserializer: StringDeserializer(),
  126. responseSerializer: ThrowingStringSerializer(),
  127. interceptors: [],
  128. userFunction: self.echo(_:context:)
  129. )
  130. handler.receiveMetadata([:])
  131. assertThat(recorder.metadata, .is([:]))
  132. let buffer = ByteBuffer(string: "hello")
  133. handler.receiveMessage(buffer)
  134. handler.receiveEnd()
  135. assertThat(recorder.messages, .isEmpty())
  136. assertThat(recorder.status, .notNil(.hasCode(.internalError)))
  137. }
  138. func testUserFunctionReturnsFailedFuture() {
  139. let recorder = ResponseRecorder()
  140. let handler = self.makeHandler(writer: recorder) { _, context in
  141. return context.eventLoop.makeFailedFuture(GRPCStatus(code: .unavailable, message: ":("))
  142. }
  143. handler.receiveMetadata([:])
  144. assertThat(recorder.metadata, .is([:]))
  145. let buffer = ByteBuffer(string: "hello")
  146. handler.receiveMessage(buffer)
  147. assertThat(recorder.messages, .isEmpty())
  148. assertThat(recorder.status, .notNil(.hasCode(.unavailable)))
  149. assertThat(recorder.status?.message, .is(":("))
  150. }
  151. func testReceiveMessageBeforeHeaders() {
  152. let recorder = ResponseRecorder()
  153. let handler = self.makeHandler(writer: recorder, function: self.neverCalled(_:context:))
  154. handler.receiveMessage(ByteBuffer(string: "foo"))
  155. assertThat(recorder.metadata, .is(.nil()))
  156. assertThat(recorder.messages, .isEmpty())
  157. assertThat(recorder.status, .notNil(.hasCode(.internalError)))
  158. }
  159. func testReceiveMultipleHeaders() {
  160. let recorder = ResponseRecorder()
  161. let handler = self.makeHandler(writer: recorder, function: self.neverCalled(_:context:))
  162. handler.receiveMetadata([:])
  163. assertThat(recorder.metadata, .is([:]))
  164. handler.receiveMetadata([:])
  165. assertThat(recorder.messages, .isEmpty())
  166. assertThat(recorder.status, .notNil(.hasCode(.internalError)))
  167. }
  168. func testReceiveMultipleMessages() {
  169. let recorder = ResponseRecorder()
  170. let handler = self.makeHandler(writer: recorder, function: self.neverComplete(_:context:))
  171. handler.receiveMetadata([:])
  172. assertThat(recorder.metadata, .is([:]))
  173. let buffer = ByteBuffer(string: "hello")
  174. handler.receiveMessage(buffer)
  175. handler.receiveEnd()
  176. // Send another message before the function completes.
  177. handler.receiveMessage(buffer)
  178. assertThat(recorder.messages, .isEmpty())
  179. assertThat(recorder.status, .notNil(.hasCode(.internalError)))
  180. }
  181. func testFinishBeforeStarting() {
  182. let recorder = ResponseRecorder()
  183. let handler = self.makeHandler(writer: recorder, function: self.neverCalled(_:context:))
  184. handler.finish()
  185. assertThat(recorder.metadata, .is(.nil()))
  186. assertThat(recorder.messages, .isEmpty())
  187. assertThat(recorder.status, .is(.nil()))
  188. assertThat(recorder.trailers, .is(.nil()))
  189. }
  190. func testFinishAfterHeaders() {
  191. let recorder = ResponseRecorder()
  192. let handler = self.makeHandler(writer: recorder, function: self.neverCalled(_:context:))
  193. handler.receiveMetadata([:])
  194. assertThat(recorder.metadata, .is([:]))
  195. handler.finish()
  196. assertThat(recorder.messages, .isEmpty())
  197. assertThat(recorder.status, .notNil(.hasCode(.unavailable)))
  198. assertThat(recorder.trailers, .is([:]))
  199. }
  200. func testFinishAfterMessage() {
  201. let recorder = ResponseRecorder()
  202. let handler = self.makeHandler(writer: recorder, function: self.neverComplete(_:context:))
  203. handler.receiveMetadata([:])
  204. handler.receiveMessage(ByteBuffer(string: "hello"))
  205. handler.finish()
  206. assertThat(recorder.messages, .isEmpty())
  207. assertThat(recorder.status, .notNil(.hasCode(.unavailable)))
  208. assertThat(recorder.trailers, .is([:]))
  209. }
  210. }