ClientClosedChannelTests.swift 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Copyright 2019, 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 EchoModel
  17. import Foundation
  18. import GRPC
  19. import NIOCore
  20. import XCTest
  21. class ClientClosedChannelTests: EchoTestCaseBase {
  22. func testUnaryOnClosedConnection() throws {
  23. let initialMetadataExpectation = self.makeInitialMetadataExpectation()
  24. let responseExpectation = self.makeResponseExpectation()
  25. let statusExpectation = self.makeStatusExpectation()
  26. self.client.channel.close().map {
  27. self.client.get(Echo_EchoRequest(text: "foo"))
  28. }.whenSuccess { get in
  29. get.initialMetadata.assertError(fulfill: initialMetadataExpectation)
  30. get.response.assertError(fulfill: responseExpectation)
  31. get.status.map { $0.code }.assertEqual(.unavailable, fulfill: statusExpectation)
  32. }
  33. self.wait(
  34. for: [initialMetadataExpectation, responseExpectation, statusExpectation],
  35. timeout: self.defaultTestTimeout
  36. )
  37. }
  38. func testClientStreamingOnClosedConnection() throws {
  39. let initialMetadataExpectation = self.makeInitialMetadataExpectation()
  40. let responseExpectation = self.makeResponseExpectation()
  41. let statusExpectation = self.makeStatusExpectation()
  42. self.client.channel.close().map {
  43. self.client.collect()
  44. }.whenSuccess { collect in
  45. collect.initialMetadata.assertError(fulfill: initialMetadataExpectation)
  46. collect.response.assertError(fulfill: responseExpectation)
  47. collect.status.map { $0.code }.assertEqual(.unavailable, fulfill: statusExpectation)
  48. }
  49. self.wait(
  50. for: [initialMetadataExpectation, responseExpectation, statusExpectation],
  51. timeout: self.defaultTestTimeout
  52. )
  53. }
  54. func testClientStreamingWhenConnectionIsClosedBetweenMessages() throws {
  55. let statusExpectation = self.makeStatusExpectation()
  56. let responseExpectation = self.makeResponseExpectation()
  57. let requestExpectation = self.makeRequestExpectation(expectedFulfillmentCount: 3)
  58. let collect = self.client.collect()
  59. collect.sendMessage(Echo_EchoRequest(text: "foo")).peek {
  60. requestExpectation.fulfill()
  61. }.flatMap {
  62. collect.sendMessage(Echo_EchoRequest(text: "bar"))
  63. }.peek {
  64. requestExpectation.fulfill()
  65. }.flatMap {
  66. self.client.channel.close()
  67. }.peekError { error in
  68. XCTFail("Encountered error before or during closing the connection: \(error)")
  69. }.flatMap {
  70. collect.sendMessage(Echo_EchoRequest(text: "baz"))
  71. }.assertError(fulfill: requestExpectation)
  72. collect.response.assertError(fulfill: responseExpectation)
  73. collect.status.map { $0.code }.assertEqual(.unavailable, fulfill: statusExpectation)
  74. self.wait(
  75. for: [statusExpectation, responseExpectation, requestExpectation],
  76. timeout: self.defaultTestTimeout
  77. )
  78. }
  79. func testServerStreamingOnClosedConnection() throws {
  80. let initialMetadataExpectation = self.makeInitialMetadataExpectation()
  81. let statusExpectation = self.makeStatusExpectation()
  82. self.client.channel.close().map {
  83. self.client.expand(Echo_EchoRequest(text: "foo")) { response in
  84. XCTFail("No response expected but got: \(response)")
  85. }
  86. }.whenSuccess { expand in
  87. expand.initialMetadata.assertError(fulfill: initialMetadataExpectation)
  88. expand.status.map { $0.code }.assertEqual(.unavailable, fulfill: statusExpectation)
  89. }
  90. self.wait(
  91. for: [initialMetadataExpectation, statusExpectation],
  92. timeout: self.defaultTestTimeout
  93. )
  94. }
  95. func testBidirectionalStreamingOnClosedConnection() throws {
  96. let initialMetadataExpectation = self.makeInitialMetadataExpectation()
  97. let statusExpectation = self.makeStatusExpectation()
  98. self.client.channel.close().map {
  99. self.client.update { response in
  100. XCTFail("No response expected but got: \(response)")
  101. }
  102. }.whenSuccess { update in
  103. update.initialMetadata.assertError(fulfill: initialMetadataExpectation)
  104. update.status.map { $0.code }.assertEqual(.unavailable, fulfill: statusExpectation)
  105. }
  106. self.wait(
  107. for: [initialMetadataExpectation, statusExpectation],
  108. timeout: self.defaultTestTimeout
  109. )
  110. }
  111. func testBidirectionalStreamingWhenConnectionIsClosedBetweenMessages() throws {
  112. let statusExpectation = self.makeStatusExpectation()
  113. let requestExpectation = self.makeRequestExpectation(expectedFulfillmentCount: 3)
  114. // We can't make any assertions about the number of responses we will receive before closing
  115. // the connection; just ignore all responses.
  116. let update = self.client.update { _ in }
  117. update.sendMessage(Echo_EchoRequest(text: "foo")).peek {
  118. requestExpectation.fulfill()
  119. }.flatMap {
  120. update.sendMessage(Echo_EchoRequest(text: "bar"))
  121. }.peek {
  122. requestExpectation.fulfill()
  123. }.flatMap {
  124. self.client.channel.close()
  125. }.peekError { error in
  126. XCTFail("Encountered error before or during closing the connection: \(error)")
  127. }.flatMap {
  128. update.sendMessage(Echo_EchoRequest(text: "baz"))
  129. }.assertError(fulfill: requestExpectation)
  130. update.status.map { $0.code }.assertEqual(.unavailable, fulfill: statusExpectation)
  131. self.wait(for: [statusExpectation, requestExpectation], timeout: self.defaultTestTimeout)
  132. }
  133. func testBidirectionalStreamingWithNoPromiseWhenConnectionIsClosedBetweenMessages() throws {
  134. let statusExpectation = self.makeStatusExpectation()
  135. let update = self.client.update { response in
  136. XCTFail("No response expected but got: \(response)")
  137. }
  138. update.sendMessage(.with { $0.text = "0" }).flatMap {
  139. self.client.channel.close()
  140. }.whenSuccess {
  141. update.sendMessage(.with { $0.text = "1" }, promise: nil)
  142. }
  143. update.status.map { $0.code }.assertEqual(.unavailable, fulfill: statusExpectation)
  144. self.wait(for: [statusExpectation], timeout: self.defaultTestTimeout)
  145. }
  146. }