Skip to content

Add a unit test to verify behavior w/ URLSession:dataTask:didReceiveResponse:completionHandler: #14489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 22 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruby-2.7
2.7.4
Original file line number Diff line number Diff line change
@@ -33,6 +33,12 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)registerObject:(id)object;

/** Registers an instance of the delegate class to be instrumented.
*
* @param proxy The instance to instrument.
*/
- (void)registerProxy:(id)proxy;

@end

/** This class allows the instrumentation of specific objects by isa swizzling specific instances
11 changes: 11 additions & 0 deletions FirebasePerformance/Sources/Instrumentation/FPRProxyObjectHelper.h
Original file line number Diff line number Diff line change
@@ -31,4 +31,15 @@
forSuperclass:(Class)superclass
varFoundHandler:(void (^)(id ivar))varFoundHandler;

/** Registers a proxy object for a given class and runs the onSuccess block whenever an ivar of the
* given class is discovered on the proxy object.
*
* @param proxy The proxy object whose ivars will be iterated.
* @param protocol The protocol all ivars will be compared against. See varFoundHandler.
* @param varFoundHandler The block to run when an ivar conformsToProtocol:protocol.
*/
+ (void)registerProxyObject:(id)proxy
forProtocol:(Protocol *)protocol
varFoundHandler:(void (^)(id ivar))varFoundHandler;

@end
11 changes: 11 additions & 0 deletions FirebasePerformance/Sources/Instrumentation/FPRProxyObjectHelper.m
Original file line number Diff line number Diff line change
@@ -29,4 +29,15 @@ + (void)registerProxyObject:(id)proxy
}
}

+ (void)registerProxyObject:(id)proxy
forProtocol:(Protocol *)protocol
varFoundHandler:(void (^)(id ivar))varFoundHandler {
NSArray<id> *ivars = [GULSwizzler ivarObjectsForObject:proxy];
for (id ivar in ivars) {
if ([ivar conformsToProtocol:protocol]) {
varFoundHandler(ivar);
}
}
}

@end
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
#import "FirebasePerformance/Sources/Instrumentation/FPRClassInstrumentor.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRInstrument_Private.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRProxyObjectHelper.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRSelectorInstrumentor.h"
#import "FirebasePerformance/Sources/Instrumentation/Network/Delegates/FPRNSURLConnectionDelegate.h"
#import "FirebasePerformance/Sources/Instrumentation/Network/FPRNetworkInstrumentHelpers.h"
@@ -304,4 +305,13 @@ - (void)registerObject:(id)object {
});
}

- (void)registerProxy:(id)proxy {
[FPRProxyObjectHelper registerProxyObject:proxy
forProtocol:@protocol(NSURLSessionDelegate)
varFoundHandler:^(id ivar) {
[self registerClass:[ivar class]];
[self registerObject:ivar];
}];
}

@end
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
#import "FirebasePerformance/Sources/Instrumentation/FPRClassInstrumentor.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRInstrument_Private.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRProxyObjectHelper.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRSelectorInstrumentor.h"
#import "FirebasePerformance/Sources/Instrumentation/Network/Delegates/FPRNSURLSessionDelegate.h"
#import "FirebasePerformance/Sources/Instrumentation/Network/FPRNetworkInstrumentHelpers.h"
@@ -263,4 +264,13 @@ - (void)registerObject:(id)object {
});
}

- (void)registerProxy:(id)proxy {
[FPRProxyObjectHelper registerProxyObject:proxy
forProtocol:@protocol(NSURLSessionDelegate)
varFoundHandler:^(id ivar) {
[self registerClass:[ivar class]];
[self registerObject:ivar];
}];
}

