RetryThrottleTests.swift 2.9 KB

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