Skip to content

Commit 0a622d9

Browse files
authored
Address flaky Alamofire network test on Alamofire.AFError.sessionDeinitialized error from concurrent requests (#16137)
2 parents 72174e5 + 05c3061 commit 0a622d9

File tree

4 files changed

+13
-47
lines changed

4 files changed

+13
-47
lines changed

Modules/Sources/NetworkingCore/Network/AlamofireNetwork.swift

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,8 @@ public class AlamofireNetwork: Network {
3434
/// authentication mode for requests
3535
public private(set) var authenticationMode: RequestAuthenticationMode?
3636

37-
/// Lazy-initialized session manager. Use ensuresSessionManagerIsInitialized=true to avoid race conditions with concurrent requests.
38-
private lazy var alamofireSession: Alamofire.Session = {
39-
let sessionConfiguration = URLSessionConfiguration.default
40-
let sessionManager = makeSession(configuration: sessionConfiguration)
41-
return sessionManager
42-
}()
37+
/// Session manager used for Alamofire requests.
38+
private let alamofireSession: Alamofire.Session
4339

4440
private let credentials: Credentials?
4541

@@ -71,14 +67,11 @@ public class AlamofireNetwork: Network {
7167
/// - selectedSite: Publisher for site selection changes.
7268
/// This is necessary if you wish to enable network switching to direct requests while authenticated with WPCOM for better performance.
7369
/// - sessionManager: Optional pre-configured session manager.
74-
/// - ensuresSessionManagerIsInitialized: If true, the session is always set during initialization immediately to avoid lazy initialization race conditions.
75-
/// Defaults to false for backward compatibility. Set to true when making concurrent requests immediately after initialization.
7670
public required init(credentials: Credentials?,
7771
selectedSite: AnyPublisher<JetpackSite?, Never>?,
7872
appPasswordSupportState: AnyPublisher<Bool, Never>?,
7973
userDefaults: UserDefaults = .standard,
80-
sessionManager: Alamofire.Session? = nil,
81-
ensuresSessionManagerIsInitialized: Bool = false) {
74+
sessionManager: Alamofire.Session? = nil) {
8275
self.credentials = credentials
8376
self.selectedSite = selectedSite
8477
self.userDefaults = userDefaults
@@ -96,11 +89,12 @@ public class AlamofireNetwork: Network {
9689
}()
9790
return RequestConverter(siteAddress: siteAddress)
9891
}()
99-
self.requestAuthenticator = RequestProcessor(requestAuthenticator: DefaultRequestAuthenticator(credentials: credentials))
92+
let requestAuthenticator = RequestProcessor(requestAuthenticator: DefaultRequestAuthenticator(credentials: credentials))
93+
self.requestAuthenticator = requestAuthenticator
10094
if let sessionManager {
10195
self.alamofireSession = sessionManager
102-
} else if ensuresSessionManagerIsInitialized {
103-
self.alamofireSession = makeSession(configuration: URLSessionConfiguration.default)
96+
} else {
97+
self.alamofireSession = Alamofire.Session(configuration: .default, interceptor: requestAuthenticator)
10498
}
10599

106100
let authenticationMode: RequestAuthenticationMode? = {
@@ -294,12 +288,6 @@ private extension AlamofireNetwork {
294288
}
295289
}
296290

297-
/// Creates a session manager with request retrier and adapter
298-
///
299-
func makeSession(configuration sessionConfiguration: URLSessionConfiguration) -> Alamofire.Session {
300-
Alamofire.Session(configuration: sessionConfiguration, interceptor: requestAuthenticator)
301-
}
302-
303291
/// Updates `requestConverter` and `requestAuthenticator` when selected site changes
304292
///
305293
func observeSelectedSite(_ selectedSite: AnyPublisher<JetpackSite?, Never>) {

Modules/Sources/Yosemite/Tools/POS/POSCatalogFullSyncService.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ public final class POSCatalogFullSyncService: POSCatalogFullSyncServiceProtocol
4343
}
4444
let network = AlamofireNetwork(credentials: credentials,
4545
selectedSite: selectedSite,
46-
appPasswordSupportState: appPasswordSupportState,
47-
ensuresSessionManagerIsInitialized: true)
46+
appPasswordSupportState: appPasswordSupportState)
4847
let syncRemote = POSCatalogSyncRemote(network: network)
4948
let persistenceService = POSCatalogPersistenceService(grdbManager: grdbManager)
5049
self.init(syncRemote: syncRemote, batchSize: batchSize, persistenceService: persistenceService)

Modules/Sources/Yosemite/Tools/POS/POSCatalogIncrementalSyncService.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ public final class POSCatalogIncrementalSyncService: POSCatalogIncrementalSyncSe
3535
}
3636
let network = AlamofireNetwork(credentials: credentials,
3737
selectedSite: selectedSite,
38-
appPasswordSupportState: appPasswordSupportState,
39-
ensuresSessionManagerIsInitialized: true)
38+
appPasswordSupportState: appPasswordSupportState)
4039
let syncRemote = POSCatalogSyncRemote(network: network)
4140
let persistenceService = POSCatalogPersistenceService(grdbManager: grdbManager)
4241
self.init(syncRemote: syncRemote, batchSize: batchSize, persistenceService: persistenceService)

