Skip to content
Open
Show file tree
Hide file tree
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
4 changes: 2 additions & 2 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
case .cellular:
if #available(iOS 13.0, *) {
if let serviceId = networkInfo.dataServiceIdentifier, let value = networkInfo.serviceCurrentRadioAccessTechnology?[serviceId] {
return ("cell", simpleConnectionName(connectionType: value), networkInfo.serviceSubscriberCellularProviders?[networkInfo.dataServiceIdentifier!])
return ("cell", simpleConnectionName(connectionType: value), networkInfo.serviceSubscriberCellularProviders?[serviceId])
}
} else {
if let radioType = networkInfo.currentRadioAccessTechnology {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ public class URLSessionInstrumentation {
URLSessionDataDelegate.urlSession(_:dataTask:didBecome:)
as (URLSessionDataDelegate) -> (
(URLSession, URLSessionDataTask, URLSessionStreamTask) -> Void
)?)
)?),
#selector(
URLSessionTaskDelegate.urlSession(_:task:didFinishCollecting:))
]
let classes =
configuration.delegateClassesToInstrument
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ class URLSessionInstrumentationTests: XCTestCase {
}
}

/// A minimal delegate that only implements didFinishCollecting.
/// This tests that delegate classes are discovered even when they only implement
/// urlSession(_:task:didFinishCollecting:) and no other delegate methods.
class MinimalMetricsDelegate: NSObject, URLSessionTaskDelegate {
var didFinishCollectingCalled = false

func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
didFinishCollectingCalled = true
}
}

static var requestCopy: URLRequest!
static var responseCopy: HTTPURLResponse!

Expand Down Expand Up @@ -915,20 +926,41 @@ class URLSessionInstrumentationTests: XCTestCase {
public func testAsyncAwaitUploadMethodsAreNotInstrumented() async throws {
let url = URL(string: "http://localhost:33333/success")!
let request = URLRequest(url: url)

// Test upload(for:from:) method
let (data, response) = try await URLSession.shared.upload(for: request, from: Data())

guard let httpResponse = response as? HTTPURLResponse else {
XCTFail("Response should be HTTPURLResponse")
return
}

XCTAssertEqual(httpResponse.statusCode, 200, "Request should succeed")
XCTAssertNotNil(data, "Should receive response data")

XCTAssertTrue(URLSessionInstrumentationTests.checker.shouldInstrumentCalled, "shouldInstrument should be called")
XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled, "createdRequest should be called")
XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled, "receivedResponse should be called")
}

/// Tests that delegate classes are discovered and swizzled even when they only implement
/// urlSession(_:task:didFinishCollecting:) and no other delegate methods.
/// This is a regression test for a bug where the selector for didFinishCollecting was missing
/// from the delegate discovery mechanism.
@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)
public func testDelegateWithOnlyDidFinishCollectingIsDiscovered() async throws {
let request = URLRequest(url: URL(string: "http://localhost:33333/success")!)

let delegate = MinimalMetricsDelegate()
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: delegate, delegateQueue: nil)

_ = try await session.data(for: request)

// Verify the user's delegate was called (proves swizzling forwarded the call)
XCTAssertTrue(delegate.didFinishCollectingCalled, "Delegate should receive metrics callback")

// Verify instrumentation worked (span was created and completed)
XCTAssertTrue(URLSessionInstrumentationTests.checker.createdRequestCalled, "Instrumentation should capture the request")
XCTAssertTrue(URLSessionInstrumentationTests.checker.receivedResponseCalled, "Instrumentation should capture the response")
}
}