FIRInstallationsBackoffControllerTests.m 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * Copyright 2020 Google LLC
  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/XCTest.h>
  17. #import "FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.h"
  18. #import "FirebaseInstallations/Source/Tests/Utils/FIRTestCurrentDateProvider.h"
  19. @interface FIRInstallationsBackoffControllerTests : XCTestCase
  20. @property(nonatomic) FIRInstallationsBackoffController *backoffController;
  21. @property(nonatomic) FIRTestCurrentDateProvider *testDateProvider;
  22. @property(nonatomic) NSDate *initialCurrentDate;
  23. @end
  24. @implementation FIRInstallationsBackoffControllerTests
  25. - (void)setUp {
  26. self.initialCurrentDate = [NSDate date];
  27. self.testDateProvider = [[FIRTestCurrentDateProvider alloc] init];
  28. self.testDateProvider.date = self.initialCurrentDate;
  29. self.backoffController = [[FIRInstallationsBackoffController alloc]
  30. initWithCurrentDateProvider:[self.testDateProvider currentDateProvider]];
  31. }
  32. - (void)tearDown {
  33. self.backoffController = nil;
  34. self.testDateProvider = nil;
  35. }
  36. - (void)testIsNextRequestAllowed_WhenNoEvents {
  37. XCTAssertTrue([self.backoffController isNextRequestAllowed]);
  38. }
  39. - (void)testIsNextRequestAllowed_AfterUnrecoverableError {
  40. XCTAssertTrue([self.backoffController isNextRequestAllowed]);
  41. [self.backoffController registerEvent:FIRInstallationsBackoffEventUnrecoverableFailure];
  42. [self assertBackoffTimeInterval:24 * 60 * 60]; // 24h
  43. }
  44. - (void)testIsNextRequestAllowed_AfterRecoverableError {
  45. XCTAssertTrue([self.backoffController isNextRequestAllowed]);
  46. for (NSInteger attempt = 1; attempt < 21; attempt++) {
  47. NSTimeInterval expectedBackoffInterval = MIN(pow(2, attempt), 30 * 60 /*30min*/);
  48. [self.backoffController registerEvent:FIRInstallationsBackoffEventRecoverableFailure];
  49. [self assertBackoffTimeInterval:expectedBackoffInterval];
  50. }
  51. [self.backoffController registerEvent:FIRInstallationsBackoffEventUnrecoverableFailure];
  52. [self assertBackoffTimeInterval:24 * 60 * 60]; // 24h
  53. }
  54. - (void)testIsNextRequestAllowed_WhenSuccessAfterError {
  55. [self.backoffController registerEvent:FIRInstallationsBackoffEventRecoverableFailure];
  56. XCTAssertFalse([self.backoffController isNextRequestAllowed]);
  57. // Expect request allowed after success.
  58. [self.backoffController registerEvent:FIRInstallationsBackoffEventSuccess];
  59. XCTAssertTrue([self.backoffController isNextRequestAllowed]);
  60. [self.backoffController registerEvent:FIRInstallationsBackoffEventUnrecoverableFailure];
  61. XCTAssertFalse([self.backoffController isNextRequestAllowed]);
  62. // Expect request allowed after success.
  63. [self.backoffController registerEvent:FIRInstallationsBackoffEventSuccess];
  64. XCTAssertTrue([self.backoffController isNextRequestAllowed]);
  65. }
  66. #pragma mark - Helpers
  67. - (void)assertBackoffTimeInterval:(NSTimeInterval)expectedBackoffTimeInterval {
  68. // Expect request denied right after the event.
  69. self.testDateProvider.date = self.initialCurrentDate;
  70. XCTAssertFalse([self.backoffController isNextRequestAllowed], @"Test: %@, interval: %f",
  71. self.name, expectedBackoffTimeInterval);
  72. // Expect request denied in the middle of backoff time interval.
  73. NSTimeInterval halfBackoffInterval = expectedBackoffTimeInterval * 0.5;
  74. self.testDateProvider.date =
  75. [self.initialCurrentDate dateByAddingTimeInterval:halfBackoffInterval];
  76. XCTAssertFalse([self.backoffController isNextRequestAllowed], @"Test: %@, interval: %f",
  77. self.name, expectedBackoffTimeInterval);
  78. // Expect request denied close to the end of backoff time interval.
  79. NSTimeInterval rightBeforeBackoffInterval = expectedBackoffTimeInterval - 1;
  80. self.testDateProvider.date =
  81. [self.initialCurrentDate dateByAddingTimeInterval:rightBeforeBackoffInterval];
  82. XCTAssertFalse([self.backoffController isNextRequestAllowed], @"Test: %@, interval: %f",
  83. self.name, expectedBackoffTimeInterval);
  84. // Expect request allowed right after backoff time interval.
  85. NSTimeInterval rightAfterBackoffInterval = expectedBackoffTimeInterval + 1.1;
  86. self.testDateProvider.date =
  87. [self.initialCurrentDate dateByAddingTimeInterval:rightAfterBackoffInterval];
  88. XCTAssertTrue([self.backoffController isNextRequestAllowed], @"Test: %@, interval: %f", self.name,
  89. expectedBackoffTimeInterval);
  90. self.testDateProvider.date = self.initialCurrentDate;
  91. }
  92. @end