Modules/Tests/NetworkingTests/Network/AlamofireNetworkTests.swift

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,11 @@ final class AlamofireNetworkTests: XCTestCase {
207207

208208
// MARK: - Session Initialization Tests
209209

210-
func test_concurrent_requests_do_not_fail_with_sessionDeinitialized_error_when_ensuresSessionManagerIsInitialized_is_true() async throws {
210+
func test_concurrent_requests_do_not_fail_with_sessionDeinitialized_error() async throws {
211211
// Given
212-
let request = JetpackRequest(wooApiVersion: .mark1, method: .get, siteID: -1, path: "test")
213-
let network = AlamofireNetwork(credentials: nil, selectedSite: nil, appPasswordSupportState: nil, ensuresSessionManagerIsInitialized: true)
212+
let url = try XCTUnwrap(URL(string: "http://localhost:991929281"))
213+
let request = URLRequest(url: url, timeoutInterval: 0.001)
214+
let network = AlamofireNetwork(credentials: nil, selectedSite: nil, appPasswordSupportState: nil)
214215

215216
// When
216217
async let request1 = network.responseDataAndHeaders(for: request)
@@ -228,27 +229,6 @@ final class AlamofireNetworkTests: XCTestCase {
228229
}
229230
}
230231

231-
func test_concurrent_requests_fail_with_sessionDeinitialized_error_when_ensuresSessionManagerIsInitialized_is_false() async throws {
232-
// Given
233-
let request = JetpackRequest(wooApiVersion: .mark1, method: .get, siteID: 1, path: "test")
234-
let network = AlamofireNetwork(credentials: nil, selectedSite: nil, appPasswordSupportState: nil, ensuresSessionManagerIsInitialized: false)
235-
236-
// When
237-
async let request1 = network.responseDataAndHeaders(for: request)
238-
async let request2 = network.responseDataAndHeaders(for: request)
239-
async let request3 = network.responseDataAndHeaders(for: request)
240-
241-
do {
242-
_ = try await [request1, request2, request3]
243-
XCTFail("Requests should fail with sessionDeinitialized error")
244-
} catch Alamofire.AFError.sessionDeinitialized {
245-
// Then
246-
XCTAssertTrue(true)
247-
} catch {
248-
XCTFail("Requests should fail with sessionDeinitialized error, got \(error) instead")
249-
}
250-
}
251-
252232
// MARK: - Retry Logic Tests
253233

254234
func test_responseData_with_completion_retries_direct_request_when_converted_request_fails() throws {

0 commit comments

Comments
 (0)