@end
Original file line number Diff line number Diff line change
@@ -157,9 +157,12 @@ void InstrumentSessionWithConfigurationDelegateDelegateQueue(
ThrowExceptionBecauseInstrumentHasBeenDeallocated(selector, instrumentedClass);
}
if (delegate) {
[delegateInstrument registerClass:[delegate class]];
[delegateInstrument registerObject:delegate];

if ([delegate isProxy]) {
[delegateInstrument registerProxy:delegate];
} else {
[delegateInstrument registerClass:[delegate class]];
[delegateInstrument registerObject:delegate];
}
} else {
delegate = [[FPRNSURLSessionDelegate alloc] init];
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -52,6 +52,12 @@ NS_ASSUME_NONNULL_BEGIN
/** Set to YES when URLSession:dataTask:didReceiveData: is called, used for testing. */
@property(nonatomic) BOOL URLSessionDataTaskDidReceiveDataCalled;

/** Set to YES when
* URLSession:dataTask:didReceiveResponse:completionHandler: is called, used
* for testing.
*/
@property(nonatomic) BOOL URLSessionDataTaskDidReceiveResponseCompletionHandlerCalled;

/** Set to YES when URLSession:downloadTask:didFinishDownloadingToURL: is called, used for testing.
*/
@property(nonatomic) BOOL URLSessionDownloadTaskDidFinishDownloadingToURLCalled;
Original file line number Diff line number Diff line change
@@ -72,6 +72,14 @@ - (void)URLSession:(NSURLSession *)session
self.URLSessionDataTaskDidReceiveDataCalled = YES;
}

- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
self.URLSessionDataTaskDidReceiveResponseCompletionHandlerCalled = YES;
completionHandler(NSURLSessionResponseAllow);
}

#pragma mark - NSURLSessionDownloadDelegate methods

- (void)URLSession:(NSURLSession *)session

Unchanged files with check annotations Beta

@end
@implementation ScreenTracesViewController

Check warning on line 22 in FirebasePerformance/Tests/TestApp/Source/ViewControllers/ScreenTracesViewController.m

GitHub Actions / performance (iOS, proddev)

method override for the designated initializer of the superclass '-initWithStyle:' not found [-Wobjc-designated-initializers]

Check warning on line 22 in FirebasePerformance/Tests/TestApp/Source/ViewControllers/ScreenTracesViewController.m

GitHub Actions / performance (tvOS, proddev)

