| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- // Copyright 2018 Google
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #import "FIRTestCase.h"
- #import <FirebaseCore/FIRReachabilityChecker+Internal.h>
- #import <FirebaseCore/FIRReachabilityChecker.h>
- @interface FIRReachabilityCheckerTest : FIRTestCase <FIRReachabilityDelegate> {
- @private
- FIRReachabilityChecker *checker_;
- NSMutableArray *statuses_;
- BOOL createFail_;
- BOOL setCallbackFail_;
- BOOL scheduleUnscheduleFail_;
- }
- - (void *)createReachabilityWithAllocator:(CFAllocatorRef)allocator withName:(const char *)hostname;
- - (BOOL)reachability:(const void *)reachability
- setCallback:(SCNetworkReachabilityCallBack)callback
- withContext:(SCNetworkReachabilityContext *)context;
- - (BOOL)scheduleReachability:(const void *)reachability
- runLoop:(CFRunLoopRef)runLoop
- runLoopMode:(CFStringRef)runLoopMode;
- - (BOOL)unscheduleReachability:(const void *)reachability
- runLoop:(CFRunLoopRef)runLoop
- runLoopMode:(CFStringRef)runLoopMode;
- - (void)releaseReachability:(const void *)reachability;
- @end
- static NSString *const kHostname = @"www.google.com";
- static const void *kFakeReachabilityObject = (const void *)0x8badf00d;
- static FIRReachabilityCheckerTest *FakeReachabilityTest = nil;
- static struct {
- int callsMade;
- int createCall;
- int setCallbackCall;
- int scheduleCall;
- int unscheduleCall;
- int releaseCall;
- void (*callback)(SCNetworkReachabilityRef, SCNetworkReachabilityFlags, void *info);
- void *callbackInfo;
- } FakeReachability;
- static SCNetworkReachabilityRef ReachabilityCreateWithName(CFAllocatorRef allocator,
- const char *hostname) {
- return (SCNetworkReachabilityRef)
- [FakeReachabilityTest createReachabilityWithAllocator:allocator withName:hostname];
- }
- static Boolean ReachabilitySetCallback(SCNetworkReachabilityRef reachability,
- SCNetworkReachabilityCallBack callback,
- SCNetworkReachabilityContext *context) {
- return [FakeReachabilityTest reachability:reachability setCallback:callback withContext:context];
- }
- static Boolean ReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef reachability,
- CFRunLoopRef runLoop,
- CFStringRef runLoopMode) {
- return [FakeReachabilityTest scheduleReachability:reachability
- runLoop:runLoop
- runLoopMode:runLoopMode];
- }
- static Boolean ReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef reachability,
- CFRunLoopRef runLoop,
- CFStringRef runLoopMode) {
- return [FakeReachabilityTest unscheduleReachability:reachability
- runLoop:runLoop
- runLoopMode:runLoopMode];
- }
- static void ReachabilityRelease(CFTypeRef reachability) {
- [FakeReachabilityTest releaseReachability:reachability];
- }
- static const struct FIRReachabilityApi kTestReachabilityApi = {
- ReachabilityCreateWithName, ReachabilitySetCallback, ReachabilityScheduleWithRunLoop,
- ReachabilityUnscheduleFromRunLoop, ReachabilityRelease,
- };
- @implementation FIRReachabilityCheckerTest
- - (void)resetFakeReachability {
- FakeReachabilityTest = self;
- FakeReachability.callsMade = 0;
- FakeReachability.createCall = -1;
- FakeReachability.setCallbackCall = -1;
- FakeReachability.scheduleCall = -1;
- FakeReachability.unscheduleCall = -1;
- FakeReachability.releaseCall = -1;
- FakeReachability.callback = NULL;
- FakeReachability.callbackInfo = NULL;
- }
- - (void)setUp {
- [super setUp];
- [self resetFakeReachability];
- createFail_ = NO;
- setCallbackFail_ = NO;
- scheduleUnscheduleFail_ = NO;
- checker_ = [[FIRReachabilityChecker alloc] initWithReachabilityDelegate:self
- loggerDelegate:nil
- withHost:kHostname];
- statuses_ = [[NSMutableArray alloc] init];
- }
- - (void *)createReachabilityWithAllocator:(CFAllocatorRef)allocator
- withName:(const char *)hostname {
- XCTAssertTrue(allocator == kCFAllocatorDefault, @"");
- XCTAssertEqual(strcmp(hostname, [kHostname UTF8String]), 0, @"");
- XCTAssertEqual(FakeReachability.callsMade, 0, @"create call must always come first.");
- XCTAssertEqual(FakeReachability.createCall, -1, @"create call must only be called once.");
- FakeReachability.createCall = ++FakeReachability.callsMade;
- return createFail_ ? NULL : (void *)kFakeReachabilityObject;
- }
- - (BOOL)reachability:(const void *)reachability
- setCallback:(SCNetworkReachabilityCallBack)callback
- withContext:(SCNetworkReachabilityContext *)context {
- XCTAssertEqual(reachability, kFakeReachabilityObject, @"got bad object");
- XCTAssertEqual((int)context->version, 0, @"");
- XCTAssertEqual(context->info, (__bridge void *)checker_, @"");
- XCTAssertEqual((void *)context->retain, NULL, @"");
- XCTAssertEqual((void *)context->release, NULL, @"");
- XCTAssertEqual((void *)context->copyDescription, NULL, @"");
- XCTAssertEqual(FakeReachability.setCallbackCall, -1, @"setCallback should only be called once.");
- FakeReachability.setCallbackCall = ++FakeReachability.callsMade;
- XCTAssertTrue(callback != NULL, @"");
- FakeReachability.callback = callback;
- XCTAssertTrue(context->info != NULL, @"");
- FakeReachability.callbackInfo = context->info;
- return setCallbackFail_ ? NO : YES;
- }
- - (BOOL)scheduleReachability:(const void *)reachability
- runLoop:(CFRunLoopRef)runLoop
- runLoopMode:(CFStringRef)runLoopMode {
- XCTAssertEqual(reachability, kFakeReachabilityObject, @"got bad object");
- XCTAssertEqual(runLoop, CFRunLoopGetMain(), @"bad run loop");
- XCTAssertEqualObjects((__bridge NSString *)runLoopMode,
- (__bridge NSString *)kCFRunLoopCommonModes, @"bad run loop mode");
- XCTAssertEqual(FakeReachability.scheduleCall, -1,
- @"scheduleWithRunLoop should only be called once.");
- FakeReachability.scheduleCall = ++FakeReachability.callsMade;
- return scheduleUnscheduleFail_ ? NO : YES;
- }
- - (BOOL)unscheduleReachability:(const void *)reachability
- runLoop:(CFRunLoopRef)runLoop
- runLoopMode:(CFStringRef)runLoopMode {
- XCTAssertEqual(reachability, kFakeReachabilityObject, @"got bad object");
- XCTAssertEqual(runLoop, CFRunLoopGetMain(), @"bad run loop");
- XCTAssertEqualObjects((__bridge NSString *)runLoopMode,
- (__bridge NSString *)kCFRunLoopCommonModes, @"bad run loop mode");
- XCTAssertEqual(FakeReachability.unscheduleCall, -1,
- @"unscheduleFromRunLoop should only be called once.");
- FakeReachability.unscheduleCall = ++FakeReachability.callsMade;
- return scheduleUnscheduleFail_ ? NO : YES;
- }
- - (void)releaseReachability:(const void *)reachability {
- XCTAssertEqual(reachability, kFakeReachabilityObject, @"got bad object");
- XCTAssertEqual(FakeReachability.releaseCall, -1, @"release should only be called once.");
- FakeReachability.releaseCall = ++FakeReachability.callsMade;
- }
- - (void)reachability:(FIRReachabilityChecker *)reachability
- statusChanged:(FIRReachabilityStatus)status {
- [statuses_ addObject:[NSNumber numberWithInt:(int)status]];
- }
- #pragma mark - Test
- - (void)testApiHappyPath {
- [checker_ setReachabilityApi:&kTestReachabilityApi];
- XCTAssertEqual([checker_ reachabilityApi], &kTestReachabilityApi, @"");
- XCTAssertFalse(checker_.isActive, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- XCTAssertTrue([checker_ start], @"");
- XCTAssertTrue(checker_.isActive, @"");
- XCTAssertEqual([statuses_ count], (NSUInteger)0, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- FakeReachability.callback(kFakeReachabilityObject, 0, FakeReachability.callbackInfo);
- XCTAssertEqual([statuses_ count], (NSUInteger)1, @"");
- XCTAssertEqual([(NSNumber *)[statuses_ objectAtIndex:0] intValue],
- (int)kFIRReachabilityNotReachable, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityNotReachable, @"");
- FakeReachability.callback(kFakeReachabilityObject, kSCNetworkReachabilityFlagsReachable,
- FakeReachability.callbackInfo);
- XCTAssertEqual([statuses_ count], (NSUInteger)2, @"");
- XCTAssertEqual([(NSNumber *)[statuses_ objectAtIndex:1] intValue], (int)kFIRReachabilityViaWifi,
- @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityViaWifi, @"");
- FakeReachability.callback(
- kFakeReachabilityObject,
- kSCNetworkReachabilityFlagsReachable | kSCNetworkReachabilityFlagsConnectionRequired,
- FakeReachability.callbackInfo);
- XCTAssertEqual([statuses_ count], (NSUInteger)3, @"");
- XCTAssertEqual([(NSNumber *)[statuses_ objectAtIndex:2] intValue],
- (int)kFIRReachabilityNotReachable, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityNotReachable, @"");
- #if TARGET_OS_IOS || TARGET_OS_TV
- FakeReachability.callback(
- kFakeReachabilityObject,
- kSCNetworkReachabilityFlagsReachable | kSCNetworkReachabilityFlagsIsWWAN,
- FakeReachability.callbackInfo);
- XCTAssertEqual([statuses_ count], (NSUInteger)4, @"");
- XCTAssertEqual([(NSNumber *)[statuses_ objectAtIndex:3] intValue],
- (int)kFIRReachabilityViaCellular, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityViaCellular, @"");
- FakeReachability.callback(kFakeReachabilityObject, kSCNetworkReachabilityFlagsIsWWAN,
- FakeReachability.callbackInfo);
- XCTAssertEqual([statuses_ count], (NSUInteger)5, @"");
- XCTAssertEqual([(NSNumber *)[statuses_ objectAtIndex:4] intValue],
- (int)kFIRReachabilityNotReachable, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityNotReachable, @"");
- #endif
- [checker_ stop];
- XCTAssertFalse(checker_.isActive, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- XCTAssertEqual(FakeReachability.callsMade, 5, @"");
- XCTAssertEqual(FakeReachability.createCall, 1, @"");
- XCTAssertEqual(FakeReachability.setCallbackCall, 2, @"");
- XCTAssertEqual(FakeReachability.scheduleCall, 3, @"");
- XCTAssertEqual(FakeReachability.unscheduleCall, 4, @"");
- XCTAssertEqual(FakeReachability.releaseCall, 5, @"");
- }
- - (void)testApiCreateFail {
- [checker_ setReachabilityApi:&kTestReachabilityApi];
- XCTAssertEqual([checker_ reachabilityApi], &kTestReachabilityApi, @"");
- createFail_ = YES;
- XCTAssertFalse(checker_.isActive, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- XCTAssertFalse([checker_ start], @"");
- XCTAssertFalse(checker_.isActive, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- [checker_ stop];
- XCTAssertFalse(checker_.isActive, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- XCTAssertEqual(FakeReachability.callsMade, 1, @"");
- XCTAssertEqual(FakeReachability.createCall, 1, @"");
- XCTAssertEqual(FakeReachability.setCallbackCall, -1, @"");
- XCTAssertEqual(FakeReachability.scheduleCall, -1, @"");
- XCTAssertEqual(FakeReachability.unscheduleCall, -1, @"");
- XCTAssertEqual(FakeReachability.releaseCall, -1, @"");
- XCTAssertEqual([statuses_ count], (NSUInteger)0, @"");
- }
- - (void)testApiCallbackFail {
- [checker_ setReachabilityApi:&kTestReachabilityApi];
- XCTAssertEqual([checker_ reachabilityApi], &kTestReachabilityApi, @"");
- setCallbackFail_ = YES;
- XCTAssertFalse(checker_.isActive, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- XCTAssertFalse([checker_ start], @"");
- XCTAssertFalse(checker_.isActive, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- [checker_ stop];
- XCTAssertFalse(checker_.isActive, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- XCTAssertEqual(FakeReachability.callsMade, 3, @"");
- XCTAssertEqual(FakeReachability.createCall, 1, @"");
- XCTAssertEqual(FakeReachability.setCallbackCall, 2, @"");
- XCTAssertEqual(FakeReachability.scheduleCall, -1, @"");
- XCTAssertEqual(FakeReachability.unscheduleCall, -1, @"");
- XCTAssertEqual(FakeReachability.releaseCall, 3, @"");
- XCTAssertEqual([statuses_ count], (NSUInteger)0, @"");
- }
- - (void)testApiScheduleFail {
- [checker_ setReachabilityApi:&kTestReachabilityApi];
- XCTAssertEqual([checker_ reachabilityApi], &kTestReachabilityApi, @"");
- scheduleUnscheduleFail_ = YES;
- XCTAssertFalse(checker_.isActive, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- XCTAssertFalse([checker_ start], @"");
- XCTAssertFalse(checker_.isActive, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- [checker_ stop];
- XCTAssertFalse(checker_.isActive, @"");
- XCTAssertEqual(checker_.reachabilityStatus, kFIRReachabilityUnknown, @"");
- XCTAssertEqual(FakeReachability.callsMade, 4, @"");
- XCTAssertEqual(FakeReachability.createCall, 1, @"");
- XCTAssertEqual(FakeReachability.setCallbackCall, 2, @"");
- XCTAssertEqual(FakeReachability.scheduleCall, 3, @"");
- XCTAssertEqual(FakeReachability.unscheduleCall, -1, @"");
- XCTAssertEqual(FakeReachability.releaseCall, 4, @"");
- XCTAssertEqual([statuses_ count], (NSUInteger)0, @"");
- }
- - (void)testBadHost {
- XCTAssertNil([[FIRReachabilityChecker alloc]
- initWithReachabilityDelegate:self
- loggerDelegate:(id<FIRNetworkLoggerDelegate>)self
- withHost:nil],
- @"Creating a checker with nil hostname must fail.");
- XCTAssertNil([[FIRReachabilityChecker alloc]
- initWithReachabilityDelegate:self
- loggerDelegate:(id<FIRNetworkLoggerDelegate>)self
- withHost:@""],
- @"Creating a checker with empty hostname must fail.");
- }
- @end
|