ClientResponseTests.swift 5.7 KB

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