ClientResponseTests.swift 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  19. final class ClientResponseTests: XCTestCase {
  20. func testAcceptedSingleResponseConvenienceMethods() {
  21. let response = ClientResponse.Single(
  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.Single(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.Single(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() async throws {
  49. let response = ClientResponse.Stream(
  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 testRejectedStreamResponseConvenienceMethods() async throws {
  67. let error = RPCError(code: .aborted, message: "error message", metadata: ["bar": "baz"])
  68. let response = ClientResponse.Stream(of: String.self, error: error)
  69. XCTAssertEqual(response.metadata, [:])
  70. await XCTAssertThrowsRPCErrorAsync {
  71. try await response.messages.collect()
  72. } errorHandler: {
  73. XCTAssertEqual($0, error)
  74. }
  75. }
  76. func testStreamToSingleConversionForValidStream() async throws {
  77. let stream = ClientResponse.Stream(
  78. of: String.self,
  79. metadata: ["foo": "bar"],
  80. bodyParts: .elements(.message("foo"), .trailingMetadata(["bar": "baz"]))
  81. )
  82. let single = await ClientResponse.Single(stream: stream)
  83. XCTAssertEqual(single.metadata, ["foo": "bar"])
  84. XCTAssertEqual(try single.message, "foo")
  85. XCTAssertEqual(single.trailingMetadata, ["bar": "baz"])
  86. }
  87. func testStreamToSingleConversionForFailedStream() async throws {
  88. let error = RPCError(code: .aborted, message: "aborted", metadata: ["bar": "baz"])
  89. let stream = ClientResponse.Stream(of: String.self, error: error)
  90. let single = await ClientResponse.Single(stream: stream)
  91. XCTAssertEqual(single.metadata, [:])
  92. XCTAssertThrowsRPCError(try single.message) {
  93. XCTAssertEqual($0, error)
  94. }
  95. XCTAssertEqual(single.trailingMetadata, ["bar": "baz"])
  96. }
  97. func testStreamToSingleConversionForInvalidSingleStream() async throws {
  98. let bodies: [[ClientResponse.Stream<String>.Contents.BodyPart]] = [
  99. [.message("1"), .message("2")], // Too many messages.
  100. [.trailingMetadata([:])], // Too few messages
  101. ]
  102. for body in bodies {
  103. let stream = ClientResponse.Stream(
  104. of: String.self,
  105. metadata: ["foo": "bar"],
  106. bodyParts: .elements(body)
  107. )
  108. let single = await ClientResponse.Single(stream: stream)
  109. XCTAssertEqual(single.metadata, [:])
  110. XCTAssertThrowsRPCError(try single.message) { error in
  111. XCTAssertEqual(error.code, .unimplemented)
  112. }
  113. XCTAssertEqual(single.trailingMetadata, [:])
  114. }
  115. }
  116. func testStreamToSingleConversionForInvalidStream() async throws {
  117. let bodies: [[ClientResponse.Stream<String>.Contents.BodyPart]] = [
  118. [], // Empty stream
  119. [.trailingMetadata([:]), .trailingMetadata([:])], // Multiple metadatas
  120. [.trailingMetadata([:]), .message("")], // Metadata then message
  121. ]
  122. for body in bodies {
  123. let stream = ClientResponse.Stream(
  124. of: String.self,
  125. metadata: ["foo": "bar"],
  126. bodyParts: .elements(body)
  127. )
  128. let single = await ClientResponse.Single(stream: stream)
  129. XCTAssertEqual(single.metadata, [:])
  130. XCTAssertThrowsRPCError(try single.message) { error in
  131. XCTAssertEqual(error.code, .internalError)
  132. }
  133. XCTAssertEqual(single.trailingMetadata, [:])
  134. }
  135. }
  136. func testStreamToSingleConversionForStreamThrowingRPCError() async throws {
  137. let error = RPCError(code: .dataLoss, message: "oops")
  138. let stream = ClientResponse.Stream(
  139. of: String.self,
  140. metadata: [:],
  141. bodyParts: .throwing(error)
  142. )
  143. let single = await ClientResponse.Single(stream: stream)
  144. XCTAssertThrowsRPCError(try single.message) {
  145. XCTAssertEqual($0, error)
  146. }
  147. }
  148. func testStreamToSingleConversionForStreamThrowingUnknownError() async throws {
  149. let stream = ClientResponse.Stream(
  150. of: String.self,
  151. metadata: [:],
  152. bodyParts: .throwing(CancellationError())
  153. )
  154. let single = await ClientResponse.Single(stream: stream)
  155. XCTAssertThrowsRPCError(try single.message) { error in
  156. XCTAssertEqual(error.code, .unknown)
  157. }
  158. }
  159. }