ClientClosedChannelTests.swift 6.5 KB

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