HTTP2ConnectionsTests.swift 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * Copyright 2021, 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. @testable import GRPC
  17. import Logging
  18. import NIO
  19. import NIOHTTP2
  20. import XCTest
  21. final class HTTP2ConnectionsTests: GRPCTestCase {
  22. private final class Placeholder {}
  23. private var placeholders: [Placeholder] = []
  24. private let eventLoop = EmbeddedEventLoop()
  25. override func setUp() {
  26. super.setUp()
  27. }
  28. private func makeID() -> ObjectIdentifier {
  29. let placeholder = Placeholder()
  30. self.placeholders.append(placeholder)
  31. return ObjectIdentifier(placeholder)
  32. }
  33. private func makeConnectionState(withID id: ObjectIdentifier) -> HTTP2ConnectionState {
  34. return HTTP2ConnectionState(connectionManagerID: id)
  35. }
  36. func testEmpty() {
  37. var connections = HTTP2Connections(capacity: 5)
  38. XCTAssertEqual(connections.count, 0)
  39. XCTAssertNil(connections.availableTokensForConnection(withID: self.makeID()))
  40. XCTAssertNil(connections.firstConnectionID(where: { _ in true }))
  41. XCTAssertNil(connections.removeConnection(withID: self.makeID()))
  42. XCTAssertNil(connections.updateConnectivityState(.shutdown, forConnectionWithID: self.makeID()))
  43. XCTAssertNil(
  44. connections.updateMaximumAvailableTokens(
  45. .max,
  46. forConnectionWithID: self.makeID()
  47. )
  48. )
  49. }
  50. func testInsertAndRemove() {
  51. var connections = HTTP2Connections(capacity: 8)
  52. let connection1 = self.makeConnectionState(withID: self.makeID())
  53. let connection2 = self.makeConnectionState(withID: self.makeID())
  54. connections.insert(connection1)
  55. XCTAssertEqual(connections.count, 1)
  56. connections.insert(connection2)
  57. XCTAssertEqual(connections.count, 2)
  58. let removed = connections.removeConnection(withID: connection1.id)
  59. XCTAssertEqual(connections.count, 1)
  60. XCTAssertEqual(removed?.id, connection1.id)
  61. connections.insert(connection1)
  62. XCTAssertEqual(connections.count, 2)
  63. connections.removeAll()
  64. XCTAssertEqual(connections.count, 0)
  65. }
  66. func testFirstConnectionIDWhere() {
  67. var connections = HTTP2Connections(capacity: 8)
  68. let connection1 = self.makeConnectionState(withID: self.makeID())
  69. connections.insert(connection1)
  70. let connection2 = self.makeConnectionState(withID: self.makeID())
  71. connections.insert(connection2)
  72. XCTAssertNil(connections.firstConnectionID(where: { _ in false }))
  73. XCTAssertNil(connections.firstConnectionID(where: { $0.id == self.makeID() }))
  74. XCTAssertEqual(
  75. connections.firstConnectionID(where: { $0.id == connection1.id }),
  76. connection1.id
  77. )
  78. XCTAssertNotNil(connections.firstConnectionID(where: { $0.isIdle }))
  79. }
  80. func testSetupBorrowAndReturn() throws {
  81. var connections = HTTP2Connections(capacity: 8)
  82. let connection = self.makeConnectionState(withID: self.makeID())
  83. connections.insert(connection)
  84. var multiplexers: [HTTP2StreamMultiplexer] = []
  85. connections.startConnection(
  86. withID: connection.id,
  87. http2StreamMultiplexerFactory: {
  88. let multiplexer = HTTP2StreamMultiplexer(
  89. mode: .client,
  90. channel: EmbeddedChannel(loop: self.eventLoop),
  91. inboundStreamInitializer: nil
  92. )
  93. return self.eventLoop.makeSucceededFuture(multiplexer)
  94. },
  95. whenConnected: {
  96. multiplexers.append($0)
  97. }
  98. )
  99. // We have an embedded event loop, so we should already have a multiplexer and we can tell
  100. // the connections about it.
  101. XCTAssertEqual(multiplexers.count, 1)
  102. connections.connectionIsReady(withID: connection.id, multiplexer: multiplexers[0])
  103. // 100 is the default.
  104. XCTAssertEqual(connections.availableTokensForConnection(withID: connection.id), 100)
  105. // Borrow a token.
  106. let (mux, borrowed) = connections.borrowTokens(1, fromConnectionWithID: connection.id)
  107. // 1 token has been borrowed in total.
  108. XCTAssertEqual(borrowed, 1)
  109. XCTAssertTrue(mux === multiplexers[0])
  110. XCTAssertEqual(connections.availableTokensForConnection(withID: connection.id), 99)
  111. // Return a token.
  112. connections.returnTokenToConnection(withID: connection.id)
  113. XCTAssertEqual(connections.availableTokensForConnection(withID: connection.id), 100)
  114. }
  115. }