ClientConnectionHandlerStateMachineTests.swift 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * Copyright 2024, 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 NIOCore
  17. import NIOEmbedded
  18. import XCTest
  19. @testable import GRPCHTTP2Core
  20. final class ClientConnectionHandlerStateMachineTests: XCTestCase {
  21. private func makeStateMachine(
  22. keepaliveWithoutCalls: Bool = false
  23. ) -> ClientConnectionHandler.StateMachine {
  24. return ClientConnectionHandler.StateMachine(allowKeepaliveWithoutCalls: keepaliveWithoutCalls)
  25. }
  26. func testCloseSomeStreamsWhenActive() {
  27. var state = self.makeStateMachine()
  28. state.streamOpened(1)
  29. state.streamOpened(2)
  30. XCTAssertEqual(state.streamClosed(2), .none)
  31. XCTAssertEqual(state.streamClosed(1), .startIdleTimer(cancelKeepalive: true))
  32. }
  33. func testCloseSomeStreamsWhenClosing() {
  34. var state = self.makeStateMachine()
  35. state.streamOpened(1)
  36. state.streamOpened(2)
  37. XCTAssertTrue(state.beginClosing())
  38. XCTAssertEqual(state.streamClosed(2), .none)
  39. XCTAssertEqual(state.streamClosed(1), .close)
  40. }
  41. func testOpenAndCloseStreamWhenClosed() {
  42. var state = self.makeStateMachine()
  43. _ = state.closed()
  44. state.streamOpened(1)
  45. XCTAssertEqual(state.streamClosed(1), .none)
  46. }
  47. func testSendKeepalivePing() {
  48. var state = self.makeStateMachine(keepaliveWithoutCalls: false)
  49. // No streams open so ping isn't allowed.
  50. XCTAssertFalse(state.sendKeepalivePing())
  51. // Stream open, ping allowed.
  52. state.streamOpened(1)
  53. XCTAssertTrue(state.sendKeepalivePing())
  54. // No stream, no ping.
  55. XCTAssertEqual(state.streamClosed(1), .startIdleTimer(cancelKeepalive: true))
  56. XCTAssertFalse(state.sendKeepalivePing())
  57. }
  58. func testSendKeepalivePingWhenAllowedWithoutCalls() {
  59. var state = self.makeStateMachine(keepaliveWithoutCalls: true)
  60. // Keep alive is allowed when no streams are open, so pings are allowed.
  61. XCTAssertTrue(state.sendKeepalivePing())
  62. state.streamOpened(1)
  63. XCTAssertTrue(state.sendKeepalivePing())
  64. XCTAssertEqual(state.streamClosed(1), .startIdleTimer(cancelKeepalive: false))
  65. XCTAssertTrue(state.sendKeepalivePing())
  66. }
  67. func testSendKeepalivePingWhenClosing() {
  68. var state = self.makeStateMachine(keepaliveWithoutCalls: false)
  69. state.streamOpened(1)
  70. XCTAssertTrue(state.beginClosing())
  71. // Stream is opened and state is closing, ping is allowed.
  72. XCTAssertTrue(state.sendKeepalivePing())
  73. }
  74. func testSendKeepalivePingWhenClosed() {
  75. var state = self.makeStateMachine(keepaliveWithoutCalls: true)
  76. _ = state.closed()
  77. XCTAssertFalse(state.sendKeepalivePing())
  78. }
  79. func testBeginGracefulShutdownWhenStreamsAreOpen() {
  80. var state = self.makeStateMachine()
  81. state.streamOpened(1)
  82. // Close is false as streams are still open.
  83. XCTAssertEqual(state.beginGracefulShutdown(promise: nil), .sendGoAway(false))
  84. }
  85. func testBeginGracefulShutdownWhenNoStreamsAreOpen() {
  86. var state = self.makeStateMachine()
  87. // Close immediately, not streams are open.
  88. XCTAssertEqual(state.beginGracefulShutdown(promise: nil), .sendGoAway(true))
  89. }
  90. }