diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index b3c36a1ed5..ecdbe2c0db 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -260,7 +260,6 @@ 6193DCCE251B6201009B8011 /* RUMTASScreen1ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6193DCCD251B6201009B8011 /* RUMTASScreen1ViewController.swift */; }; 6193DCE1251B692C009B8011 /* RUMTASTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6193DCE0251B692C009B8011 /* RUMTASTableViewController.swift */; }; 6193DCE8251B9AB1009B8011 /* RUMTASCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6193DCE7251B9AB1009B8011 /* RUMTASCollectionViewController.swift */; }; - 61940C7C25668EC600A20043 /* URLSessionInterceptionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61940C7B25668EC600A20043 /* URLSessionInterceptionHandler.swift */; }; 6198D27124C6E3B700493501 /* RUMViewScopeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6198D27024C6E3B700493501 /* RUMViewScopeTests.swift */; }; 619E16D82577C1CB00B2516B /* DataProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619E16D72577C1CB00B2516B /* DataProcessor.swift */; }; 619E16E92578E73E00B2516B /* DataMigrator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619E16E82578E73E00B2516B /* DataMigrator.swift */; }; @@ -804,7 +803,6 @@ 6193DCCD251B6201009B8011 /* RUMTASScreen1ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RUMTASScreen1ViewController.swift; sourceTree = ""; }; 6193DCE0251B692C009B8011 /* RUMTASTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RUMTASTableViewController.swift; sourceTree = ""; }; 6193DCE7251B9AB1009B8011 /* RUMTASCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RUMTASCollectionViewController.swift; sourceTree = ""; }; - 61940C7B25668EC600A20043 /* URLSessionInterceptionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSessionInterceptionHandler.swift; sourceTree = ""; }; 6198D27024C6E3B700493501 /* RUMViewScopeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RUMViewScopeTests.swift; sourceTree = ""; }; 619E16D72577C1CB00B2516B /* DataProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataProcessor.swift; sourceTree = ""; }; 619E16E82578E73E00B2516B /* DataMigrator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataMigrator.swift; sourceTree = ""; }; @@ -1903,7 +1901,6 @@ children = ( 613F23DC252B05BD006CD2D7 /* URLFiltering */, 618E1337252340810098C6B0 /* URLSessionInterceptor.swift */, - 61940C7B25668EC600A20043 /* URLSessionInterceptionHandler.swift */, 61417DC52525CDDE00E2D55C /* TaskInterception.swift */, ); path = Interception; @@ -3293,7 +3290,6 @@ 618715F924DC13A100FC0F69 /* RUMDataModelsMapping.swift in Sources */, 61C3638524361E9200C4D4E6 /* Globals.swift in Sources */, E1D202EA24C065CF00D1AF3A /* ActiveSpansPool.swift in Sources */, - 61940C7C25668EC600A20043 /* URLSessionInterceptionHandler.swift in Sources */, 9ED6A6B425F2901800CB2E29 /* AppStateListener.swift in Sources */, 61F3CDA3251118FB00C816E5 /* UIKitRUMViewsHandler.swift in Sources */, 61C5A88824509A0C00DA608C /* Warnings.swift in Sources */, diff --git a/Datadog/Example/Scenarios/URLSession/NSURLSessionAutoInstrumentation/ObjcSendFirstPartyRequestsViewController.m b/Datadog/Example/Scenarios/URLSession/NSURLSessionAutoInstrumentation/ObjcSendFirstPartyRequestsViewController.m index fb8dabdded..61f3024094 100644 --- a/Datadog/Example/Scenarios/URLSession/NSURLSessionAutoInstrumentation/ObjcSendFirstPartyRequestsViewController.m +++ b/Datadog/Example/Scenarios/URLSession/NSURLSessionAutoInstrumentation/ObjcSendFirstPartyRequestsViewController.m @@ -20,7 +20,7 @@ - (void)viewDidLoad { self.testScenario = SwiftGlobals.currentTestScenario; - self.session = [self.testScenario buildURLSession]; + self.session = [self.testScenario getURLSession]; assert(self.testScenario != nil); } diff --git a/Datadog/Example/Scenarios/URLSession/NSURLSessionAutoInstrumentation/ObjcSendThirdPartyRequestsViewController.m b/Datadog/Example/Scenarios/URLSession/NSURLSessionAutoInstrumentation/ObjcSendThirdPartyRequestsViewController.m index 593020271f..e5fb7ab7b2 100644 --- a/Datadog/Example/Scenarios/URLSession/NSURLSessionAutoInstrumentation/ObjcSendThirdPartyRequestsViewController.m +++ b/Datadog/Example/Scenarios/URLSession/NSURLSessionAutoInstrumentation/ObjcSendThirdPartyRequestsViewController.m @@ -18,7 +18,7 @@ @implementation ObjcSendThirdPartyRequestsViewController - (void)viewDidLoad { [super viewDidLoad]; self.testScenario = SwiftGlobals.currentTestScenario; - self.session = [self.testScenario buildURLSession]; + self.session = [self.testScenario getURLSession]; assert(self.testScenario != nil); } diff --git a/Datadog/Example/Scenarios/URLSession/URLSessionAutoInstrumentation/SendFirstPartyRequestsViewController.swift b/Datadog/Example/Scenarios/URLSession/URLSessionAutoInstrumentation/SendFirstPartyRequestsViewController.swift index c3877aab65..01ec92f79b 100644 --- a/Datadog/Example/Scenarios/URLSession/URLSessionAutoInstrumentation/SendFirstPartyRequestsViewController.swift +++ b/Datadog/Example/Scenarios/URLSession/URLSessionAutoInstrumentation/SendFirstPartyRequestsViewController.swift @@ -10,7 +10,7 @@ import Datadog internal class SendFirstPartyRequestsViewController: UIViewController { private var testScenario: URLSessionBaseScenario! - private lazy var session = testScenario.buildURLSession() + private lazy var session = testScenario.getURLSession() override func viewDidLoad() { super.viewDidLoad() diff --git a/Datadog/Example/Scenarios/URLSession/URLSessionAutoInstrumentation/SendThirdPartyRequestsViewController.swift b/Datadog/Example/Scenarios/URLSession/URLSessionAutoInstrumentation/SendThirdPartyRequestsViewController.swift index 9085f9b5d0..2af51e9201 100644 --- a/Datadog/Example/Scenarios/URLSession/URLSessionAutoInstrumentation/SendThirdPartyRequestsViewController.swift +++ b/Datadog/Example/Scenarios/URLSession/URLSessionAutoInstrumentation/SendThirdPartyRequestsViewController.swift @@ -10,7 +10,7 @@ import Datadog internal class SendThirdPartyRequestsViewController: UIViewController { private var testScenario: URLSessionBaseScenario! - private lazy var session = testScenario.buildURLSession() + private lazy var session = testScenario.getURLSession() override func viewDidLoad() { super.viewDidLoad() diff --git a/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift b/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift index b1c13de8ff..17f457017f 100644 --- a/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift +++ b/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift @@ -14,9 +14,13 @@ import Datadog /// calls third party endpoints. @objc class URLSessionBaseScenario: NSObject { - /// If yes, instrumented endpoints are passed to `DDURLSessionDelegate`; otherwise, they are passed to `DatadogConfiguration.trackURLSession` method - @objc - let feedAdditionalFirstyPartyHosts: Bool + /// Randomizes the way of passing additional first party hosts. + /// If `true`, instrumented endpoints are passed to `DDURLSessionDelegate`; otherwise, they are passed to `DatadogConfiguration.trackURLSession(...)`. + private let feedAdditionalFirstyPartyHosts: Bool + + /// Randomizes the way of creating `URLSession` instrumented with `DDURLSessionDelegate`. + /// If `true`, the session is created after `Datadog.initialize()`; if `false`, it's created before. + private let lazyInitURLSession: Bool /// The URL to custom GET resource, observed by Tracing auto instrumentation. @objc @@ -38,8 +42,13 @@ class URLSessionBaseScenario: NSObject { @objc let thirdPartyURL: URL + /// Randomized value determining if the `DDURLSessionDelegate` should be initialized before (`false)` or after `Datadog.initialize()` (`true`). + private var ddURLSessionDelegate: DDURLSessionDelegate? + override init() { - feedAdditionalFirstyPartyHosts = Bool.random() + feedAdditionalFirstyPartyHosts = .random() + lazyInitURLSession = .random() + if ProcessInfo.processInfo.arguments.contains("IS_RUNNING_UI_TESTS") { let serverMockConfiguration = Environment.serverMockConfiguration()! customGETResourceURL = serverMockConfiguration.instrumentedEndpoints[0] @@ -71,6 +80,13 @@ class URLSessionBaseScenario: NSObject { return request }() } + super.init() + + if lazyInitURLSession { + self.session = nil // it will be created on lazily, on first access from VC + } else { + self.session = createInstrumentedURLSession() + } } func configureSDK(builder: Datadog.Configuration.Builder) { @@ -83,8 +99,18 @@ class URLSessionBaseScenario: NSObject { } } + private var session: URLSession! + @objc - func buildURLSession() -> URLSession { + func getURLSession() -> URLSession { + if session == nil { + precondition(lazyInitURLSession, "The session is unavailable, but it is not configured for lazy init") + session = createInstrumentedURLSession() + } + return session + } + + private func createInstrumentedURLSession() -> URLSession { let delegate: DDURLSessionDelegate if feedAdditionalFirstyPartyHosts { delegate = DDURLSessionDelegate( diff --git a/Sources/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegate.swift b/Sources/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegate.swift index 8170df3990..5cd529cbbf 100644 --- a/Sources/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegate.swift +++ b/Sources/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegate.swift @@ -28,44 +28,22 @@ open class DDURLSessionDelegate: NSObject, URLSessionTaskDelegate, URLSessionDat return self } - var interceptor: URLSessionInterceptorType? + var interceptor: URLSessionInterceptorType? { 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 /// - Parameter additionalFirstPartyHosts: these hosts are tracked **in addition to** what was /// passed to `DatadogConfiguration.Builder` via `trackURLSession(firstPartyHosts:)` + /// /// **NOTE:** If `trackURLSession(firstPartyHosts:)` is never called, automatic tracking will **not** take place @objc public init(additionalFirstPartyHosts: Set) { - // NOTE: RUMM-954 copy&pasting `init()` is a conscious decision. - // otherwise `DDURLSessionDelegateAsSuperclassTests` fails. - // if `init()` was made convenience and call the designated `init` below, - // that would result in potential breaking changes. - // host projects would need to change their `init()`s in subclasses. - // we can fix this in v2.0 - Self.datadogInitializationCheck() firstPartyURLsFilter = FirstPartyURLsFilter(hosts: additionalFirstPartyHosts) - interceptor = URLSessionAutoInstrumentation.instance?.interceptor - } - - private static func datadogInitializationCheck() { - if URLSessionAutoInstrumentation.instance?.interceptor == nil { - let error = ProgrammerError( - description: """ - `Datadog.initialize()` must be called before initializing the `DDURLSessionDelegate` and - first party hosts must be specified in `Datadog.Configuration`: `trackURLSession(firstPartyHosts:)` - to enable network requests tracking. - """ - ) - consolePrint("\(error)") - } } open func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) { diff --git a/Sources/Datadog/URLSessionAutoInstrumentation/Interception/URLSessionInterceptionHandler.swift b/Sources/Datadog/URLSessionAutoInstrumentation/Interception/URLSessionInterceptionHandler.swift deleted file mode 100644 index 6f74799409..0000000000 --- a/Sources/Datadog/URLSessionAutoInstrumentation/Interception/URLSessionInterceptionHandler.swift +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. - * This product includes software developed at Datadog (https://www.datadoghq.com/). - * Copyright 2019-2020 Datadog, Inc. - */ - -import Foundation - -/// An interface for handling `URLSession` interceptions. -internal protocol URLSessionInterceptionHandler { - /// Notifies the `URLSessionTask` interception start. - func notify_taskInterceptionStarted(interception: TaskInterception) - /// Notifies the `URLSessionTask` interception completion. - func notify_taskInterceptionCompleted(interception: TaskInterception) -} diff --git a/Sources/Datadog/URLSessionAutoInstrumentation/Interception/URLSessionInterceptor.swift b/Sources/Datadog/URLSessionAutoInstrumentation/Interception/URLSessionInterceptor.swift index 7f94d334c9..c99786d49c 100644 --- a/Sources/Datadog/URLSessionAutoInstrumentation/Interception/URLSessionInterceptor.swift +++ b/Sources/Datadog/URLSessionAutoInstrumentation/Interception/URLSessionInterceptor.swift @@ -6,18 +6,29 @@ import Foundation +/// An interface for handling `URLSession` interceptions start and completion. +internal protocol URLSessionInterceptionHandler { + /// Notifies the `URLSessionTask` interception start. + func notify_taskInterceptionStarted(interception: TaskInterception) + /// Notifies the `URLSessionTask` interception completion. + func notify_taskInterceptionCompleted(interception: TaskInterception) +} + +/// An interface for processing `URLSession` task interceptions. internal protocol URLSessionInterceptorType: class { func modify(request: URLRequest, session: URLSession?) -> URLRequest func taskCreated(task: URLSessionTask, session: URLSession?) func taskMetricsCollected(task: URLSessionTask, metrics: URLSessionTaskMetrics) func taskReceivedData(task: URLSessionTask, data: Data) func taskCompleted(task: URLSessionTask, error: Error?) + + var handler: URLSessionInterceptionHandler { get } } /// An object performing interception of requests sent with `URLSession`. public class URLSessionInterceptor: URLSessionInterceptorType { public static var shared: URLSessionInterceptor? { - URLSessionAutoInstrumentation.instance?.interceptor + URLSessionAutoInstrumentation.instance?.interceptor as? URLSessionInterceptor } /// Filters first party `URLs` defined by the user. diff --git a/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionAutoInstrumentation.swift b/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionAutoInstrumentation.swift index dbb44d7e45..0ff3c6218a 100644 --- a/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionAutoInstrumentation.swift +++ b/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionAutoInstrumentation.swift @@ -11,20 +11,22 @@ internal class URLSessionAutoInstrumentation { static var instance: URLSessionAutoInstrumentation? let swizzler: URLSessionSwizzler - let interceptor: URLSessionInterceptor + let interceptor: URLSessionInterceptorType - init?( + convenience init?( configuration: FeaturesConfiguration.URLSessionAutoInstrumentation, dateProvider: DateProvider, appStateListener: AppStateListening ) { do { - self.interceptor = URLSessionInterceptor( - configuration: configuration, - dateProvider: dateProvider, - appStateListener: appStateListener + self.init( + swizzler: try URLSessionSwizzler(), + interceptor: URLSessionInterceptor( + configuration: configuration, + dateProvider: dateProvider, + appStateListener: appStateListener + ) ) - self.swizzler = try URLSessionSwizzler() } catch { consolePrint( "🔥 Datadog SDK error: automatic tracking of `URLSession` requests can't be set up due to error: \(error)" @@ -33,6 +35,11 @@ internal class URLSessionAutoInstrumentation { } } + init(swizzler: URLSessionSwizzler, interceptor: URLSessionInterceptorType) { + self.swizzler = swizzler + self.interceptor = interceptor + } + func enable() { swizzler.swizzle() } diff --git a/Tests/DatadogTests/Datadog/Mocks/URLSessionAutoInstrumentationMocks.swift b/Tests/DatadogTests/Datadog/Mocks/URLSessionAutoInstrumentationMocks.swift index 97e20c1860..892baf1734 100644 --- a/Tests/DatadogTests/Datadog/Mocks/URLSessionAutoInstrumentationMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/URLSessionAutoInstrumentationMocks.swift @@ -55,6 +55,26 @@ class URLSessionInterceptorMock: URLSessionInterceptorType { taskMetrics.append((task: task, metrics: metrics)) onTaskMetricsCollected?(task, metrics) } + + let handler: URLSessionInterceptionHandler = URLSessionInterceptionHandlerMock() +} + +class URLSessionInterceptionHandlerMock: URLSessionInterceptionHandler { + var didNotifyInterceptionStart: ((TaskInterception) -> Void)? + var startedInterceptions: [TaskInterception] = [] + + func notify_taskInterceptionStarted(interception: TaskInterception) { + startedInterceptions.append(interception) + didNotifyInterceptionStart?(interception) + } + + var didNotifyInterceptionCompletion: ((TaskInterception) -> Void)? + var completedInterceptions: [TaskInterception] = [] + + func notify_taskInterceptionCompleted(interception: TaskInterception) { + completedInterceptions.append(interception) + didNotifyInterceptionCompletion?(interception) + } } extension ResourceCompletion { diff --git a/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegateTests.swift b/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegateTests.swift index e484c1b81e..1723dab0c6 100644 --- a/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegateTests.swift +++ b/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegateTests.swift @@ -9,11 +9,20 @@ import XCTest class DDURLSessionDelegateTests: XCTestCase { private let interceptor = URLSessionInterceptorMock() - private lazy var delegate: DDURLSessionDelegate = { - let delegate = DDURLSessionDelegate() - delegate.interceptor = interceptor - return delegate - }() + private let delegate = DDURLSessionDelegate() + + override func setUpWithError() throws { + try super.setUpWithError() + URLSessionAutoInstrumentation.instance = .init( + swizzler: try URLSessionSwizzler(), + interceptor: interceptor + ) + } + + override func tearDown() { + URLSessionAutoInstrumentation.instance = nil + super.tearDown() + } // MARK: - Interception Flow @@ -158,90 +167,4 @@ class DDURLSessionDelegateTests: XCTestCase { XCTAssertTrue(interceptor.tasksReceivedData[1].task === taskWithURLRequest) XCTAssertEqual(interceptor.tasksReceivedData[1].data, randomData) } - - // MARK: - Usage errors - - func testGivenAutoInstrumentationInstanceIsNil_whenInitializingDDURLSessionDelegate_itPrintsError() { - let printFunction = PrintFunctionMock() - let previousConsolePrint = consolePrint - consolePrint = printFunction.print - defer { consolePrint = previousConsolePrint } - - // given - URLSessionAutoInstrumentation.instance = nil - - // when - _ = DDURLSessionDelegate() - - // then - XCTAssertEqual( - printFunction.printedMessage, - """ - 🔥 Datadog SDK usage error: `Datadog.initialize()` must be called before initializing the `DDURLSessionDelegate` and - first party hosts must be specified in `Datadog.Configuration`: `trackURLSession(firstPartyHosts:)` - to enable network requests tracking. - """ - ) - } - - func testGivenAutoInstrumentationInstanceIsNil_whenInitializingDDURLSessionDelegateWithCustomFirstPartyHosts_itPrintsError() { - let printFunction = PrintFunctionMock() - let previousConsolePrint = consolePrint - consolePrint = printFunction.print - defer { consolePrint = previousConsolePrint } - - // given - URLSessionAutoInstrumentation.instance = nil - - // when - _ = DDURLSessionDelegate(additionalFirstPartyHosts: ["foo.com"]) - - // then - XCTAssertEqual( - printFunction.printedMessage, - """ - 🔥 Datadog SDK usage error: `Datadog.initialize()` must be called before initializing the `DDURLSessionDelegate` and - first party hosts must be specified in `Datadog.Configuration`: `trackURLSession(firstPartyHosts:)` - to enable network requests tracking. - """ - ) - } - - func testWhenDDURLSessionDelegateInits_itPicksCorrectInterceptor() { - // given - URLSessionAutoInstrumentation.instance = URLSessionAutoInstrumentation( - configuration: .mockAny(), - dateProvider: SystemDateProvider(), - appStateListener: AppStateListener.mockAny() - ) - defer { URLSessionAutoInstrumentation.instance = nil } - - // when - let testDelegate = DDURLSessionDelegate() - - // then - XCTAssert( - testDelegate.interceptor === URLSessionAutoInstrumentation.instance?.interceptor, - "\(String(describing: testDelegate.interceptor)) must be identical to \(String(describing: URLSessionAutoInstrumentation.instance?.interceptor))" - ) - } - - func testWhenDDURLSessionDelegateInitsWithCustomFirstPartyHosts_itPicksCorrectInterceptor() { - // given - URLSessionAutoInstrumentation.instance = URLSessionAutoInstrumentation( - configuration: .mockAny(), - dateProvider: SystemDateProvider(), - appStateListener: AppStateListener.mockAny() - ) - defer { URLSessionAutoInstrumentation.instance = nil } - - // when - let testDelegate = DDURLSessionDelegate(additionalFirstPartyHosts: ["foo.com"]) - - // then - XCTAssert( - testDelegate.interceptor === URLSessionAutoInstrumentation.instance?.interceptor, - "\(String(describing: testDelegate.interceptor)) must be identical to \(String(describing: URLSessionAutoInstrumentation.instance?.interceptor))" - ) - } } diff --git a/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/Interception/URLSessionInterceptorTests.swift b/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/Interception/URLSessionInterceptorTests.swift index 29e967605f..b95c7d0679 100644 --- a/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/Interception/URLSessionInterceptorTests.swift +++ b/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/Interception/URLSessionInterceptorTests.swift @@ -7,24 +7,6 @@ import XCTest @testable import Datadog -private class URLSessionInterceptionHandlerMock: URLSessionInterceptionHandler { - var didNotifyInterceptionStart: ((TaskInterception) -> Void)? - var startedInterceptions: [TaskInterception] = [] - - func notify_taskInterceptionStarted(interception: TaskInterception) { - startedInterceptions.append(interception) - didNotifyInterceptionStart?(interception) - } - - var didNotifyInterceptionCompletion: ((TaskInterception) -> Void)? - var completedInterceptions: [TaskInterception] = [] - - func notify_taskInterceptionCompleted(interception: TaskInterception) { - completedInterceptions.append(interception) - didNotifyInterceptionCompletion?(interception) - } -} - class URLSessionInterceptorTests: XCTestCase { private let handler = URLSessionInterceptionHandlerMock() /// Mock request made to a first party URL. diff --git a/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/URLSessionSwizzlerTests.swift b/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/URLSessionSwizzlerTests.swift index 36cfa12381..bb280f7465 100644 --- a/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/URLSessionSwizzlerTests.swift +++ b/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/URLSessionSwizzlerTests.swift @@ -16,25 +16,32 @@ extension URLSessionSwizzler { } } +extension URLSessionAutoInstrumentation { + func disable() { + swizzler.unswizzle() + } +} + class URLSessionSwizzlerTests: XCTestCase { private let interceptor = URLSessionInterceptorMock() - private var swizzler: URLSessionSwizzler! // swiftlint:disable:this implicitly_unwrapped_optional override func setUpWithError() throws { super.setUp() - swizzler = try URLSessionSwizzler() - swizzler.swizzle() + URLSessionAutoInstrumentation.instance = .init( + swizzler: try URLSessionSwizzler(), + interceptor: interceptor + ) + URLSessionAutoInstrumentation.instance?.enable() // swizzle `URLSession` } override func tearDown() { - swizzler.unswizzle() + URLSessionAutoInstrumentation.instance?.disable() // unswizzle `URLSession` + URLSessionAutoInstrumentation.instance = nil super.tearDown() } private func interceptedSession() -> URLSession { - let delegate = DDURLSessionDelegate() - delegate.interceptor = self.interceptor - return URLSession.createServerMockURLSession(delegate: delegate) + return .createServerMockURLSession(delegate: DDURLSessionDelegate()) } // MARK: - Interception Flow