method override for the designated initializer of the superclass '-initWithStyle:' not found [-Wobjc-designated-initializers]
- (instancetype)init {
NSAssert(NO, @"Not a valid initializer.");
#import <Foundation/Foundation.h>
typedef void (^SuccessNetworkCallback)();

Check warning on line 17 in FirebasePerformance/Tests/TestApp/Source/Networking/NetworkConnection.h

GitHub Actions / performance (iOS, proddev)

a block declaration without a prototype is deprecated [-Wstrict-prototypes]

Check warning on line 17 in FirebasePerformance/Tests/TestApp/Source/Networking/NetworkConnection.h

GitHub Actions / performance (iOS, proddev)

a block declaration without a prototype is deprecated [-Wstrict-prototypes]

Check warning on line 17 in FirebasePerformance/Tests/TestApp/Source/Networking/NetworkConnection.h

GitHub Actions / performance (iOS, proddev)

a block declaration without a prototype is deprecated [-Wstrict-prototypes]

Check warning on line 17 in FirebasePerformance/Tests/TestApp/Source/Networking/NetworkConnection.h

GitHub Actions / performance (iOS, proddev)

a block declaration without a prototype is deprecated [-Wstrict-prototypes]

Check warning on line 17 in FirebasePerformance/Tests/TestApp/Source/Networking/NetworkConnection.h

GitHub Actions / performance (iOS, proddev)

a block declaration without a prototype is deprecated [-Wstrict-prototypes]

Check warning on line 17 in FirebasePerformance/Tests/TestApp/Source/Networking/NetworkConnection.h

GitHub Actions / performance (tvOS, proddev)

a block declaration without a prototype is deprecated [-Wstrict-prototypes]

Check warning on line 17 in FirebasePerformance/Tests/TestApp/Source/Networking/NetworkConnection.h

GitHub Actions / performance (tvOS, proddev)

a block declaration without a prototype is deprecated [-Wstrict-prototypes]

Check warning on line 17 in FirebasePerformance/Tests/TestApp/Source/Networking/NetworkConnection.h

GitHub Actions / performance (tvOS, proddev)

a block declaration without a prototype is deprecated [-Wstrict-prototypes]

Check warning on line 17 in FirebasePerformance/Tests/TestApp/Source/Networking/NetworkConnection.h

GitHub Actions / performance (tvOS, proddev)

a block declaration without a prototype is deprecated [-Wstrict-prototypes]

Check warning on line 17 in FirebasePerformance/Tests/TestApp/Source/Networking/NetworkConnection.h

GitHub Actions / performance (tvOS, proddev)

a block declaration without a prototype is deprecated [-Wstrict-prototypes]
typedef void (^FailureNetworkCallback)(NSError *error);
/** A protocol for network connection tasks. */
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:self.urlString]];
self.URLConnection = [[NSURLConnection alloc] initWithRequest:request

Check warning on line 42 in FirebasePerformance/Tests/TestApp/Source/Networking/PerfURLConnectionWithDelegateStartImmediately.m

GitHub Actions / performance (iOS, proddev)

'initWithRequest:delegate:startImmediately:' is deprecated: first deprecated in iOS 9.0 - Use NSURLSession (see NSURLSession.h) [-Wdeprecated-declarations]
delegate:self
startImmediately:YES];
}
/** Tests that FPRAssert actually asserts (when NS_BLOCK_ASSERTIONS=0|undefined). */
- (void)testFPRAssert {
XCTAssertThrows(FPRAssert(NO, @"This is a failed assert!"));

Check warning on line 83 in FirebasePerformance/Tests/Unit/Common/FPRDiagnosticsTest.m

GitHub Actions / spm (macos-15, Xcode_16.2, tvOS)

'(' and '{' tokens introducing statement expression appear in different macro expansion contexts [-Wcompound-token-split-by-macro]

Check warning on line 83 in FirebasePerformance/Tests/Unit/Common/FPRDiagnosticsTest.m

GitHub Actions / spm (macos-15, Xcode_16.2, tvOS)

'}' and ')' tokens terminating statement expression appear in different macro expansion contexts [-Wcompound-token-split-by-macro]

Check warning on line 83 in FirebasePerformance/Tests/Unit/Common/FPRDiagnosticsTest.m

GitHub Actions / spm (macos-15, Xcode_16.2, iOS)

'(' and '{' tokens introducing statement expression appear in different macro expansion contexts [-Wcompound-token-split-by-macro]

Check warning on line 83 in FirebasePerformance/Tests/Unit/Common/FPRDiagnosticsTest.m

GitHub Actions / spm (macos-15, Xcode_16.2, iOS)

'}' and ')' tokens terminating statement expression appear in different macro expansion contexts [-Wcompound-token-split-by-macro]

Check warning on line 83 in FirebasePerformance/Tests/Unit/Common/FPRDiagnosticsTest.m

GitHub Actions / spm (macos-14, Xcode_15.4, iOS)

'(' and '{' tokens introducing statement expression appear in different macro expansion contexts [-Wcompound-token-split-by-macro]

Check warning on line 83 in FirebasePerformance/Tests/Unit/Common/FPRDiagnosticsTest.m

GitHub Actions / spm (macos-14, Xcode_15.4, iOS)

'}' and ')' tokens terminating statement expression appear in different macro expansion contexts [-Wcompound-token-split-by-macro]

Check warning on line 83 in FirebasePerformance/Tests/Unit/Common/FPRDiagnosticsTest.m

GitHub Actions / spm (macos-13, Xcode_15.2, iOS)

'(' and '{' tokens introducing statement expression appear in different macro expansion contexts [-Wcompound-token-split-by-macro]

Check warning on line 83 in FirebasePerformance/Tests/Unit/Common/FPRDiagnosticsTest.m

GitHub Actions / spm (macos-13, Xcode_15.2, iOS)

'}' and ')' tokens terminating statement expression appear in different macro expansion contexts [-Wcompound-token-split-by-macro]
}
/** Tests emit diagnostics methods. */
*/
- (void)testViewDidAppearInvokesViewControllerDidAppearOnScreenTraceTracker {
UIViewController *testViewController = [[UIViewController alloc] init];
[[UIApplication sharedApplication].keyWindow addSubview:[testViewController view]];

Check warning on line 62 in FirebasePerformance/Tests/Unit/Instruments/FPRUIViewControllerInstrumentTest.m

GitHub Actions / performance (tvOS, unit)

'keyWindow' is deprecated: first deprecated in tvOS 13.0 - Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes [-Wdeprecated-declarations]

Check warning on line 62 in FirebasePerformance/Tests/Unit/Instruments/FPRUIViewControllerInstrumentTest.m

GitHub Actions / performance (iOS, unit)

'keyWindow' is deprecated: first deprecated in iOS 13.0 - Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes [-Wdeprecated-declarations]
FPRUIViewControllerInstrument *instrument = [[FPRUIViewControllerInstrument alloc] init];
[instrument registerInstrumentors];
forKey:@"fpr_vc_session_sampling_rate"];
// Trigger the RC config fetch
remoteConfig.fetchStatus = FIRRemoteConfigFetchStatusSuccess;

