RetryThrottleTests.swift 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  19. final class RetryThrottleTests: XCTestCase {
  20. func testThrottleOnInit() {
  21. let throttle = RetryThrottle(maximumTokens: 10, tokenRatio: 0.1)
  22. // Start with max tokens, so permitted.
  23. XCTAssertTrue(throttle.isRetryPermitted)
  24. XCTAssertEqual(throttle.maximumTokens, 10)
  25. XCTAssertEqual(throttle.tokens, 10)
  26. XCTAssertEqual(throttle.tokenRatio, 0.1)
  27. }
  28. func testThrottleIgnoresMoreThanThreeDecimals() {
  29. let throttle = RetryThrottle(maximumTokens: 10, tokenRatio: 0.1239)
  30. XCTAssertEqual(throttle.tokenRatio, 0.123)
  31. }
  32. func testFailureReducesTokens() {
  33. let throttle = RetryThrottle(maximumTokens: 10, tokenRatio: 0.1)
  34. XCTAssertEqual(throttle.tokens, 10)
  35. XCTAssert(throttle.isRetryPermitted)
  36. throttle.recordFailure()
  37. XCTAssertEqual(throttle.tokens, 9)
  38. XCTAssert(throttle.isRetryPermitted)
  39. throttle.recordFailure()
  40. XCTAssertEqual(throttle.tokens, 8)
  41. XCTAssert(throttle.isRetryPermitted)
  42. throttle.recordFailure()
  43. XCTAssertEqual(throttle.tokens, 7)
  44. XCTAssert(throttle.isRetryPermitted)
  45. throttle.recordFailure()
  46. XCTAssertEqual(throttle.tokens, 6)
  47. XCTAssert(throttle.isRetryPermitted)
  48. // Drop to threshold, retries no longer allowed.
  49. throttle.recordFailure()
  50. XCTAssertEqual(throttle.tokens, 5)
  51. XCTAssertFalse(throttle.isRetryPermitted)
  52. }
  53. func testTokensCantDropBelowZero() {
  54. let throttle = RetryThrottle(maximumTokens: 10, tokenRatio: 0.1)
  55. for _ in 0 ..< 1000 {
  56. throttle.recordFailure()
  57. XCTAssertGreaterThanOrEqual(throttle.tokens, 0)
  58. }
  59. XCTAssertEqual(throttle.tokens, 0)
  60. }
  61. func testSuccessIncreasesTokens() {
  62. let throttle = RetryThrottle(maximumTokens: 10, tokenRatio: 0.1)
  63. // Drop to zero.
  64. for _ in 0 ..< 10 {
  65. throttle.recordFailure()
  66. }
  67. XCTAssertEqual(throttle.tokens, 0)
  68. // Start recording successes.
  69. throttle.recordSuccess()
  70. XCTAssertEqual(throttle.tokens, 0.1)
  71. throttle.recordSuccess()
  72. XCTAssertEqual(throttle.tokens, 0.2)
  73. throttle.recordSuccess()
  74. XCTAssertEqual(throttle.tokens, 0.3)
  75. }
  76. func testTokensCantRiseAboveMax() {
  77. let throttle = RetryThrottle(maximumTokens: 10, tokenRatio: 0.1)
  78. XCTAssertEqual(throttle.tokens, 10)
  79. throttle.recordSuccess()
  80. XCTAssertEqual(throttle.tokens, 10)
  81. }
  82. }