ClientResponseTests.swift 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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 XCTest
  17. @testable import GRPCCore
  18. @available(gRPCSwift 2.0, *)
  19. final class ClientResponseTests: XCTestCase {
  20. func testAcceptedSingleResponseConvenienceMethods() {
  21. let response = ClientResponse(
  22. message: "message",
  23. metadata: ["foo": "bar"],
  24. trailingMetadata: ["bar": "baz"]
  25. )
  26. XCTAssertEqual(response.metadata, ["foo": "bar"])
  27. XCTAssertEqual(try response.message, "message")
  28. XCTAssertEqual(response.trailingMetadata, ["bar": "baz"])
  29. }
  30. func testRejectedSingleResponseConvenienceMethods() {
  31. let error = RPCError(code: .aborted, message: "error message", metadata: ["bar": "baz"])
  32. let response = ClientResponse(of: String.self, error: error)
  33. XCTAssertEqual(response.metadata, [:])
  34. XCTAssertThrowsRPCError(try response.message) {
  35. XCTAssertEqual($0, error)
  36. }
  37. XCTAssertEqual(response.trailingMetadata, ["bar": "baz"])
  38. }
  39. func testAcceptedButFailedSingleResponseConvenienceMethods() {
  40. let error = RPCError(code: .aborted, message: "error message", metadata: ["bar": "baz"])
  41. let response = ClientResponse(of: String.self, metadata: ["foo": "bar"], error: error)
  42. XCTAssertEqual(response.metadata, ["foo": "bar"])
  43. XCTAssertThrowsRPCError(try response.message) {
  44. XCTAssertEqual($0, error)
  45. }
  46. XCTAssertEqual(response.trailingMetadata, ["bar": "baz"])
  47. }
  48. func testAcceptedStreamResponseConvenienceMethods_Messages() async throws {
  49. let response = StreamingClientResponse(
  50. of: String.self,
  51. metadata: ["foo": "bar"],
  52. bodyParts: RPCAsyncSequence(
  53. wrapping: AsyncThrowingStream {
  54. $0.yield(.message("foo"))
  55. $0.yield(.message("bar"))
  56. $0.yield(.message("baz"))
  57. $0.yield(.trailingMetadata(["baz": "baz"]))
  58. $0.finish()
  59. }
  60. )
  61. )
  62. XCTAssertEqual(response.metadata, ["foo": "bar"])
  63. let messages = try await response.messages.collect()
  64. XCTAssertEqual(messages, ["foo", "bar", "baz"])
  65. }
  66. func testAcceptedStreamResponseConvenienceMethods_BodyParts() async throws {
  67. let response = StreamingClientResponse(
  68. of: String.self,
  69. metadata: ["foo": "bar"],
  70. bodyParts: RPCAsyncSequence(
  71. wrapping: AsyncThrowingStream {
  72. $0.yield(.message("foo"))
  73. $0.yield(.message("bar"))
  74. $0.yield(.message("baz"))
  75. $0.yield(.trailingMetadata(["baz": "baz"]))
  76. $0.finish()
  77. }
  78. )
  79. )
  80. XCTAssertEqual(response.metadata, ["foo": "bar"])
  81. let bodyParts = try await response.bodyParts.collect()
  82. XCTAssertEqual(
  83. bodyParts,
  84. [.message("foo"), .message("bar"), .message("baz"), .trailingMetadata(["baz": "baz"])]
  85. )
  86. }
  87. func testRejectedStreamResponseConvenienceMethods() async throws {
  88. let error = RPCError(code: .aborted, message: "error message", metadata: ["bar": "baz"])
  89. let response = StreamingClientResponse(of: String.self, error: error)
  90. XCTAssertEqual(response.metadata, [:])
  91. await XCTAssertThrowsRPCErrorAsync {
  92. try await response.messages.collect()
  93. } errorHandler: {
  94. XCTAssertEqual($0, error)
  95. }
  96. await XCTAssertThrowsRPCErrorAsync {
  97. try await response.bodyParts.collect()
  98. } errorHandler: {
  99. XCTAssertEqual($0, error)
  100. }
  101. }
  102. func testStreamToSingleConversionForValidStream() async throws {
  103. let stream = StreamingClientResponse(
  104. of: String.self,
  105. metadata: ["foo": "bar"],
  106. bodyParts: .elements(.message("foo"), .trailingMetadata(["bar": "baz"]))
  107. )
  108. let single = await ClientResponse(stream: stream)
  109. XCTAssertEqual(single.metadata, ["foo": "bar"])
  110. XCTAssertEqual(try single.message, "foo")
  111. XCTAssertEqual(single.trailingMetadata, ["bar": "baz"])
  112. }
  113. func testStreamToSingleConversionForFailedStream() async throws {
  114. let error = RPCError(code: .aborted, message: "aborted", metadata: ["bar": "baz"])
  115. let stream = StreamingClientResponse(of: String.self, error: error)
  116. let single = await ClientResponse(stream: stream)
  117. XCTAssertEqual(single.metadata, [:])
  118. XCTAssertThrowsRPCError(try single.message) {
  119. XCTAssertEqual($0, error)
  120. }
  121. XCTAssertEqual(single.trailingMetadata, ["bar": "baz"])
  122. }
  123. func testStreamToSingleConversionForInvalidSingleStream() async throws {
  124. let bodies: [[StreamingClientResponse<String>.Contents.BodyPart]] = [
  125. [.message("1"), .message("2")], // Too many messages.
  126. [.trailingMetadata([:])], // Too few messages
  127. ]
  128. for body in bodies {
  129. let stream = StreamingClientResponse(
  130. of: String.self,
  131. metadata: ["foo": "bar"],
  132. bodyParts: .elements(body)
  133. )
  134. let single = await ClientResponse(stream: stream)
  135. XCTAssertEqual(single.metadata, [:])
  136. XCTAssertThrowsRPCError(try single.message) { error in
  137. XCTAssertEqual(error.code, .unimplemented)
  138. }
  139. XCTAssertEqual(single.trailingMetadata, [:])
  140. }
  141. }
  142. func testStreamToSingleConversionForInvalidStream() async throws {
  143. let bodies: [[StreamingClientResponse<String>.Contents.BodyPart]] = [
  144. [], // Empty stream
  145. [.trailingMetadata([:]), .trailingMetadata([:])], // Multiple metadatas
  146. [.trailingMetadata([:]), .message("")], // Metadata then message
  147. ]
  148. for body in bodies {
  149. let stream = StreamingClientResponse(
  150. of: String.self,
  151. metadata: ["foo": "bar"],
  152. bodyParts: .elements(body)
  153. )
  154. let single = await ClientResponse(stream: stream)
  155. XCTAssertEqual(single.metadata, [:])
  156. XCTAssertThrowsRPCError(try single.message) { error in
  157. XCTAssertEqual(error.code, .internalError)
  158. }
  159. XCTAssertEqual(single.trailingMetadata, [:])
  160. }
  161. }
  162. func testStreamToSingleConversionForStreamThrowingRPCError() async throws {
  163. let error = RPCError(code: .dataLoss, message: "oops")
  164. let stream = StreamingClientResponse(
  165. of: String.self,
  166. metadata: [:],
  167. bodyParts: .throwing(error)
  168. )
  169. let single = await ClientResponse(stream: stream)
  170. XCTAssertThrowsRPCError(try single.message) {
  171. XCTAssertEqual($0, error)
  172. }
  173. }
  174. func testStreamToSingleConversionForStreamThrowingUnknownError() async throws {
  175. let stream = StreamingClientResponse(
  176. of: String.self,
  177. metadata: [:],
  178. bodyParts: .throwing(CancellationError())
  179. )
  180. let single = await ClientResponse(stream: stream)
  181. XCTAssertThrowsRPCError(try single.message) { error in
  182. XCTAssertEqual(error.code, .unknown)
  183. }
  184. }
  185. }