ClientClosedChannelTests.swift 6.4 KB

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