Check warning on line 68 in FirebasePerformance/Tests/Unit/Configurations/FPRRemoteConfigFlagsTest.m

GitHub Actions / performance (tvOS, unit)

implicit conversion from enumeration type 'enum FIRRemoteConfigFetchStatus' to different enumeration type 'FIRRemoteConfigFetchAndActivateStatus' (aka 'enum FIRRemoteConfigFetchAndActivateStatus') [-Wenum-conversion]

Check warning on line 68 in FirebasePerformance/Tests/Unit/Configurations/FPRRemoteConfigFlagsTest.m

GitHub Actions / performance (iOS, unit)

implicit conversion from enumeration type 'enum FIRRemoteConfigFetchStatus' to different enumeration type 'FIRRemoteConfigFetchAndActivateStatus' (aka 'enum FIRRemoteConfigFetchAndActivateStatus') [-Wenum-conversion]
remoteConfig.lastFetchTime = nil;
configFlags.appStartConfigFetchDelayInSeconds = 0.0;
[configFlags update];
forKey:@"fpr_vc_session_sampling_rate"];
// Retrigger the RC config fetch
remoteConfig.fetchStatus = FIRRemoteConfigFetchStatusSuccess;

Check warning on line 95 in FirebasePerformance/Tests/Unit/Configurations/FPRRemoteConfigFlagsTest.m

GitHub Actions / performance (tvOS, unit)

implicit conversion from enumeration type 'enum FIRRemoteConfigFetchStatus' to different enumeration type 'FIRRemoteConfigFetchAndActivateStatus' (aka 'enum FIRRemoteConfigFetchAndActivateStatus') [-Wenum-conversion]

Check warning on line 95 in FirebasePerformance/Tests/Unit/Configurations/FPRRemoteConfigFlagsTest.m

GitHub Actions / performance (iOS, unit)

implicit conversion from enumeration type 'enum FIRRemoteConfigFetchStatus' to different enumeration type 'FIRRemoteConfigFetchAndActivateStatus' (aka 'enum FIRRemoteConfigFetchAndActivateStatus') [-Wenum-conversion]
remoteConfig.lastFetchTime = nil;
[configFlags update];
FPRRemoteConfigFlags *configFlags =
[[FPRRemoteConfigFlags alloc] initWithRemoteConfig:(FIRRemoteConfig *)remoteConfig];
remoteConfig.fetchStatus = FIRRemoteConfigFetchStatusSuccess;

Check warning on line 115 in FirebasePerformance/Tests/Unit/Configurations/FPRRemoteConfigFlagsTest.m

GitHub Actions / performance (tvOS, unit)

implicit conversion from enumeration type 'enum FIRRemoteConfigFetchStatus' to different enumeration type 'FIRRemoteConfigFetchAndActivateStatus' (aka 'enum FIRRemoteConfigFetchAndActivateStatus') [-Wenum-conversion]

Check warning on line 115 in FirebasePerformance/Tests/Unit/Configurations/FPRRemoteConfigFlagsTest.m

GitHub Actions / performance (iOS, unit)

implicit conversion from enumeration type 'enum FIRRemoteConfigFetchStatus' to different enumeration type 'FIRRemoteConfigFetchAndActivateStatus' (aka 'enum FIRRemoteConfigFetchAndActivateStatus') [-Wenum-conversion]
configFlags.appStartConfigFetchDelayInSeconds = 0.0;
[configFlags update];
XCTAssertNotNil(configFlags.lastFetchedTime);
FPRRemoteConfigFlags *configFlags =
[[FPRRemoteConfigFlags alloc] initWithRemoteConfig:(FIRRemoteConfig *)remoteConfig];
remoteConfig.fetchStatus = FIRRemoteConfigFetchStatusSuccess;

Check warning on line 182 in FirebasePerformance/Tests/Unit/Configurations/FPRRemoteConfigFlagsTest.m

GitHub Actions / performance (tvOS, unit)

implicit conversion from enumeration type 'enum FIRRemoteConfigFetchStatus' to different enumeration type 'FIRRemoteConfigFetchAndActivateStatus' (aka 'enum FIRRemoteConfigFetchAndActivateStatus') [-Wenum-conversion]
configFlags.appStartConfigFetchDelayInSeconds = 0.0;
[configFlags update];
XCTAssertNotNil(configFlags.lastFetchedTime);