Skip to content

Commit

Permalink
Add more tests around stopping fetchers with callbacks.
Browse files Browse the repository at this point in the history
Some of these cases are XCTSkipped as they reliable fail when run locally. This
will be follow up work to fix them.

These tests are likely to be racy since they are just using delays, but they do
catch some fail cause already. Some could be made non racy if the authorizer
delay and the stop ordering was perfectly synchronized, but that is likely to be
a fair amount of complexity to ensure it is done correctly and non blocking; so
it is deferred for now.

I also haven't reasoned through why the Service versions currently all pass when
the non service cases fail. That will get some attention during the followup to
fix the existing failures.
  • Loading branch information
thomasvl committed Nov 8, 2024
1 parent 2a38f99 commit e18fe7c
Show file tree
Hide file tree
Showing 3 changed files with 371 additions and 11 deletions.
2 changes: 2 additions & 0 deletions UnitTests/GTMSessionFetcherFetchingTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,13 @@ extern NSString *const kGTMGettysburgFileName;
@interface TestAuthorizer : NSObject <GTMSessionFetcherAuthorizer>

@property(atomic, assign, getter=isAsync) BOOL async;
@property(atomic, assign) NSUInteger delay; // Only honored if async
@property(atomic, assign, getter=isExpired) BOOL expired;
@property(atomic, assign) BOOL willFailWithError;

+ (instancetype)syncAuthorizer;
+ (instancetype)asyncAuthorizer;
+ (instancetype)asyncAuthorizerDelayed:(NSUInteger)delaySeconds;
+ (instancetype)expiredSyncAuthorizer;
+ (instancetype)expiredAsyncAuthorizer;

Expand Down
67 changes: 60 additions & 7 deletions UnitTests/GTMSessionFetcherFetchingTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -1567,19 +1567,56 @@ - (void)testImmediateCancelFetchWithCallback {
[self internalCancelFetchWithCallback:0];
}

- (void)testDelayedSyncAuthCancelFetchWithCallback {
[self internalCancelFetchWithCallback:1 authorizer:[TestAuthorizer syncAuthorizer]];
}

- (void)testImmediateSyncAuthCancelFetchWithCallback {
XCTSkip(@"Has failed on CI, but not locally, needs investigation.");
[self internalCancelFetchWithCallback:0 authorizer:[TestAuthorizer syncAuthorizer]];
}

- (void)testDelayedAsyncAuthCancelFetchWithCallback {
XCTSkip(@"Currently fails, needs fixing.");
[self internalCancelFetchWithCallback:1 authorizer:[TestAuthorizer asyncAuthorizer]];
}

- (void)testImmediateAsyncAuthCancelFetchWithCallback {
XCTSkip(@"Currently fails, needs fixing.");
[self internalCancelFetchWithCallback:0 authorizer:[TestAuthorizer asyncAuthorizer]];
}

- (void)testDelayedAsyncDelayedAuthCancelFetchWithCallback {
XCTSkip(@"Currently fails, needs fixing.");
[self internalCancelFetchWithCallback:1 authorizer:[TestAuthorizer asyncAuthorizerDelayed:2]];
}

- (void)testImmediateAsyncDelayedAuthCancelFetchWithCallback {
XCTSkip(@"Currently fails, needs fixing.");
[self internalCancelFetchWithCallback:0 authorizer:[TestAuthorizer asyncAuthorizerDelayed:1]];
}

- (void)internalCancelFetchWithCallback:(unsigned int)sleepTime {
[self internalCancelFetchWithCallback:sleepTime authorizer:nil];
}

#pragma clang diagnostic ignored "-Wdeprecated"
- (void)internalCancelFetchWithCallback:(unsigned int)sleepTime
authorizer:(nullable id<GTMFetcherAuthorizationProtocol>)authorizer {
#pragma clang diagnostic pop
if (!_isServerRunning) return;

CREATE_START_STOP_NOTIFICATION_EXPECTATIONS(1, 1);

FetcherNotificationsCounter *fnctr = [[FetcherNotificationsCounter alloc] init];

__block GTMSessionFetcher *fetcher;

NSString *timeoutFileURLString = [self localURLStringToTestFileName:kGTMGettysburgFileName
parameters:@{@"sleep" : @"10"}];
fetcher = [self fetcherWithURLString:timeoutFileURLString];
GTMSessionFetcher *fetcher = [self fetcherWithURLString:timeoutFileURLString];
fetcher.stopFetchingTriggersCompletionHandler = YES;
if (authorizer) {
fetcher.authorizer = authorizer;
}
XCTestExpectation *expectation = [self expectationWithDescription:@"Expect to call callback"];
[fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
XCTAssertNil(data, @"error data unexpected");
Expand Down Expand Up @@ -2860,7 +2897,8 @@ - (void)testFetcherRedirectURLHandling {
@end

@implementation TestAuthorizer
@synthesize async = _async, expired = _expired, willFailWithError = _willFailWithError;
@synthesize async = _async, delay = _delay, expired = _expired,
willFailWithError = _willFailWithError;

+ (instancetype)syncAuthorizer {
return [[self alloc] init];
Expand All @@ -2872,6 +2910,13 @@ + (instancetype)asyncAuthorizer {
return authorizer;
}

+ (instancetype)asyncAuthorizerDelayed:(NSUInteger)delaySeconds {
TestAuthorizer *authorizer = [self syncAuthorizer];
authorizer.async = YES;
authorizer.delay = delaySeconds;
return authorizer;
}

+ (instancetype)expiredSyncAuthorizer {
TestAuthorizer *authorizer = [self syncAuthorizer];
authorizer.expired = YES;
Expand All @@ -2897,9 +2942,17 @@ - (void)authorizeRequest:(NSMutableURLRequest *)request
}

if (self.async) {
dispatch_async(dispatch_get_main_queue(), ^{
handler(error);
});
if (self.delay) {
dispatch_time_t delay_time =
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.delay * NSEC_PER_SEC));
dispatch_after(delay_time, dispatch_get_main_queue(), ^{
handler(error);
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
handler(error);
});
}
} else {
handler(error);
}
Expand Down
Loading

0 comments on commit e18fe7c

Please sign in to comment.