ConnectionBackoffTests.swift 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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 XCTest
  19. class ConnectionBackoffTests: XCTestCase {
  20. var backoff = ConnectionBackoff()
  21. func testExpectedValuesWithNoJitter() {
  22. self.backoff.jitter = 0.0
  23. self.backoff.multiplier = 2.0
  24. self.backoff.initialBackoff = 1.0
  25. self.backoff.maximumBackoff = 16.0
  26. self.backoff.minimumConnectionTimeout = 4.2
  27. let timeoutAndBackoff = Array(self.backoff)
  28. let expectedBackoff: [TimeInterval] = [1.0, 2.0, 4.0, 8.0, 16.0]
  29. XCTAssertEqual(expectedBackoff, timeoutAndBackoff.map { $0.backoff })
  30. let expectedTimeout: [TimeInterval] = [4.2, 4.2, 4.2, 8.0, 16.0]
  31. XCTAssertEqual(expectedTimeout, timeoutAndBackoff.map { $0.timeout })
  32. }
  33. func testBackoffWithNoJitter() {
  34. self.backoff.jitter = 0.0
  35. for (i, timeoutAndBackoff) in self.backoff.enumerated() {
  36. let expected = min(pow(self.backoff.initialBackoff * self.backoff.multiplier, Double(i)),
  37. self.backoff.maximumBackoff)
  38. XCTAssertEqual(expected, timeoutAndBackoff.backoff, accuracy: 1e-6)
  39. }
  40. }
  41. func testBackoffWithJitter() {
  42. for (i, timeoutAndBackoff) in self.backoff.enumerated() {
  43. let unjittered = min(pow(self.backoff.initialBackoff * self.backoff.multiplier, Double(i)),
  44. self.backoff.maximumBackoff)
  45. let halfJitterRange = self.backoff.jitter * unjittered
  46. let jitteredRange = (unjittered-halfJitterRange)...(unjittered+halfJitterRange)
  47. XCTAssert(jitteredRange.contains(timeoutAndBackoff.backoff))
  48. }
  49. }
  50. func testBackoffDoesNotExceedMaximum() {
  51. // Since jitter is applied after checking against the maximum allowed backoff, the maximum
  52. // backoff can still be exceeded if jitter is non-zero.
  53. self.backoff.jitter = 0.0
  54. for (_, backoff) in self.backoff {
  55. XCTAssertLessThanOrEqual(backoff, self.backoff.maximumBackoff)
  56. }
  57. }
  58. func testConnectionTimeoutAlwaysGreatherThanOrEqualToMinimum() {
  59. for (connectionTimeout, _) in self.backoff {
  60. XCTAssertGreaterThanOrEqual(connectionTimeout, self.backoff.minimumConnectionTimeout)
  61. }
  62. }
  63. }