ClientClosedChannelTests.swift 6.2 KB

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