Skip to content

Commit

Permalink
RUMM-1234 Fix DDNSURLSessionDelegate build error
Browse files Browse the repository at this point in the history
DDNSURLSessionDelegate is disinherited as
its inheritance cause build errors with
BUILD_LIBRARY_FOR_DISTRIBUTION
  • Loading branch information
buranmert committed Apr 6, 2021
1 parent c9a837f commit 2e68caa
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ - (void)viewDidLoad {

self.testScenario = SwiftGlobals.currentTestScenario;

self.session = [self.testScenario buildURLSession];
self.session = [self.testScenario buildNSURLSession];
assert(self.testScenario != nil);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ @implementation ObjcSendThirdPartyRequestsViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.testScenario = SwiftGlobals.currentTestScenario;
self.session = [self.testScenario buildURLSession];
self.session = [self.testScenario buildNSURLSession];
assert(self.testScenario != nil);
}

Expand Down
23 changes: 22 additions & 1 deletion Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import Foundation
import Datadog
import DatadogObjc

/// Base scenario for `URLSession` and `NSURLSession` instrumentation. It makes
/// both Swift and Objective-C tests share the same endpoints and SDK configuration.
Expand Down Expand Up @@ -83,7 +84,6 @@ class URLSessionBaseScenario: NSObject {
}
}

