FABOperationPreFlightCancellationTest.m 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright 2019 Google
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // This test class checks the behavior of an operation that is cancelled before
  15. // it begins execution. It observes the operation's isExecuting property and fails
  16. // the test if that property is ever set to true. The completionBlock should execute,
  17. // but asyncCompletion should not.
  18. #import <XCTest/XCTest.h>
  19. #import "Crashlytics/Shared/FIRCLSOperation/FIRCLSOperation.h"
  20. #import "Crashlytics/UnitTests/FABOperation/FABTestAsyncOperation.h"
  21. #import "Crashlytics/UnitTests/FABOperation/FABTestExpectations.h"
  22. @interface FABOperationPreFlightCancellationTest : XCTestCase
  23. @end
  24. @implementation FABOperationPreFlightCancellationTest
  25. - (void)testAsyncCancellationPreFlight {
  26. FABTestAsyncOperation *cancelledOperation = [[FABTestAsyncOperation alloc] init];
  27. cancelledOperation.name = @"cancelledOperation";
  28. [FABTestExpectations
  29. addPreFlightCancellationCompletionExpectationsToOperation:cancelledOperation
  30. testCase:self
  31. asyncAssertionBlock:^(NSString *operationName,
  32. NSError *error) {
  33. XCTFail(@"asyncCompletion should not have executed "
  34. @"for %@",
  35. operationName);
  36. }];
  37. FABTestExpectationObserver *observer =
  38. [FABTestExpectations addPreFlightCancellationKVOExpectationsToOperation:cancelledOperation
  39. testCase:self];
  40. observer.assertionBlock = ^{
  41. XCTFail(@"%@ should never have begun executing", cancelledOperation.name);
  42. };
  43. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  44. queue.maxConcurrentOperationCount = 1;
  45. [cancelledOperation cancel];
  46. [queue addOperation:cancelledOperation];
  47. [self waitForExpectationsWithTimeout:5
  48. handler:^(NSError *error) {
  49. XCTAssertNil(error, @"expectations failed: %@", error);
  50. }];
  51. }
  52. // This test case adds several async operations to a compound operation and cancels the compound
  53. // operation before it can execute. All suboperations and the compound operation are tested using
  54. // pre-flight cancellation checks.
  55. - (void)testCompoundCancellationPreFlight {
  56. FIRCLSCompoundOperation *cancelledCompoundOperation = [[FIRCLSCompoundOperation alloc] init];
  57. cancelledCompoundOperation.name = @"cancelled compound operation";
  58. cancelledCompoundOperation.compoundQueue.maxConcurrentOperationCount = 1;
  59. NSMutableArray<NSOperation *> *cancelledSuboperations = [NSMutableArray array];
  60. NSMutableArray *observers = [NSMutableArray array];
  61. for (int i = 0; i < 5; i++) {
  62. FABTestAsyncOperation *subOperation = [[FABTestAsyncOperation alloc] init];
  63. subOperation.name = [NSString stringWithFormat:@"cancelledOperation %i", i];
  64. [cancelledSuboperations addObject:subOperation];
  65. [FABTestExpectations
  66. addPreFlightCancellationCompletionExpectationsToOperation:subOperation
  67. testCase:self
  68. asyncAssertionBlock:^(NSString *operationName,
  69. NSError *error) {
  70. XCTFail(@"asyncCompletion should not have executed "
  71. @"for %@",
  72. operationName);
  73. }];
  74. FABTestExpectationObserver *observer =
  75. [FABTestExpectations addPreFlightCancellationKVOExpectationsToOperation:subOperation
  76. testCase:self];
  77. observer.assertionBlock = ^{
  78. XCTFail(@"%@ should not have begun executing", subOperation.name);
  79. };
  80. [observers addObject:observer];
  81. }
  82. cancelledCompoundOperation.operations = cancelledSuboperations;
  83. [FABTestExpectations
  84. addPreFlightCancellationCompletionExpectationsToOperation:cancelledCompoundOperation
  85. testCase:self
  86. asyncAssertionBlock:^(NSString *operationName,
  87. NSError *error) {
  88. XCTAssertNotNil(error,
  89. @"Should have received error for "
  90. @"cancellation of %@.",
  91. operationName);
  92. XCTAssertEqual(
  93. error.code,
  94. FIRCLSCompoundOperationErrorCodeCancelled,
  95. @"Unexpected error code from %@.", operationName);
  96. }];
  97. FABTestExpectationObserver *observer = [FABTestExpectations
  98. addPreFlightCancellationKVOExpectationsToOperation:cancelledCompoundOperation
  99. testCase:self];
  100. observer.assertionBlock = ^{
  101. XCTFail(@"%@ should not have begun executing", cancelledCompoundOperation.name);
  102. };
  103. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  104. [cancelledCompoundOperation cancel];
  105. [queue addOperation:cancelledCompoundOperation];
  106. [self waitForExpectationsWithTimeout:5
  107. handler:^(NSError *error) {
  108. XCTAssertNil(error, @"expectations failed: %@", error);
  109. }];
  110. }
  111. @end