GRPCIdleHandlerStateMachineTests.swift 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. /*
  2. * Copyright 2020, 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 NIOHTTP2
  19. import XCTest
  20. @testable import GRPC
  21. class GRPCIdleHandlerStateMachineTests: GRPCTestCase {
  22. private func makeClientStateMachine() -> GRPCIdleHandlerStateMachine {
  23. return GRPCIdleHandlerStateMachine(role: .client, logger: self.clientLogger)
  24. }
  25. private func makeServerStateMachine() -> GRPCIdleHandlerStateMachine {
  26. return GRPCIdleHandlerStateMachine(role: .server, logger: self.serverLogger)
  27. }
  28. private func makeNoOpScheduled() -> Scheduled<Void> {
  29. let loop = EmbeddedEventLoop()
  30. return loop.scheduleTask(deadline: .distantFuture) { return () }
  31. }
  32. func testInactiveBeforeSettings() {
  33. var stateMachine = self.makeClientStateMachine()
  34. let op1 = stateMachine.channelInactive()
  35. op1.assertConnectionManager(.inactive)
  36. }
  37. func testInactiveAfterSettings() {
  38. var stateMachine = self.makeClientStateMachine()
  39. let op1 = stateMachine.receiveSettings([])
  40. op1.assertConnectionManager(.ready)
  41. let readyStateMachine = stateMachine
  42. // Inactive with a stream open.
  43. let op2 = stateMachine.streamCreated(withID: 1)
  44. op2.assertDoNothing()
  45. let op3 = stateMachine.channelInactive()
  46. op3.assertConnectionManager(.inactive)
  47. // Inactive with no open streams.
  48. stateMachine = readyStateMachine
  49. let op4 = stateMachine.channelInactive()
  50. op4.assertConnectionManager(.idle)
  51. }
  52. func testInactiveWhenWaitingToIdle() {
  53. var stateMachine = self.makeClientStateMachine()
  54. // Become ready.
  55. let op1 = stateMachine.receiveSettings([])
  56. op1.assertConnectionManager(.ready)
  57. op1.assertScheduleIdleTimeout()
  58. // Schedule the timeout.
  59. let op2 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  60. op2.assertDoNothing()
  61. // Become inactive unexpectedly.
  62. let op3 = stateMachine.channelInactive()
  63. op3.assertConnectionManager(.idle)
  64. }
  65. func testInactiveWhenQuiescing() {
  66. var stateMachine = self.makeClientStateMachine()
  67. // Become ready.
  68. let op1 = stateMachine.receiveSettings([])
  69. op1.assertConnectionManager(.ready)
  70. // Try a few combinations: initiator of shutdown, and whether streams are open or not when
  71. // shutdown is initiated.
  72. let readyStateMachine = stateMachine
  73. // (1) Peer initiates shutdown, no streams are open.
  74. do {
  75. let op2 = stateMachine.receiveGoAway()
  76. op2.assertGoAway(streamID: .rootStream)
  77. op2.assertShouldClose()
  78. // We become idle.
  79. let op3 = stateMachine.channelInactive()
  80. op3.assertConnectionManager(.idle)
  81. }
  82. // (2) We initiate shutdown, no streams are open.
  83. stateMachine = readyStateMachine
  84. do {
  85. let op2 = stateMachine.initiateGracefulShutdown()
  86. op2.assertGoAway(streamID: .rootStream)
  87. op2.assertShouldClose()
  88. // We become idle.
  89. let op3 = stateMachine.channelInactive()
  90. op3.assertConnectionManager(.idle)
  91. }
  92. stateMachine = readyStateMachine
  93. _ = stateMachine.streamCreated(withID: 1)
  94. let streamOpenStateMachine = stateMachine
  95. // (3) Peer initiates shutdown, streams are open.
  96. do {
  97. let op2 = stateMachine.receiveGoAway()
  98. op2.assertNoGoAway()
  99. op2.assertShouldNotClose()
  100. // We become inactive.
  101. let op3 = stateMachine.channelInactive()
  102. op3.assertConnectionManager(.inactive)
  103. }
  104. // (4) We initiate shutdown, streams are open.
  105. stateMachine = streamOpenStateMachine
  106. do {
  107. let op2 = stateMachine.initiateGracefulShutdown()
  108. op2.assertShouldNotClose()
  109. // We become inactive.
  110. let op3 = stateMachine.channelInactive()
  111. op3.assertConnectionManager(.inactive)
  112. }
  113. }
  114. func testReceiveSettings() {
  115. var stateMachine = self.makeClientStateMachine()
  116. // No open streams.
  117. let op1 = stateMachine.receiveSettings([])
  118. op1.assertConnectionManager(.ready)
  119. op1.assertScheduleIdleTimeout()
  120. // Open streams.
  121. stateMachine = self.makeClientStateMachine()
  122. let op2 = stateMachine.streamCreated(withID: 1)
  123. op2.assertDoNothing()
  124. let op3 = stateMachine.receiveSettings([])
  125. // No idle timeout to cancel.
  126. op3.assertConnectionManager(.ready)
  127. op3.assertNoIdleTimeoutTask()
  128. }
  129. func testReceiveSettingsWhenWaitingToIdle() {
  130. var stateMachine = self.makeClientStateMachine()
  131. // Become ready.
  132. let op1 = stateMachine.receiveSettings([])
  133. op1.assertConnectionManager(.ready)
  134. op1.assertScheduleIdleTimeout()
  135. // Receive more settings.
  136. let op2 = stateMachine.receiveSettings([])
  137. op2.assertDoNothing()
  138. // Schedule the timeout.
  139. let op3 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  140. op3.assertDoNothing()
  141. // More settings.
  142. let op4 = stateMachine.receiveSettings([])
  143. op4.assertDoNothing()
  144. }
  145. func testReceiveGoAwayWhenWaitingToIdle() {
  146. var stateMachine = self.makeClientStateMachine()
  147. // Become ready.
  148. let op1 = stateMachine.receiveSettings([])
  149. op1.assertConnectionManager(.ready)
  150. op1.assertScheduleIdleTimeout()
  151. // Schedule the timeout.
  152. let op2 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  153. op2.assertDoNothing()
  154. // Receive a GOAWAY frame.
  155. let op3 = stateMachine.receiveGoAway()
  156. op3.assertGoAway(streamID: .rootStream)
  157. op3.assertShouldClose()
  158. op3.assertCancelIdleTimeout()
  159. op3.assertConnectionManager(.quiescing)
  160. // Close; we were going to go idle anyway.
  161. let op4 = stateMachine.channelInactive()
  162. op4.assertConnectionManager(.idle)
  163. }
  164. func testInitiateGracefulShutdownWithNoOpenStreams() {
  165. var stateMachine = self.makeClientStateMachine()
  166. // No open streams: so GOAWAY and close.
  167. let op1 = stateMachine.initiateGracefulShutdown()
  168. op1.assertGoAway(streamID: .rootStream)
  169. op1.assertShouldClose()
  170. op1.assertConnectionManager(.quiescing)
  171. // Closed.
  172. let op2 = stateMachine.channelInactive()
  173. op2.assertConnectionManager(.inactive)
  174. }
  175. func testInitiateGracefulShutdownWithOpenStreams() {
  176. var stateMachine = self.makeClientStateMachine()
  177. // Open a stream.
  178. let op1 = stateMachine.streamCreated(withID: 1)
  179. op1.assertDoNothing()
  180. // Initiate shutdown.
  181. let op2 = stateMachine.initiateGracefulShutdown()
  182. op2.assertShouldNotClose()
  183. op2.assertConnectionManager(.quiescing)
  184. // Receive a GOAWAY; no change.
  185. let op3 = stateMachine.receiveGoAway()
  186. op3.assertDoNothing()
  187. // Close the remaining open stream, connection should close as a result.
  188. let op4 = stateMachine.streamClosed(withID: 1)
  189. op4.assertShouldClose()
  190. // Connection closed.
  191. let op5 = stateMachine.channelInactive()
  192. op5.assertConnectionManager(.inactive)
  193. }
  194. func testInitiateGracefulShutdownWhenWaitingToIdle() {
  195. var stateMachine = self.makeClientStateMachine()
  196. // Become 'ready'
  197. let op1 = stateMachine.receiveSettings([])
  198. op1.assertConnectionManager(.ready)
  199. op1.assertScheduleIdleTimeout()
  200. // Schedule the task.
  201. let op2 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  202. op2.assertDoNothing()
  203. // Initiate shutdown: cancel the timeout, send a GOAWAY and close.
  204. let op3 = stateMachine.initiateGracefulShutdown()
  205. op3.assertCancelIdleTimeout()
  206. op3.assertGoAway(streamID: .rootStream)
  207. op3.assertShouldClose()
  208. // Closed: become inactive.
  209. let op4 = stateMachine.channelInactive()
  210. op4.assertConnectionManager(.inactive)
  211. }
  212. func testInitiateGracefulShutdownWhenQuiescing() {
  213. var stateMachine = self.makeClientStateMachine()
  214. // Become ready.
  215. let op1 = stateMachine.receiveSettings([])
  216. op1.assertConnectionManager(.ready)
  217. op1.assertScheduleIdleTimeout()
  218. // Open a few streams.
  219. for streamID in stride(from: HTTP2StreamID(1), to: HTTP2StreamID(6), by: 2) {
  220. let op = stateMachine.streamCreated(withID: streamID)
  221. op.assertDoNothing()
  222. }
  223. // Receive a GOAWAY.
  224. let op2 = stateMachine.receiveGoAway()
  225. op2.assertNoGoAway()
  226. // Initiate shutdown from our side: we've already sent GOAWAY and have a stream open, we don't
  227. // need to do anything.
  228. let op3 = stateMachine.initiateGracefulShutdown()
  229. op3.assertDoNothing()
  230. // Close the first couple of streams; should be a no-op.
  231. for streamID in [HTTP2StreamID(1), HTTP2StreamID(3)] {
  232. let op = stateMachine.streamClosed(withID: streamID)
  233. op.assertDoNothing()
  234. }
  235. // Close the final stream.
  236. let op4 = stateMachine.streamClosed(withID: 5)
  237. op4.assertShouldClose()
  238. // Initiate shutdown again: we're closing so this should be a no-op.
  239. let op5 = stateMachine.initiateGracefulShutdown()
  240. op5.assertDoNothing()
  241. // Closed.
  242. let op6 = stateMachine.channelInactive()
  243. op6.assertConnectionManager(.inactive)
  244. }
  245. func testScheduleIdleTaskWhenStreamsAreOpen() {
  246. var stateMachine = self.makeClientStateMachine()
  247. // Become ready.
  248. let op1 = stateMachine.receiveSettings([])
  249. op1.assertConnectionManager(.ready)
  250. op1.assertScheduleIdleTimeout()
  251. // Open a stream before scheduling the task.
  252. let op2 = stateMachine.streamCreated(withID: 1)
  253. op2.assertDoNothing()
  254. // Schedule an idle timeout task: there are open streams so this should be cancelled.
  255. let op3 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  256. op3.assertCancelIdleTimeout()
  257. }
  258. func testScheduleIdleTaskWhenQuiescing() {
  259. var stateMachine = self.makeClientStateMachine()
  260. // Become ready.
  261. let op1 = stateMachine.receiveSettings([])
  262. op1.assertConnectionManager(.ready)
  263. op1.assertScheduleIdleTimeout()
  264. // Save the state machine so we can test a few branches.
  265. let readyStateMachine = stateMachine
  266. // (1) Scheduled when quiescing.
  267. let op2 = stateMachine.streamCreated(withID: 1)
  268. op2.assertDoNothing()
  269. // Start shutting down.
  270. _ = stateMachine.initiateGracefulShutdown()
  271. // Schedule an idle timeout task: we're quiescing, so cancel the task.
  272. let op4 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  273. op4.assertCancelIdleTimeout()
  274. // (2) Scheduled when closing.
  275. stateMachine = readyStateMachine
  276. let op5 = stateMachine.initiateGracefulShutdown()
  277. op5.assertGoAway(streamID: .rootStream)
  278. op5.assertShouldClose()
  279. // Schedule an idle timeout task: we're already closing, so cancel the task.
  280. let op6 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  281. op6.assertCancelIdleTimeout()
  282. }
  283. func testIdleTimeoutTaskFiresWhenIdle() {
  284. var stateMachine = self.makeClientStateMachine()
  285. // Become ready.
  286. let op1 = stateMachine.receiveSettings([])
  287. op1.assertConnectionManager(.ready)
  288. op1.assertScheduleIdleTimeout()
  289. // Schedule the task.
  290. let op2 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  291. op2.assertDoNothing()
  292. // Fire the task.
  293. let op3 = stateMachine.idleTimeoutTaskFired()
  294. op3.assertGoAway(streamID: .rootStream)
  295. op3.assertShouldClose()
  296. // Close.
  297. let op4 = stateMachine.channelInactive()
  298. op4.assertConnectionManager(.idle)
  299. }
  300. func testIdleTimeoutTaskFiresWhenClosed() {
  301. var stateMachine = self.makeClientStateMachine()
  302. // Become ready.
  303. let op1 = stateMachine.receiveSettings([])
  304. op1.assertConnectionManager(.ready)
  305. op1.assertScheduleIdleTimeout()
  306. // Schedule the task.
  307. let op2 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  308. op2.assertDoNothing()
  309. // Close.
  310. let op3 = stateMachine.channelInactive()
  311. op3.assertCancelIdleTimeout()
  312. // Fire the idle timeout task.
  313. let op4 = stateMachine.idleTimeoutTaskFired()
  314. op4.assertDoNothing()
  315. }
  316. func testShutdownNow() {
  317. var stateMachine = self.makeClientStateMachine()
  318. let op1 = stateMachine.shutdownNow()
  319. op1.assertGoAway(streamID: .rootStream)
  320. op1.assertShouldClose()
  321. let op2 = stateMachine.channelInactive()
  322. op2.assertConnectionManager(.inactive)
  323. }
  324. func testShutdownNowWhenWaitingToIdle() {
  325. var stateMachine = self.makeClientStateMachine()
  326. // Become ready.
  327. let op1 = stateMachine.receiveSettings([])
  328. op1.assertConnectionManager(.ready)
  329. op1.assertScheduleIdleTimeout()
  330. // Schedule the task.
  331. let op2 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  332. op2.assertDoNothing()
  333. let op3 = stateMachine.shutdownNow()
  334. op3.assertGoAway(streamID: .rootStream)
  335. op3.assertShouldClose()
  336. let op4 = stateMachine.channelInactive()
  337. op4.assertConnectionManager(.inactive)
  338. }
  339. func testShutdownNowWhenQuiescing() {
  340. var stateMachine = self.makeClientStateMachine()
  341. // Become ready.
  342. let op1 = stateMachine.receiveSettings([])
  343. op1.assertConnectionManager(.ready)
  344. op1.assertScheduleIdleTimeout()
  345. // Open a stream.
  346. let op2 = stateMachine.streamCreated(withID: 1)
  347. op2.assertDoNothing()
  348. // Initiate shutdown.
  349. let op3 = stateMachine.initiateGracefulShutdown()
  350. op3.assertNoGoAway()
  351. // Shutdown now.
  352. let op4 = stateMachine.shutdownNow()
  353. op4.assertShouldClose()
  354. }
  355. func testNormalFlow() {
  356. var stateMachine = self.makeClientStateMachine()
  357. // Become ready.
  358. let op1 = stateMachine.receiveSettings([])
  359. op1.assertConnectionManager(.ready)
  360. op1.assertScheduleIdleTimeout()
  361. // Schedule the task.
  362. let op2 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  363. op2.assertDoNothing()
  364. // Create a stream to cancel the task.
  365. let op3 = stateMachine.streamCreated(withID: 1)
  366. op3.assertCancelIdleTimeout()
  367. // Close the stream.
  368. let op4 = stateMachine.streamClosed(withID: 1)
  369. op4.assertScheduleIdleTimeout()
  370. // Receive a GOAWAY frame.
  371. let op5 = stateMachine.receiveGoAway()
  372. // We're the client, there are no server initiated streams, so GOAWAY with root stream.
  373. op5.assertGoAway(streamID: 0)
  374. // No open streams, so we can close now. Also assert the connection manager got a quiescing event.
  375. op5.assertShouldClose()
  376. op5.assertConnectionManager(.quiescing)
  377. // Closed.
  378. let op6 = stateMachine.channelInactive()
  379. // The peer initiated shutdown by sending GOAWAY, we'll idle.
  380. op6.assertConnectionManager(.idle)
  381. }
  382. func testClientSendsGoAwayAndOpensStream() {
  383. var stateMachine = self.makeServerStateMachine()
  384. let op1 = stateMachine.receiveSettings([])
  385. op1.assertConnectionManager(.ready)
  386. op1.assertScheduleIdleTimeout()
  387. // Schedule the idle timeout.
  388. let op2 = stateMachine.scheduledIdleTimeoutTask(self.makeNoOpScheduled())
  389. op2.assertDoNothing()
  390. // Create a stream to cancel the task.
  391. let op3 = stateMachine.streamCreated(withID: 1)
  392. op3.assertCancelIdleTimeout()
  393. // Receive a GOAWAY frame from the client.
  394. let op4 = stateMachine.receiveGoAway()
  395. op4.assertGoAway(streamID: .maxID)
  396. op4.assertShouldPingAfterGoAway()
  397. op4.assertConnectionManager(.quiescing)
  398. // Create another stream. This is fine, the client hasn't ack'd the ping yet.
  399. let op5 = stateMachine.streamCreated(withID: 7)
  400. op5.assertDoNothing()
  401. // Receiving the ping is handled by a different state machine which will tell us to ratchet
  402. // down the go away stream ID.
  403. let op6 = stateMachine.ratchetDownGoAwayStreamID()
  404. op6.assertGoAway(streamID: 7)
  405. op6.assertShouldNotPingAfterGoAway()
  406. let op7 = stateMachine.streamClosed(withID: 7)
  407. op7.assertDoNothing()
  408. let op8 = stateMachine.streamClosed(withID: 1)
  409. op8.assertShouldClose()
  410. }
  411. func testRatchetDownStreamIDWhenNotQuiescing() {
  412. var stateMachine = self.makeServerStateMachine()
  413. _ = stateMachine.receiveSettings([])
  414. // from the 'operating' state.
  415. stateMachine.ratchetDownGoAwayStreamID().assertDoNothing()
  416. // move to the 'waiting to idle' state.
  417. let promise = EmbeddedEventLoop().makePromise(of: Void.self)
  418. let task = Scheduled(promise: promise, cancellationTask: {})
  419. stateMachine.scheduledIdleTimeoutTask(task).assertDoNothing()
  420. promise.succeed(())
  421. stateMachine.ratchetDownGoAwayStreamID().assertDoNothing()
  422. // move to 'closing'
  423. _ = stateMachine.idleTimeoutTaskFired()
  424. stateMachine.ratchetDownGoAwayStreamID().assertDoNothing()
  425. // move to 'closed'
  426. _ = stateMachine.channelInactive()
  427. stateMachine.ratchetDownGoAwayStreamID().assertDoNothing()
  428. }
  429. func testStreamIDWhenQuiescing() {
  430. var stateMachine = self.makeClientStateMachine()
  431. let op1 = stateMachine.receiveSettings([])
  432. op1.assertConnectionManager(.ready)
  433. // Open a stream so we enter quiescing when receiving the GOAWAY.
  434. let op2 = stateMachine.streamCreated(withID: 1)
  435. op2.assertDoNothing()
  436. let op3 = stateMachine.receiveGoAway()
  437. op3.assertConnectionManager(.quiescing)
  438. // Create a new stream. This can happen if the GOAWAY races with opening the stream; HTTP2 will
  439. // open and then close the stream with an error.
  440. let op4 = stateMachine.streamCreated(withID: 3)
  441. op4.assertDoNothing()
  442. // Close the newly opened stream.
  443. let op5 = stateMachine.streamClosed(withID: 3)
  444. op5.assertDoNothing()
  445. // Close the original stream.
  446. let op6 = stateMachine.streamClosed(withID: 1)
  447. // Now we can send a GOAWAY with stream ID zero (we're the client and the server didn't open
  448. // any streams).
  449. XCTAssertEqual(op6.sendGoAwayWithLastPeerInitiatedStreamID, 0)
  450. }
  451. }
  452. extension GRPCIdleHandlerStateMachine.Operations {
  453. func assertDoNothing() {
  454. XCTAssertNil(self.connectionManagerEvent)
  455. XCTAssertNil(self.idleTask)
  456. XCTAssertNil(self.sendGoAwayWithLastPeerInitiatedStreamID)
  457. XCTAssertFalse(self.shouldCloseChannel)
  458. XCTAssertFalse(self.shouldPingAfterGoAway)
  459. }
  460. func assertGoAway(streamID: HTTP2StreamID) {
  461. XCTAssertEqual(self.sendGoAwayWithLastPeerInitiatedStreamID, streamID)
  462. }
  463. func assertNoGoAway() {
  464. XCTAssertNil(self.sendGoAwayWithLastPeerInitiatedStreamID)
  465. }
  466. func assertScheduleIdleTimeout() {
  467. switch self.idleTask {
  468. case .some(.schedule):
  469. ()
  470. case .some(.cancel), .none:
  471. XCTFail("Expected 'schedule' but was '\(String(describing: self.idleTask))'")
  472. }
  473. }
  474. func assertCancelIdleTimeout() {
  475. switch self.idleTask {
  476. case .some(.cancel):
  477. ()
  478. case .some(.schedule), .none:
  479. XCTFail("Expected 'cancel' but was '\(String(describing: self.idleTask))'")
  480. }
  481. }
  482. func assertNoIdleTimeoutTask() {
  483. XCTAssertNil(self.idleTask)
  484. }
  485. func assertConnectionManager(_ event: GRPCIdleHandlerStateMachine.ConnectionManagerEvent) {
  486. XCTAssertEqual(self.connectionManagerEvent, event)
  487. }
  488. func assertNoConnectionManagerEvent() {
  489. XCTAssertNil(self.connectionManagerEvent)
  490. }
  491. func assertShouldClose() {
  492. XCTAssertTrue(self.shouldCloseChannel)
  493. }
  494. func assertShouldNotClose() {
  495. XCTAssertFalse(self.shouldCloseChannel)
  496. }
  497. func assertShouldPingAfterGoAway() {
  498. XCTAssert(self.shouldPingAfterGoAway)
  499. }
  500. func assertShouldNotPingAfterGoAway() {
  501. XCTAssertFalse(self.shouldPingAfterGoAway)
  502. }
  503. }