ClientResponseTests.swift 6.1 KB

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