소스 검색

Start diagnosing and fixing precise lifetime bugs.

Jon Shier 4 년 전
부모
커밋
87f5ae6ae0

+ 2 - 0
Alamofire.xcodeproj/project.pbxproj

@@ -2096,6 +2096,7 @@
 				PRODUCT_BUNDLE_IDENTIFIER = org.alamofire.Alamofire;
 				PRODUCT_NAME = Alamofire;
 				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				SWIFT_OPTIMIZE_OBJECT_LIFETIME = YES;
 				SWIFT_SWIFT3_OBJC_INFERENCE = Off;
 				SWIFT_VERSION = 5.0;
 				TVOS_DEPLOYMENT_TARGET = 10.0;
@@ -2161,6 +2162,7 @@
 				PRODUCT_NAME = Alamofire;
 				SWIFT_COMPILATION_MODE = wholemodule;
 				SWIFT_OPTIMIZATION_LEVEL = "-O";
+				SWIFT_OPTIMIZE_OBJECT_LIFETIME = YES;
 				SWIFT_SWIFT3_OBJC_INFERENCE = Off;
 				SWIFT_VERSION = 5.0;
 				TVOS_DEPLOYMENT_TARGET = 10.0;

+ 6 - 0
Source/Request.swift

@@ -268,6 +268,11 @@ public class Request {
         self.eventMonitor = eventMonitor
         self.interceptor = interceptor
         self.delegate = delegate
+        NSLog("*** Request \(id) initialized.")
+    }
+    
+    deinit {
+        NSLog("*** Request \(id) deinitialized, delegate: \(String(describing: delegate)).")
     }
 
     // MARK: - Internal Event API
@@ -391,6 +396,7 @@ public class Request {
     func didResumeTask(_ task: URLSessionTask) {
         dispatchPrecondition(condition: .onQueue(underlyingQueue))
 
+        NSLog("*** didResumeTask, tasks: \(tasks), delegate: \(String(describing: delegate))")
         eventMonitor?.request(self, didResumeTask: task)
     }
 

+ 1 - 0
Source/Session.swift

@@ -202,6 +202,7 @@ open class Session {
     deinit {
         finishRequestsForDeinit()
         session.invalidateAndCancel()
+        NSLog("*** Deinitializing session.")
     }
 
     // MARK: - All Requests API

+ 4 - 0
Source/SessionDelegate.swift

@@ -38,6 +38,10 @@ open class SessionDelegate: NSObject {
     public init(fileManager: FileManager = .default) {
         self.fileManager = fileManager
     }
+    
+    deinit {
+        NSLog("*** SessionDelegate deinitialized.")
+    }
 
     /// Internal method to find and cast requests while maintaining some integrity checking.
     ///

+ 14 - 14
Tests/AuthenticationInterceptorTests.swift

@@ -150,7 +150,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
         let authenticator = TestAuthenticator()
         let interceptor = AuthenticationInterceptor(authenticator: authenticator, credential: credential)
 
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
 
         let expect = expectation(description: "request should complete")
         var response: AFDataResponse<Data?>?
@@ -181,7 +181,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
         let authenticator = TestAuthenticator()
         let interceptor = AuthenticationInterceptor(authenticator: authenticator, credential: credential)
 
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
 
         let expect = expectation(description: "both requests should complete")
         expect.expectedFulfillmentCount = 2
@@ -222,7 +222,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
         let authenticator = TestAuthenticator()
         let interceptor = AuthenticationInterceptor(authenticator: authenticator)
 
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
 
         let expect = expectation(description: "request should complete")
         var response: AFDataResponse<Data?>?
@@ -256,7 +256,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
         let authenticator = TestAuthenticator(refreshResult: .failure(TestAuthError.refreshNetworkFailure))
         let interceptor = AuthenticationInterceptor(authenticator: authenticator, credential: credential)
 
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
 
         let expect = expectation(description: "request should complete")
         var response: AFDataResponse<Data?>?
@@ -299,7 +299,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
         let interceptor = AuthenticationInterceptor(authenticator: authenticator, credential: credential)
 
         let urlRequest = URLRequest(url: URL(string: "/invalid/path")!)
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
 
         let expect = expectation(description: "request should complete")
         var response: AFDataResponse<Data?>?
@@ -333,7 +333,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
         let authenticator = TestAuthenticator()
         let interceptor = AuthenticationInterceptor(authenticator: authenticator, credential: credential)
 
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
 
         let expect = expectation(description: "request should complete")
         var response: AFDataResponse<Data?>?
@@ -370,7 +370,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
         let eventMonitor = ClosureEventMonitor()
         eventMonitor.requestDidCreateTask = { _, _ in interceptor.credential = nil }
 
-        let session = Session(eventMonitors: [eventMonitor])
+        let session = Session(eventMonitors: [eventMonitor]); defer { keepAlive(session) }
 
         let expect = expectation(description: "request should complete")
         var response: AFDataResponse<Data?>?
@@ -419,7 +419,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
                                                     requiresRefresh: false)
         }
 
-        let session = Session(eventMonitors: [eventMonitor])
+        let session = Session(eventMonitors: [eventMonitor]); defer { keepAlive(session) }
 
         let pathAdapter = PathAdapter(paths: ["/status/401", "/status/200"])
         let compositeInterceptor = Interceptor(adapters: [pathAdapter, interceptor], retriers: [interceptor])
@@ -464,7 +464,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
                                                     requiresRefresh: false)
         }
 