@objc
func buildURLSession() -> URLSession {
let delegate: DDURLSessionDelegate
if feedAdditionalFirstyPartyHosts {
Expand All @@ -103,4 +103,25 @@ class URLSessionBaseScenario: NSObject {
delegateQueue: nil
)
}

@objc
func buildNSURLSession() -> URLSession {
let delegate: DDNSURLSessionDelegate
if feedAdditionalFirstyPartyHosts {
delegate = DDNSURLSessionDelegate(
additionalFirstPartyHosts: [
customGETResourceURL.host!,
customPOSTRequest.url!.host!,
badResourceURL.host!
]
)
} else {
delegate = DDNSURLSessionDelegate()
}
return URLSession(
configuration: .default,
delegate: delegate,
delegateQueue: nil
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import Foundation
/// All requests made with the `URLSession` instrumented with this delegate will be intercepted by the SDK.
@objc
open class DDURLSessionDelegate: NSObject, URLSessionTaskDelegate {
var interceptor: URLSessionInterceptorType?
var interceptor: URLSessionInterceptorType? {
return URLSessionAutoInstrumentation.instance?.interceptor
}
let firstPartyURLsFilter: FirstPartyURLsFilter?

@objc
override public init() {
Self.datadogInitializationCheck()
firstPartyURLsFilter = nil
interceptor = URLSessionAutoInstrumentation.instance?.interceptor
}

/// Automatically tracked hosts can be customized per instance with this initializer
Expand All @@ -36,7 +37,6 @@ open class DDURLSessionDelegate: NSObject, URLSessionTaskDelegate {
// we can fix this in v2.0
Self.datadogInitializationCheck()
firstPartyURLsFilter = FirstPartyURLsFilter(hosts: additionalFirstPartyHosts)
interceptor = URLSessionAutoInstrumentation.instance?.interceptor
}

private static func datadogInitializationCheck() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,23 @@ internal class URLSessionAutoInstrumentation {
let swizzler: URLSessionSwizzler
let interceptor: URLSessionInterceptor

init?(
convenience init?(
configuration: FeaturesConfiguration.URLSessionAutoInstrumentation,
dateProvider: DateProvider,
appStateListener: AppStateListening
) {
do {
self.interceptor = URLSessionInterceptor(
self.init(
interceptor: URLSessionInterceptor(
configuration: configuration,
dateProvider: dateProvider,
appStateListener: appStateListener
)
)
}

init?(interceptor: URLSessionInterceptor) {
do {
self.interceptor = interceptor
self.swizzler = try URLSessionSwizzler()
} catch {
consolePrint(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ internal class URLSessionSwizzler {
typealias Signature = @convention(block) (URLSession, URLRequest, CompletionHandler?) -> URLSessionDataTask
swizzle(method) { previousImplementation -> Signature in
return { session, urlRequest, completionHandler -> URLSessionDataTask in
guard let interceptor = (session.delegate as? DDURLSessionDelegate)?.interceptor else {
guard session.delegate?.isKind(of: DDURLSessionDelegate.self) == true,
let interceptor = URLSessionInterceptor.shared else {
return previousImplementation(session, Self.selector, urlRequest, completionHandler)
}
let task: URLSessionDataTask
Expand Down Expand Up @@ -129,7 +130,8 @@ internal class URLSessionSwizzler {
typealias Signature = @convention(block) (URLSession, URL, CompletionHandler?) -> URLSessionDataTask
swizzle(method) { previousImplementation -> Signature in
return { session, url, completionHandler -> URLSessionDataTask in
guard let interceptor = (session.delegate as? DDURLSessionDelegate)?.interceptor else {
guard session.delegate?.isKind(of: DDURLSessionDelegate.self) == true,
let interceptor = URLSessionInterceptor.shared else {
return previousImplementation(session, Self.selector, url, completionHandler)
}
let task: URLSessionDataTask
Expand Down Expand Up @@ -183,7 +185,8 @@ internal class URLSessionSwizzler {
typealias Signature = @convention(block) (URLSession, URLRequest) -> URLSessionDataTask
swizzle(method) { previousImplementation -> Signature in
return { session, urlRequest -> URLSessionDataTask in
guard let interceptor = (session.delegate as? DDURLSessionDelegate)?.interceptor else {
guard session.delegate?.isKind(of: DDURLSessionDelegate.self) == true,
let interceptor = URLSessionInterceptor.shared else {
return previousImplementation(session, Self.selector, urlRequest)
}
let newRequest = interceptor.modify(request: urlRequest, session: session)
Expand Down Expand Up @@ -227,7 +230,8 @@ internal class URLSessionSwizzler {
typealias Signature = @convention(block) (URLSession, URL) -> URLSessionDataTask
swizzle(method) { previousImplementation -> Signature in
return { session, url -> URLSessionDataTask in
guard let interceptor = (session.delegate as? DDURLSessionDelegate)?.interceptor else {
guard session.delegate?.isKind(of: DDURLSessionDelegate.self) == true,
let interceptor = URLSessionInterceptor.shared else {
return previousImplementation(session, Self.selector, url)
}
let task = previousImplementation(session, Self.selector, url)
Expand Down
40 changes: 39 additions & 1 deletion Sources/DatadogObjc/DDURLSessionDelegate+objc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,42 @@ import Foundation
import Datadog

@objc
public class DDNSURLSessionDelegate: DDURLSessionDelegate {}
open class DDNSURLSessionDelegate: NSObject, URLSessionTaskDelegate {
let swiftDelegate: DDURLSessionDelegate

@objc
override public init() {
swiftDelegate = DDURLSessionDelegate()
}

@objc
public init(additionalFirstPartyHosts: Set<String>) {
swiftDelegate = DDURLSessionDelegate(additionalFirstPartyHosts: additionalFirstPartyHosts)
}

// swiftlint:disable:next implicitly_unwrapped_optional
override open func forwardingTarget(for aSelector: Selector!) -> Any? {
return swiftDelegate
}

// swiftlint:disable:next implicitly_unwrapped_optional
override open class func forwardingTarget(for aSelector: Selector!) -> Any? {
return DDURLSessionDelegate.self
}

override open func responds(to aSelector: Selector!) -> Bool {
return swiftDelegate.responds(to: aSelector)
}

override open class func responds(to aSelector: Selector!) -> Bool {
return DDURLSessionDelegate.responds(to: aSelector)
}

override open func isKind(of aClass: AnyClass) -> Bool {
return swiftDelegate.isKind(of: aClass)
}

override open class func isKind(of aClass: AnyClass) -> Bool {
return DDURLSessionDelegate.isKind(of: aClass)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ extension URLSession {
}
}

class URLSessionInterceptorMock: URLSessionInterceptorType {
class URLSessionInterceptorMock: URLSessionInterceptor {
static func mockAny() -> URLSessionInterceptorMock {
return URLSessionInterceptorMock(configuration: .mockAny(), handler: URLSessionInterceptionHandlerMock(), appStateListener: MockAppStateListener())
}

var modifiedRequest: URLRequest?

var onRequestModified: ((URLRequest, URLSession?) -> Void)?
Expand All @@ -25,27 +29,60 @@ class URLSessionInterceptorMock: URLSessionInterceptorType {
var tasksCompleted: [(task: URLSessionTask, error: Error?)] = []
var taskMetrics: [(task: URLSessionTask, metrics: URLSessionTaskMetrics)] = []

func modify(request: URLRequest, session: URLSession?) -> URLRequest {
override func modify(request: URLRequest, session: URLSession?) -> URLRequest {
onRequestModified?(request, session)
return modifiedRequest ?? request
}

func taskCreated(task: URLSessionTask, session: URLSession?) {
override func taskCreated(task: URLSessionTask, session: URLSession?) {
tasksCreated.append(task)
onTaskCreated?(task, session)
}

func taskCompleted(task: URLSessionTask, error: Error?) {
override func taskCompleted(task: URLSessionTask, error: Error?) {
tasksCompleted.append((task: task, error: error))
onTaskCompleted?(task, error)
}

func taskMetricsCollected(task: URLSessionTask, metrics: URLSessionTaskMetrics) {
override func taskMetricsCollected(task: URLSessionTask, metrics: URLSessionTaskMetrics) {
taskMetrics.append((task: task, metrics: metrics))
onTaskMetricsCollected?(task, metrics)
}
}

//class URLSessionInterceptorMock: URLSessionInterceptorType {
// var modifiedRequest: URLRequest?
//
// var onRequestModified: ((URLRequest, URLSession?) -> Void)?
// var onTaskCreated: ((URLSessionTask, URLSession?) -> Void)?
// var onTaskCompleted: ((URLSessionTask, Error?) -> Void)?
// var onTaskMetricsCollected: ((URLSessionTask, URLSessionTaskMetrics) -> Void)?
//
// var tasksCreated: [URLSessionTask] = []
// var tasksCompleted: [(task: URLSessionTask, error: Error?)] = []
// var taskMetrics: [(task: URLSessionTask, metrics: URLSessionTaskMetrics)] = []
//
// func modify(request: URLRequest, session: URLSession?) -> URLRequest {
// onRequestModified?(request, session)
// return modifiedRequest ?? request
// }
//
// func taskCreated(task: URLSessionTask, session: URLSession?) {
// tasksCreated.append(task)
// onTaskCreated?(task, session)
// }
//
// func taskCompleted(task: URLSessionTask, error: Error?) {
// tasksCompleted.append((task: task, error: error))
// onTaskCompleted?(task, error)
// }
//
// func taskMetricsCollected(task: URLSessionTask, metrics: URLSessionTaskMetrics) {
// taskMetrics.append((task: task, metrics: metrics))
// onTaskMetricsCollected?(task, metrics)
// }
//}

extension ResourceCompletion {
static func mockAny() -> Self {
return mockWith()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import XCTest
@testable import Datadog

private class MockAppStateListener: AppStateListening {
class MockAppStateListener: AppStateListening {
let history = AppStateHistory(
initialState: .init(isActive: true, date: .mockDecember15th2019At10AMUTC()),
finalDate: .mockDecember15th2019At10AMUTC() + 10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,21 @@ import XCTest
@testable import Datadog

class DDURLSessionDelegateTests: XCTestCase {
private let interceptor = URLSessionInterceptorMock()
private lazy var delegate: DDURLSessionDelegate = {
let delegate = DDURLSessionDelegate()
delegate.interceptor = interceptor
return delegate
}()
private let interceptor = URLSessionInterceptorMock.mockAny()
private lazy var delegate = DDURLSessionDelegate()

private var currentAutoInstrumentation: URLSessionAutoInstrumentation?
override func setUpWithError() throws {
try super.setUpWithError()
currentAutoInstrumentation = URLSessionAutoInstrumentation.instance
URLSessionAutoInstrumentation.instance = URLSessionAutoInstrumentation(interceptor: interceptor)
}

override func tearDownWithError() throws {
URLSessionAutoInstrumentation.instance = currentAutoInstrumentation
currentAutoInstrumentation = nil
try super.tearDownWithError()
}

// MARK: - Interception Flow

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import XCTest
@testable import Datadog

private class URLSessionInterceptionHandlerMock: URLSessionInterceptionHandler {
class URLSessionInterceptionHandlerMock: URLSessionInterceptionHandler {
var didNotifyInterceptionStart: ((TaskInterception) -> Void)?
var startedInterceptions: [TaskInterception] = []

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,30 @@ extension URLSessionSwizzler {
}

class URLSessionSwizzlerTests: XCTestCase {
private let interceptor = URLSessionInterceptorMock()
private let interceptor = URLSessionInterceptorMock.mockAny()
private var swizzler: URLSessionSwizzler! // swiftlint:disable:this implicitly_unwrapped_optional

private var currentAutoInstrumentation: URLSessionAutoInstrumentation?
override func setUpWithError() throws {
super.setUp()
try super.setUpWithError()
swizzler = try URLSessionSwizzler()
swizzler.swizzle()

currentAutoInstrumentation = URLSessionAutoInstrumentation.instance
URLSessionAutoInstrumentation.instance = URLSessionAutoInstrumentation(interceptor: interceptor)
}

override func tearDown() {
swizzler.unswizzle()

URLSessionAutoInstrumentation.instance = currentAutoInstrumentation
currentAutoInstrumentation = nil

super.tearDown()
}

private func interceptedSession() -> URLSession {
let delegate = DDURLSessionDelegate()
delegate.interceptor = self.interceptor
return URLSession.createServerMockURLSession(delegate: delegate)
return URLSession.createServerMockURLSession(delegate: DDURLSessionDelegate())
}

// MARK: - Interception Flow
Expand Down

0 comments on commit 2e68caa

Please sign in to comment.