RetryDelaySequenceTests.swift 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Copyright 2023, 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 XCTest
  17. @testable import GRPCCore
  18. final class RetryDelaySequenceTests: XCTestCase {
  19. func testSequence() {
  20. let policy = RetryPolicy(
  21. maxAttempts: 3, // ignored here
  22. initialBackoff: .seconds(1),
  23. maxBackoff: .seconds(8),
  24. backoffMultiplier: 2.0,
  25. retryableStatusCodes: [.aborted] // ignored here
  26. )
  27. let sequence = RetryDelaySequence(policy: policy)
  28. var iterator = sequence.makeIterator()
  29. // The iterator will never return 'nil', '!' is safe.
  30. XCTAssertLessThanOrEqual(iterator.next()!, .seconds(1))
  31. XCTAssertLessThanOrEqual(iterator.next()!, .seconds(2))
  32. XCTAssertLessThanOrEqual(iterator.next()!, .seconds(4))
  33. XCTAssertLessThanOrEqual(iterator.next()!, .seconds(8))
  34. XCTAssertLessThanOrEqual(iterator.next()!, .seconds(8)) // Clamped
  35. }
  36. func testSequenceSupportsMultipleIteration() {
  37. let policy = RetryPolicy(
  38. maxAttempts: 3, // ignored here
  39. initialBackoff: .seconds(1),
  40. maxBackoff: .seconds(8),
  41. backoffMultiplier: 2.0,
  42. retryableStatusCodes: [.aborted] // ignored here
  43. )
  44. let sequence = RetryDelaySequence(policy: policy)
  45. for _ in 0 ..< 10 {
  46. var iterator = sequence.makeIterator()
  47. // The iterator will never return 'nil', '!' is safe.
  48. XCTAssertLessThanOrEqual(iterator.next()!, .seconds(1))
  49. XCTAssertLessThanOrEqual(iterator.next()!, .seconds(2))
  50. XCTAssertLessThanOrEqual(iterator.next()!, .seconds(4))
  51. XCTAssertLessThanOrEqual(iterator.next()!, .seconds(8))
  52. XCTAssertLessThanOrEqual(iterator.next()!, .seconds(8)) // Clamped
  53. }
  54. }
  55. func testDurationToDouble() {
  56. let testData: [(Duration, Double)] = [
  57. (.zero, 0.0),
  58. (.seconds(1), 1.0),
  59. (.milliseconds(1500), 1.5),
  60. (.nanoseconds(1_000_000_000), 1.0),
  61. (.nanoseconds(3_141_592_653 as Int64), 3.141592653),
  62. ]
  63. for (duration, expected) in testData {
  64. XCTAssertEqual(RetryDelaySequence.Iterator._durationToTimeInterval(duration), expected)
  65. }
  66. }
  67. func testDoubleToDuration() {
  68. let testData: [(Double, Duration)] = [
  69. (0.0, .zero),
  70. (1.0, .seconds(1)),
  71. (1.5, .milliseconds(1500)),
  72. (1.0, .nanoseconds(1_000_000_000)),
  73. (3.141592653, .nanoseconds(3_141_592_653 as Int64)),
  74. ]
  75. for (seconds, expected) in testData {
  76. let actual = RetryDelaySequence.Iterator._timeIntervalToDuration(seconds)
  77. XCTAssertEqual(actual.components.seconds, expected.components.seconds)
  78. // We lose some precision in the conversion, that's fine.
  79. XCTAssertEqual(actual.components.attoseconds / 1_000, expected.components.attoseconds / 1_000)
  80. }
  81. }
  82. }