-        let session = Session(eventMonitors: [eventMonitor])
+        let session = Session(eventMonitors: [eventMonitor]); defer { keepAlive(session) }
 
         let pathAdapter = PathAdapter(paths: ["/status/200"])
         let compositeInterceptor = Interceptor(adapters: [pathAdapter, interceptor], retriers: [interceptor])
@@ -502,7 +502,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
 
         let compositeInterceptor = Interceptor(adapters: [pathAdapter, interceptor], retriers: [interceptor])
 
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
 
         let expect = expectation(description: "request should complete")
         var response: AFDataResponse<Data?>?
@@ -533,7 +533,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
         let authenticator = TestAuthenticator(refreshResult: .failure(TestAuthError.refreshNetworkFailure))
         let interceptor = AuthenticationInterceptor(authenticator: authenticator, credential: credential)
 
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
 
         let expect = expectation(description: "request should complete")
         var response: AFDataResponse<Data?>?
@@ -573,7 +573,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
         let interceptor = AuthenticationInterceptor(authenticator: authenticator, credential: credential)
 
         let requestCount = 6
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
 
         let expect = expectation(description: "both requests should complete")
         expect.expectedFulfillmentCount = requestCount
@@ -629,7 +629,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
 
         let compositeInterceptor = Interceptor(adapters: [pathAdapter, interceptor], retriers: [interceptor])
 
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
 
         let expect = expectation(description: "request should complete")
         var response: AFDataResponse<Data?>?
@@ -662,7 +662,7 @@ final class AuthenticationInterceptorTestCase: BaseTestCase {
                                                     credential: credential,
                                                     refreshWindow: .init(interval: 30, maximumAttempts: 2))
 
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
 
         let expect = expectation(description: "request should complete")
         var response: AFDataResponse<Data?>?

+ 8 - 6
Tests/AuthenticationTests.swift

