ClientResponseTests.swift 5.7 KB

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