summaryrefslogtreecommitdiffhomepage
path: root/ios
diff options
context:
space:
mode:
authorSteffen Ernst <steffen.ernst@mullvad.net>2025-02-13 10:22:54 +0100
committerBug Magnet <marco.nikic@mullvad.net>2025-02-18 11:52:06 +0100
commite61ff5cbaeab56efe2031e633dcfba4d7a00946a (patch)
tree09d5d7744bff10bd74d00b864612ec5406e7e91d /ios
parent19e8b5d5b9fc38510a5c9287fd9ed8548f4f960c (diff)
downloadmullvadvpn-e61ff5cbaeab56efe2031e633dcfba4d7a00946a.tar.xz
mullvadvpn-e61ff5cbaeab56efe2031e633dcfba4d7a00946a.zip
Add tests for reconnection strategy
Diffstat (limited to 'ios')
-rw-r--r--ios/MullvadSettings/TunnelSettingsStrategy.swift13
-rw-r--r--ios/MullvadVPN/TunnelManager/TunnelManager.swift4
-rw-r--r--ios/MullvadVPNTests/MullvadSettings/TunnelSettingsUpdateTests.swift28
-rw-r--r--ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift62
-rw-r--r--ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelSettingsStrategyTests.swift26
5 files changed, 126 insertions, 7 deletions
diff --git a/ios/MullvadSettings/TunnelSettingsStrategy.swift b/ios/MullvadSettings/TunnelSettingsStrategy.swift
index 6c8ff01955..8f9cc0bf46 100644
--- a/ios/MullvadSettings/TunnelSettingsStrategy.swift
+++ b/ios/MullvadSettings/TunnelSettingsStrategy.swift
@@ -22,7 +22,10 @@ public struct TunnelSettingsStrategy: TunnelSettingsStrategyProtocol, Sendable {
oldSettings: LatestTunnelSettings,
newSettings: LatestTunnelSettings
) -> Bool {
- getReconnectionStrategy(oldSettings: oldSettings, newSettings: newSettings) != .noReconnect
+ getReconnectionStrategy(
+ oldSettings: oldSettings,
+ newSettings: newSettings
+ ) != .currentRelayReconnect
}
public func getReconnectionStrategy(
@@ -35,16 +38,16 @@ public struct TunnelSettingsStrategy: TunnelSettingsStrategyProtocol, Sendable {
}
switch (oldSettings, newSettings) {
case let (old, new) where old != new:
- return .softReconnect
+ return .newRelayReconnect
default:
- return .noReconnect
+ return .currentRelayReconnect
}
}
}
public enum TunnelSettingsReconnectionStrategy {
- case noReconnect
- case softReconnect
+ case currentRelayReconnect
+ case newRelayReconnect
// This will fully disconnect and start a new connection
// Attention: This will leak traffic!!!
case hardReconnect
diff --git a/ios/MullvadVPN/TunnelManager/TunnelManager.swift b/ios/MullvadVPN/TunnelManager/TunnelManager.swift
index d12be3b424..ad6deeb3d7 100644
--- a/ios/MullvadVPN/TunnelManager/TunnelManager.swift
+++ b/ios/MullvadVPN/TunnelManager/TunnelManager.swift
@@ -976,9 +976,9 @@ final class TunnelManager: StorePaymentObserver, @unchecked Sendable {
newSettings: updatedSettings
)
switch reconnectionStrategy {
- case .noReconnect:
+ case .currentRelayReconnect:
self.reconnectTunnel(selectNewRelay: false)
- case .softReconnect:
+ case .newRelayReconnect:
self.reconnectTunnel(selectNewRelay: true)
case .hardReconnect:
self.reapplyTunnelConfiguration()
diff --git a/ios/MullvadVPNTests/MullvadSettings/TunnelSettingsUpdateTests.swift b/ios/MullvadVPNTests/MullvadSettings/TunnelSettingsUpdateTests.swift
index d123c7026e..246da1b07b 100644
--- a/ios/MullvadVPNTests/MullvadSettings/TunnelSettingsUpdateTests.swift
+++ b/ios/MullvadVPNTests/MullvadSettings/TunnelSettingsUpdateTests.swift
@@ -101,4 +101,32 @@ final class TunnelSettingsUpdateTests: XCTestCase {
// Then:
XCTAssertEqual(settings.daita, daitaSettings)
}
+
+ func testApplyIAN() {
+ // Given:
+ let includeAllNetworks = true
+ var settings = LatestTunnelSettings()
+
+ // When:
+ let update = TunnelSettingsUpdate.includeAllNetworks(includeAllNetworks)
+ update.apply(to: &settings)
+
+ // Then:
+ XCTAssertEqual(settings.includeAllNetworks, includeAllNetworks)
+ }
+
+ func testApplyLocalNetworkSharing() {
+ // Given:
+ let localNetworkSharing = true
+ var settings = LatestTunnelSettings()
+
+ // When:
+ let update = TunnelSettingsUpdate.localNetworkSharing(
+ localNetworkSharing
+ )
+ update.apply(to: &settings)
+
+ // Then:
+ XCTAssertEqual(settings.localNetworkSharing, localNetworkSharing)
+ }
}
diff --git a/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift b/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift
index c06026e92f..0c21fdacc6 100644
--- a/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift
+++ b/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift
@@ -187,4 +187,66 @@ class TunnelManagerTests: XCTestCase {
enforceOrder: true
)
}
+
+ /// This test verifies tunnel gets disconnected and reconnected on config reapply.
+ func testReapplyingConfigDisconnectsAndReconnects() async throws {
+ var connectedExpectation = expectation(description: "Connected!")
+ let disconnectedExpectation = expectation(description: "Disconnected!")
+
+ accountProxy.createAccountResult = .success(REST.NewAccountData.mockValue())
+
+ let relaySelector = RelaySelectorStub { _ in
+ try RelaySelectorStub.nonFallible().selectRelays(
+ tunnelSettings: LatestTunnelSettings(),
+ connectionAttemptCount: 0
+ )
+ }
+
+ let tunnelManager = TunnelManager(
+ backgroundTaskProvider: application,
+ tunnelStore: TunnelStore(application: application),
+ relayCacheTracker: relayCacheTracker,
+ accountsProxy: accountProxy,
+ devicesProxy: devicesProxy,
+ apiProxy: apiProxy,
+ accessTokenManager: accessTokenManager,
+ relaySelector: relaySelector
+ )
+
+ let simulatorTunnelProviderHost = SimulatorTunnelProviderHost(
+ relaySelector: relaySelector,
+ transportProvider: transportProvider
+ )
+ SimulatorTunnelProvider.shared.delegate = simulatorTunnelProviderHost
+ let tunnelObserver = TunnelBlockObserver(
+ didUpdateTunnelStatus: { _, tunnelStatus in
+ switch tunnelStatus.state {
+ case .connected:
+ connectedExpectation.fulfill()
+ case .disconnected:
+ disconnectedExpectation.fulfill()
+ default:
+ return
+ }
+ }
+ )
+
+ self.tunnelObserver = tunnelObserver
+ tunnelManager.addObserver(tunnelObserver)
+
+ _ = try await tunnelManager.setNewAccount()
+
+ XCTAssertTrue(tunnelManager.deviceState.isLoggedIn)
+
+ tunnelManager.startTunnel()
+ await fulfillment(of: [connectedExpectation])
+ tunnelManager
+ .reapplyTunnelConfiguration()
+ connectedExpectation = expectation(description: "Connected!")
+ await fulfillment(
+ of: [disconnectedExpectation, connectedExpectation],
+ timeout: .UnitTest.timeout,
+ enforceOrder: true
+ )
+ }
}
diff --git a/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelSettingsStrategyTests.swift b/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelSettingsStrategyTests.swift
index aec327473e..4b845e724d 100644
--- a/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelSettingsStrategyTests.swift
+++ b/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelSettingsStrategyTests.swift
@@ -104,4 +104,30 @@ final class TunnelSettingsStrategyTests: XCTestCase {
newSettings: updatedSettings
))
}
+
+ func testHardReconnectWhenIncludeAllNetworksChange() {
+ let currentSettings = LatestTunnelSettings()
+ var updatedSettings = currentSettings
+ TunnelSettingsUpdate.includeAllNetworks(true)
+ .apply(to: &updatedSettings)
+
+ let tunnelSettingsStrategy = TunnelSettingsStrategy()
+ XCTAssertEqual(tunnelSettingsStrategy.getReconnectionStrategy(
+ oldSettings: currentSettings,
+ newSettings: updatedSettings
+ ), .hardReconnect)
+ }
+
+ func testHardReconnectWhenLocalNetworkSharingChange() {
+ let currentSettings = LatestTunnelSettings()
+ var updatedSettings = currentSettings
+ TunnelSettingsUpdate.localNetworkSharing(true)
+ .apply(to: &updatedSettings)
+
+ let tunnelSettingsStrategy = TunnelSettingsStrategy()
+ XCTAssertEqual(tunnelSettingsStrategy.getReconnectionStrategy(
+ oldSettings: currentSettings,
+ newSettings: updatedSettings
+ ), .hardReconnect)
+ }
}