@@ -29,7 +29,7 @@ import XCTest
 final class BasicAuthenticationTestCase: BaseTestCase {
     func testHTTPBasicAuthenticationFailsWithInvalidCredentials() {
         // Given
-        let session = Session()
+        let session = Session(eventMonitors: [NSLoggingEventMonitor()]); defer { keepAlive(session) }
         let endpoint = Endpoint.basicAuth()
         let expectation = self.expectation(description: "\(endpoint.url) 401")
 
@@ -39,6 +39,7 @@ final class BasicAuthenticationTestCase: BaseTestCase {
         session.request(endpoint)
             .authenticate(username: "invalid", password: "credentials")
             .response { resp in
+                NSLog("*** Response: \(resp.debugDescription)")
                 response = resp
                 expectation.fulfill()
             }
@@ -46,6 +47,7 @@ final class BasicAuthenticationTestCase: BaseTestCase {
         waitForExpectations(timeout: timeout)
 
         // Then
+        
         XCTAssertNotNil(response?.request)
         XCTAssertNotNil(response?.response)
         XCTAssertEqual(response?.response?.statusCode, 401)
@@ -55,7 +57,7 @@ final class BasicAuthenticationTestCase: BaseTestCase {
 
     func testHTTPBasicAuthenticationWithValidCredentials() {
         // Given
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
         let user = "user1", password = "password"
         let endpoint = Endpoint.basicAuth(forUser: user, password: password)
         let expectation = self.expectation(description: "\(endpoint.url) 200")
@@ -82,7 +84,7 @@ final class BasicAuthenticationTestCase: BaseTestCase {
 
     func testHTTPBasicAuthenticationWithStoredCredentials() {
         // Given
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
         let user = "user2", password = "password"
         let endpoint = Endpoint.basicAuth(forUser: user, password: password)
         let expectation = self.expectation(description: "\(endpoint.url) 200")
@@ -115,7 +117,7 @@ final class BasicAuthenticationTestCase: BaseTestCase {
 
     func testHiddenHTTPBasicAuthentication() {
         // Given
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
         let endpoint = Endpoint.hiddenBasicAuth()
         let expectation = self.expectation(description: "\(endpoint.url) 200")
 
@@ -144,7 +146,7 @@ final class BasicAuthenticationTestCase: BaseTestCase {
 final class HTTPDigestAuthenticationTestCase: BaseTestCase {
     func testHTTPDigestAuthenticationWithInvalidCredentials() {
         // Given
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
         let endpoint = Endpoint.digestAuth()
         let expectation = self.expectation(description: "\(endpoint.url) 401")
 
@@ -170,7 +172,7 @@ final class HTTPDigestAuthenticationTestCase: BaseTestCase {
 
     func testHTTPDigestAuthenticationWithValidCredentials() {
         // Given
-        let session = Session()
+        let session = Session(); defer { keepAlive(session) }
         let user = "user", password = "password"
         let endpoint = Endpoint.digestAuth(forUser: user, password: password)
         let expectation = self.expectation(description: "\(endpoint.url) 200")

+ 4 - 0
Tests/BaseTestCase.swift

@@ -57,6 +57,10 @@ class BaseTestCase: XCTestCase {
             }
         }
     }
+    
+    func keepAlive<T: AnyObject>(_ object: T) {
+        withExtendedLifetime(object) {}
+    }
 
     func url(forResource fileName: String, withExtension ext: String) -> URL {
         let bundle = Bundle(for: BaseTestCase.self)

+ 2 - 1
Tests/DataStreamTests.swift

@@ -652,7 +652,7 @@ final class DataStreamIntegrationTests: BaseTestCase {
             }
         }
 
-        let session = Session(interceptor: GoodRetry())
+        let session = Session(interceptor: GoodRetry()); defer { keepAlive(session) }
         var accumulatedData = Data()
         var streamOnMain = false
         var completeOnMain = false
@@ -788,6 +788,7 @@ final class DataStreamIntegrationTests: BaseTestCase {
         let requestQueue = DispatchQueue(label: "org.alamofire.testRequestQueue")
         let serializationQueue = DispatchQueue(label: "org.alamofire.testSerializationQueue")
         let session = Session(requestQueue: requestQueue, serializationQueue: serializationQueue)
+        defer { keepAlive(session) }
         var firstResponse: HTTPURLResponse?
         var firstDecodedResponse: TestResponse?
         var firstDecodingError: AFError?

+ 47 - 44
Tests/NSLoggingEventMonitor.swift

@@ -27,15 +27,18 @@ import Foundation
 
 public final class NSLoggingEventMonitor: EventMonitor {
     public let queue = DispatchQueue(label: "org.alamofire.nsLoggingEventMonitorQueue", qos: .utility)
+    public let prefix: String
 
-    public init() {}
+    public init(prefix: String = "***") {
+        self.prefix = prefix
+    }
 
     public func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {
-        NSLog("URLSession: \(session), didBecomeInvalidWithError: \(error?.localizedDescription ?? "None")")
+        NSLog("\(prefix) URLSession: \(session), didBecomeInvalidWithError: \(error?.localizedDescription ?? "None")")
     }
 
     public func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge) {
-        NSLog("URLSession: \(session), task: \(task), didReceiveChallenge: \(challenge)")
+        NSLog("\(prefix) URLSession: \(session), task: \(task), didReceiveChallenge: \(challenge)")
     }
 
     public func urlSession(_ session: URLSession,
@@ -43,47 +46,47 @@ public final class NSLoggingEventMonitor: EventMonitor {
                            didSendBodyData bytesSent: Int64,
                            totalBytesSent: Int64,
                            totalBytesExpectedToSend: Int64) {
-        NSLog("URLSession: \(session), task: \(task), didSendBodyData: \(bytesSent), totalBytesSent: \(totalBytesSent), totalBytesExpectedToSent: \(totalBytesExpectedToSend)")
+        NSLog("\(prefix) URLSession: \(session), task: \(task), didSendBodyData: \(bytesSent), totalBytesSent: \(totalBytesSent), totalBytesExpectedToSent: \(totalBytesExpectedToSend)")
     }
 
     public func urlSession(_ session: URLSession, taskNeedsNewBodyStream task: URLSessionTask) {
-        NSLog("URLSession: \(session), taskNeedsNewBodyStream: \(task)")
+        NSLog("\(prefix) URLSession: \(session), taskNeedsNewBodyStream: \(task)")
     }
 
     public func urlSession(_ session: URLSession,
                            task: URLSessionTask,
                            willPerformHTTPRedirection response: HTTPURLResponse,
                            newRequest request: URLRequest) {
-        NSLog("URLSession: \(session), task: \(task), willPerformHTTPRedirection: \(response), newRequest: \(request)")
+        NSLog("\(prefix) URLSession: \(session), task: \(task), willPerformHTTPRedirection: \(response), newRequest: \(request)")
     }
 
     public func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
-        NSLog("URLSession: \(session), task: \(task), didFinishCollecting: \(metrics)")
+        NSLog("\(prefix) URLSession: \(session), task: \(task), didFinishCollecting: \(metrics)")
     }
 
     public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
-        NSLog("URLSession: \(session), task: \(task), didCompleteWithError: \(error?.localizedDescription ?? "None")")
+        NSLog("\(prefix) URLSession: \(session), task: \(task), didCompleteWithError: \(error?.localizedDescription ?? "None")")
     }
 
     public func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {
-        NSLog("URLSession: \(session), taskIsWaitingForConnectivity: \(task)")
+        NSLog("\(prefix) URLSession: \(session), taskIsWaitingForConnectivity: \(task)")
     }
 
     public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
-        NSLog("URLSession: \(session), dataTask: \(dataTask), didReceiveDataOfLength: \(data.count)")
+        NSLog("\(prefix) URLSession: \(session), dataTask: \(dataTask), didReceiveDataOfLength: \(data.count)")
     }
 
     public func urlSession(_ session: URLSession,
                            dataTask: URLSessionDataTask,
                            willCacheResponse proposedResponse: CachedURLResponse) {
-        NSLog("URLSession: \(session), dataTask: \(dataTask), willCacheResponse: \(proposedResponse)")
+        NSLog("\(prefix) URLSession: \(session), dataTask: \(dataTask), willCacheResponse: \(proposedResponse)")
     }
 
     public func urlSession(_ session: URLSession,
                            downloadTask: URLSessionDownloadTask,
                            didResumeAtOffset fileOffset: Int64,
                            expectedTotalBytes: Int64) {
-        NSLog("URLSession: \(session), downloadTask: \(downloadTask), didResumeAtOffset: \(fileOffset), expectedTotalBytes: \(expectedTotalBytes)")
+        NSLog("\(prefix) URLSession: \(session), downloadTask: \(downloadTask), didResumeAtOffset: \(fileOffset), expectedTotalBytes: \(expectedTotalBytes)")
     }
 
     public func urlSession(_ session: URLSession,
@@ -91,132 +94,132 @@ public final class NSLoggingEventMonitor: EventMonitor {
                            didWriteData bytesWritten: Int64,
                            totalBytesWritten: Int64,
                            totalBytesExpectedToWrite: Int64) {
-        NSLog("URLSession: \(session), downloadTask: \(downloadTask), didWriteData bytesWritten: \(bytesWritten), totalBytesWritten: \(totalBytesWritten), totalBytesExpectedToWrite: \(totalBytesExpectedToWrite)")
+        NSLog("\(prefix) URLSession: \(session), downloadTask: \(downloadTask), didWriteData bytesWritten: \(bytesWritten), totalBytesWritten: \(totalBytesWritten), totalBytesExpectedToWrite: \(totalBytesExpectedToWrite)")
     }
 
     public func urlSession(_ session: URLSession,
                            downloadTask: URLSessionDownloadTask,
                            didFinishDownloadingTo location: URL) {
-        NSLog("URLSession: \(session), downloadTask: \(downloadTask), didFinishDownloadingTo: \(location)")
+        NSLog("\(prefix) URLSession: \(session), downloadTask: \(downloadTask), didFinishDownloadingTo: \(location)")
     }
 
     public func request(_ request: Request, didCreateInitialURLRequest urlRequest: URLRequest) {
-        NSLog("Request: \(request) didCreateInitialURLRequest: \(urlRequest)")
+        NSLog("\(prefix) Request: \(request) didCreateInitialURLRequest: \(urlRequest)")
     }
 
     public func request(_ request: Request, didFailToCreateURLRequestWithError error: Error) {
-        NSLog("Request: \(request) didFailToCreateURLRequestWithError: \(error)")
+        NSLog("\(prefix) Request: \(request) didFailToCreateURLRequestWithError: \(error)")
     }
 
     public func request(_ request: Request, didAdaptInitialRequest initialRequest: URLRequest, to adaptedRequest: URLRequest) {
-        NSLog("Request: \(request) didAdaptInitialRequest \(initialRequest) to \(adaptedRequest)")
+        NSLog("\(prefix) Request: \(request) didAdaptInitialRequest \(initialRequest) to \(adaptedRequest)")
     }
 
     public func request(_ request: Request, didFailToAdaptURLRequest initialRequest: URLRequest, withError error: Error) {
-        NSLog("Request: \(request) didFailToAdaptURLRequest \(initialRequest) withError \(error)")
+        NSLog("\(prefix) Request: \(request) didFailToAdaptURLRequest \(initialRequest) withError \(error)")
     }
 
     public func request(_ request: Request, didCreateURLRequest urlRequest: URLRequest) {
-        NSLog("Request: \(request) didCreateURLRequest: \(urlRequest)")
+        NSLog("\(prefix) Request: \(request) didCreateURLRequest: \(urlRequest)")
     }
 
     public func request(_ request: Request, didCreateTask task: URLSessionTask) {
-        NSLog("Request: \(request) didCreateTask \(task)")
+        NSLog("\(prefix) Request: \(request) didCreateTask \(task)")
     }
 
     public func request(_ request: Request, didGatherMetrics metrics: URLSessionTaskMetrics) {
-        NSLog("Request: \(request) didGatherMetrics \(metrics)")
+        NSLog("\(prefix) Request: \(request) didGatherMetrics \(metrics)")
     }
 
     public func request(_ request: Request, didFailTask task: URLSessionTask, earlyWithError error: Error) {
-        NSLog("Request: \(request) didFailTask \(task) earlyWithError \(error)")
+        NSLog("\(prefix) Request: \(request) didFailTask \(task) earlyWithError \(error)")
     }
 
     public func request(_ request: Request, didCompleteTask task: URLSessionTask, with error: Error?) {
-        NSLog("Request: \(request) didCompleteTask \(task) withError: \(error?.localizedDescription ?? "None")")
+        NSLog("\(prefix) Request: \(request) didCompleteTask \(task) withError: \(error?.localizedDescription ?? "None")")
     }
 
     public func requestDidFinish(_ request: Request) {
-        NSLog("Request: \(request) didFinish")
+        NSLog("\(prefix) Request: \(request) didFinish")
     }
 
     public func requestDidResume(_ request: Request) {
-        NSLog("Request: \(request) didResume")
+        NSLog("\(prefix) Request: \(request) didResume")
     }
 
     public func request(_ request: Request, didResumeTask task: URLSessionTask) {
-        NSLog("Request: \(request) didResumeTask: \(task)")
+        NSLog("\(prefix) Request: \(request) didResumeTask: \(task)")
     }
 
     public func requestDidSuspend(_ request: Request) {
-        NSLog("Request: \(request) didSuspend")
+        NSLog("\(prefix) Request: \(request) didSuspend")
     }
 
     public func request(_ request: Request, didSuspendTask task: URLSessionTask) {
-        NSLog("Request: \(request) didSuspendTask: \(task)")
+        NSLog("\(prefix) Request: \(request) didSuspendTask: \(task)")
     }
 
     public func requestDidCancel(_ request: Request) {
-        NSLog("Request: \(request) didCancel")
+        NSLog("\(prefix) Request: \(request) didCancel")
     }
 
     public func request(_ request: Request, didCancelTask task: URLSessionTask) {
-        NSLog("Request: \(request) didCancelTask: \(task)")
+        NSLog("\(prefix) Request: \(request) didCancelTask: \(task)")
     }
 
     public func request(_ request: DataRequest, didParseResponse response: DataResponse<Data?, Error>) {
-        NSLog("Request: \(request), didParseResponse: \(response)")
+        NSLog("\(prefix) Request: \(request), didParseResponse: \(response)")
     }
 
     public func request<Value>(_ request: DataRequest, didParseResponse response: DataResponse<Value, Error>) {
-        NSLog("Request: \(request), didParseResponse: \(response)")
+        NSLog("\(prefix) Request: \(request), didParseResponse: \(response)")
     }
 
     public func request(_ request: DownloadRequest, didParseResponse response: DownloadResponse<Data?, Error>) {
-        NSLog("Request: \(request), didParseResponse: \(response)")
+        NSLog("\(prefix) Request: \(request), didParseResponse: \(response)")
     }
 
     public func request<Value>(_ request: DownloadRequest, didParseResponse response: DownloadResponse<Value, Error>) {
-        NSLog("Request: \(request), didParseResponse: \(response)")
+        NSLog("\(prefix) Request: \(request), didParseResponse: \(response)")
     }
 
     public func requestIsRetrying(_ request: Request) {
-        NSLog("Request: \(request), isRetrying")
+        NSLog("\(prefix) Request: \(request), isRetrying")
     }
 
     public func request(_ request: DataRequest, didValidateRequest urlRequest: URLRequest?, response: HTTPURLResponse, data: Data?, withResult result: Request.ValidationResult) {
-        NSLog("Request: \(request), didValidateRequestWithResult: \(result)")
+        NSLog("\(prefix) Request: \(request), didValidateRequestWithResult: \(result)")
     }
 
     public func request(_ request: DataStreamRequest, didValidateRequest urlRequest: URLRequest?, response: HTTPURLResponse, withResult result: Request.ValidationResult) {
-        NSLog("Request: \(request), didValidateRequestWithResult: \(result)")
+        NSLog("\(prefix) Request: \(request), didValidateRequestWithResult: \(result)")
     }
 
     public func request<Value>(_ request: DataStreamRequest, didParseStream result: Result<Value, AFError>) {
-        NSLog("Request: \(request), didParseStreamWithResult: \(result)")
+        NSLog("\(prefix) Request: \(request), didParseStreamWithResult: \(result)")
     }
 
     public func request(_ request: UploadRequest, didCreateUploadable uploadable: UploadRequest.Uploadable) {
-        NSLog("Request: \(request), didCreateUploadable: \(uploadable)")
+        NSLog("\(prefix) Request: \(request), didCreateUploadable: \(uploadable)")
     }
 
     public func request(_ request: UploadRequest, didFailToCreateUploadableWithError error: Error) {
-        NSLog("Request: \(request), didFailToCreateUploadableWithError: \(error)")
+        NSLog("\(prefix) Request: \(request), didFailToCreateUploadableWithError: \(error)")
     }
 
     public func request(_ request: UploadRequest, didProvideInputStream stream: InputStream) {
-        NSLog("Request: \(request), didProvideInputStream: \(stream)")
+        NSLog("\(prefix) Request: \(request), didProvideInputStream: \(stream)")
     }
 
     public func request(_ request: DownloadRequest, didFinishDownloadingUsing task: URLSessionTask, with result: Result<URL, Error>) {
-        NSLog("Request: \(request), didFinishDownloadingUsing: \(task), withResult: \(result)")
+        NSLog("\(prefix) Request: \(request), didFinishDownloadingUsing: \(task), withResult: \(result)")
     }
 
     public func request(_ request: DownloadRequest, didCreateDestinationURL url: URL) {
-        NSLog("Request: \(request), didCreateDestinationURL: \(url)")
+        NSLog("\(prefix) Request: \(request), didCreateDestinationURL: \(url)")
     }
 
     public func request(_ request: DownloadRequest, didValidateRequest urlRequest: URLRequest?, response: HTTPURLResponse, temporaryURL: URL?, destinationURL: URL?, withResult result: Request.ValidationResult) {
-        NSLog("Request: \(request), didValidateRequestWithResult: \(result)")
+        NSLog("\(prefix) Request: \(request), didValidateRequestWithResult: \(result)")
     }
 }

+ 1 - 1
Tests/ValidationTests.swift

@@ -383,7 +383,7 @@ final class ContentTypeValidationTestCase: BaseTestCase {
             }()
 
             return MockManager(configuration: configuration)
-        }()
+        }(); defer { keepAlive(manager) }
 
         let endpoint = Endpoint.method(.delete)