summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj8
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift2
-rw-r--r--ios/PacketTunnelCore/Actor/ObservedState+Extensions.swift75
-rw-r--r--ios/PacketTunnelCore/Actor/ObservedState.swift78
-rw-r--r--ios/PacketTunnelCore/Actor/PacketTunnelActor+Extensions.swift16
-rw-r--r--ios/PacketTunnelCore/Actor/PacketTunnelActor.swift5
-rw-r--r--ios/PacketTunnelCore/Actor/PacketTunnelActorProtocol.swift2
-rw-r--r--ios/PacketTunnelCore/Actor/State+Extensions.swift44
-rw-r--r--ios/PacketTunnelCore/Actor/State.swift16
-rw-r--r--ios/PacketTunnelCore/IPC/AppMessageHandler.swift2
-rw-r--r--ios/PacketTunnelCoreTests/AppMessageHandlerTests.swift2
-rw-r--r--ios/PacketTunnelCoreTests/Mocks/PacketTunnelActorStub.swift4
-rw-r--r--ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift36
13 files changed, 201 insertions, 89 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index 6484120dbc..ba0d868cd3 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -161,6 +161,7 @@
5878F50029CDA742003D4BE2 /* UIView+AutoLayoutBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5878F4FF29CDA742003D4BE2 /* UIView+AutoLayoutBuilder.swift */; };
587988C728A2A01F00E3DF54 /* AccountDataThrottling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587988C628A2A01F00E3DF54 /* AccountDataThrottling.swift */; };
587A01FC23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587A01FB23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift */; };
+ 587A5E522ADD7569003A70F1 /* ObservedState+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587A5E512ADD7569003A70F1 /* ObservedState+Extensions.swift */; };
587B7536266528A200DEF7E9 /* NotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B7535266528A200DEF7E9 /* NotificationManager.swift */; };
587B753B2666467500DEF7E9 /* NotificationBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B753A2666467500DEF7E9 /* NotificationBannerView.swift */; };
587B753D2666468F00DEF7E9 /* NotificationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B753C2666468F00DEF7E9 /* NotificationController.swift */; };
@@ -292,6 +293,7 @@
58CE5E66224146200008646E /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CE5E65224146200008646E /* LoginViewController.swift */; };
58CE5E6B224146210008646E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 58CE5E6A224146210008646E /* Assets.xcassets */; };
58CE5E81224146470008646E /* PacketTunnel.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 58CE5E79224146470008646E /* PacketTunnel.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ 58CF95A22AD6F35800B59F5D /* ObservedState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CF95A12AD6F35800B59F5D /* ObservedState.swift */; };
58D0C79E23F1CEBA00FE9BA7 /* SnapshotHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58D0C79D23F1CEBA00FE9BA7 /* SnapshotHelper.swift */; };
58D0C7A223F1CECF00FE9BA7 /* MullvadVPNScreenshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58D0C7A023F1CECF00FE9BA7 /* MullvadVPNScreenshots.swift */; };
58D223A8294C8A490029F5F8 /* Operations.h in Headers */ = {isa = PBXBuildFile; fileRef = 58D223A7294C8A490029F5F8 /* Operations.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -1315,6 +1317,7 @@
587988C628A2A01F00E3DF54 /* AccountDataThrottling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDataThrottling.swift; sourceTree = "<group>"; };
58799A352A84FC9F007BE51F /* PingerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PingerProtocol.swift; sourceTree = "<group>"; };
587A01FB23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulatorTunnelProviderHost.swift; sourceTree = "<group>"; };
+ 587A5E512ADD7569003A70F1 /* ObservedState+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ObservedState+Extensions.swift"; sourceTree = "<group>"; };
587AD7C523421D7000E93A53 /* TunnelSettingsV1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelSettingsV1.swift; sourceTree = "<group>"; };
587B7535266528A200DEF7E9 /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = "<group>"; };
587B753A2666467500DEF7E9 /* NotificationBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationBannerView.swift; sourceTree = "<group>"; };
@@ -1432,6 +1435,7 @@
58CE5E79224146470008646E /* PacketTunnel.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PacketTunnel.appex; sourceTree = BUILT_PRODUCTS_DIR; };
58CE5E7D224146470008646E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
58CE5E7E224146470008646E /* PacketTunnel.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PacketTunnel.entitlements; sourceTree = "<group>"; };
+ 58CF95A12AD6F35800B59F5D /* ObservedState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservedState.swift; sourceTree = "<group>"; };
58D0C79323F1CE7000FE9BA7 /* MullvadVPNScreenshots.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MullvadVPNScreenshots.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
58D0C79D23F1CEBA00FE9BA7 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapshotHelper.swift; sourceTree = "<group>"; };
58D0C79F23F1CECF00FE9BA7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -2336,6 +2340,8 @@
5838322A2AC3EF9600EA2071 /* CommandChannel.swift */,
583E60952A9F6D0800DC61EF /* ConfigurationBuilder.swift */,
580D6B892AB31AB400B2D6E0 /* NetworkPath+NetworkReachability.swift */,
+ 58CF95A12AD6F35800B59F5D /* ObservedState.swift */,
+ 587A5E512ADD7569003A70F1 /* ObservedState+Extensions.swift */,
58E9C3852A4EF1CB00CFDEAC /* PacketTunnelActor.swift */,
583832242AC318A100EA2071 /* PacketTunnelActor+ConnectionMonitoring.swift */,
583832222AC3181400EA2071 /* PacketTunnelActor+ErrorState.swift */,
@@ -4188,12 +4194,14 @@
58C7A4572A863FB90060C66F /* TunnelDeviceInfoProtocol.swift in Sources */,
58C7A4562A863FB90060C66F /* DefaultPathObserverProtocol.swift in Sources */,
58FE25DA2AA72A8F003D1918 /* PacketTunnelActor.swift in Sources */,
+ 587A5E522ADD7569003A70F1 /* ObservedState+Extensions.swift in Sources */,
58FE25E62AA738E8003D1918 /* TunnelAdapterProtocol.swift in Sources */,
583832252AC318A100EA2071 /* PacketTunnelActor+ConnectionMonitoring.swift in Sources */,
58C7A4552A863FB90060C66F /* TunnelMonitor.swift in Sources */,
58C7AF182ABD84AB007EDD7A /* ProxyURLResponse.swift in Sources */,
58C7A4512A863FB50060C66F /* PingerProtocol.swift in Sources */,
583832292AC3DF1300EA2071 /* Command.swift in Sources */,
+ 58CF95A22AD6F35800B59F5D /* ObservedState.swift in Sources */,
583832232AC3181400EA2071 /* PacketTunnelActor+ErrorState.swift in Sources */,
58C7AF112ABD8480007EDD7A /* TunnelProviderMessage.swift in Sources */,
58C7AF162ABD84A8007EDD7A /* URLRequestProxy.swift in Sources */,
diff --git a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
index 1c155ca7bc..cf8ec138f7 100644
--- a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
@@ -164,7 +164,7 @@ extension PacketTunnelProvider {
stopObservingActorState()
stateObserverTask = Task {
- let stateStream = await self.actor.states
+ let stateStream = await self.actor.observedStates
var lastConnectionAttempt: UInt = 0
for await newState in stateStream {
diff --git a/ios/PacketTunnelCore/Actor/ObservedState+Extensions.swift b/ios/PacketTunnelCore/Actor/ObservedState+Extensions.swift
new file mode 100644
index 0000000000..954f4450c5
--- /dev/null
+++ b/ios/PacketTunnelCore/Actor/ObservedState+Extensions.swift
@@ -0,0 +1,75 @@
+//
+// ObservedState+Extensions.swift
+// PacketTunnelCore
+//
+// Created by pronebird on 16/10/2023.
+// Copyright © 2023 Mullvad VPN AB. All rights reserved.
+//
+
+import Foundation
+import MullvadTypes
+
+extension ObservedState {
+ public var packetTunnelStatus: PacketTunnelStatus {
+ var status = PacketTunnelStatus()
+
+ switch self {
+ case let .connecting(connState),
+ let .connected(connState),
+ let .reconnecting(connState),
+ let .disconnecting(connState):
+ switch connState.networkReachability {
+ case .reachable:
+ status.isNetworkReachable = true
+ case .unreachable:
+ status.isNetworkReachable = false
+ case .undetermined:
+ // TODO: fix me
+ status.isNetworkReachable = true
+ }
+
+ status.numberOfFailedAttempts = connState.connectionAttemptCount
+ status.tunnelRelay = connState.selectedRelay.packetTunnelRelay
+
+ case .disconnected, .initial:
+ break
+
+ case let .error(blockedState):
+ status.blockedStateReason = blockedState.reason
+ }
+
+ return status
+ }
+
+ public var relayConstraints: RelayConstraints? {
+ switch self {
+ case let .connecting(connState), let .connected(connState), let .reconnecting(connState):
+ return connState.relayConstraints
+
+ case let .error(blockedState):
+ return blockedState.relayConstraints
+
+ case .initial, .disconnecting, .disconnected:
+ return nil
+ }
+ }
+
+ public var name: String {
+ switch self {
+ case .connected:
+ return "Connected"
+ case .connecting:
+ return "Connecting"
+ case .reconnecting:
+ return "Reconnecting"
+ case .disconnecting:
+ return "Disconnecting"
+ case .disconnected:
+ return "Disconnected"
+ case .initial:
+ return "Initial"
+ case .error:
+ return "Error"
+ }
+ }
+}
diff --git a/ios/PacketTunnelCore/Actor/ObservedState.swift b/ios/PacketTunnelCore/Actor/ObservedState.swift
new file mode 100644
index 0000000000..bdef364122
--- /dev/null
+++ b/ios/PacketTunnelCore/Actor/ObservedState.swift
@@ -0,0 +1,78 @@
+//
+// ObservedState.swift
+// PacketTunnelCore
+//
+// Created by pronebird on 11/10/2023.
+// Copyright © 2023 Mullvad VPN AB. All rights reserved.
+//
+
+import Combine
+import Foundation
+import MullvadTypes
+import Network
+
+/// A serializable representation of internal state.
+public enum ObservedState: Equatable, Codable {
+ case initial
+ case connecting(ObservedConnectionState)
+ case reconnecting(ObservedConnectionState)
+ case connected(ObservedConnectionState)
+ case disconnecting(ObservedConnectionState)
+ case disconnected
+ case error(ObservedBlockedState)
+}
+
+/// A serializable representation of internal connection state.
+public struct ObservedConnectionState: Equatable, Codable {
+ public var selectedRelay: SelectedRelay
+ public var relayConstraints: RelayConstraints
+ public var networkReachability: NetworkReachability
+ public var connectionAttemptCount: UInt
+}
+
+/// A serializable representation of internal blocked state.
+public struct ObservedBlockedState: Equatable, Codable {
+ public var reason: BlockedStateReason
+ public var relayConstraints: RelayConstraints?
+}
+
+extension State {
+ /// Map `State` to `ObservedState`.
+ var observedState: ObservedState {
+ switch self {
+ case .initial:
+ return .initial
+ case let .connecting(connState):
+ return .connecting(connState.observedConnectionState)
+ case let .connected(connState):
+ return .connected(connState.observedConnectionState)
+ case let .reconnecting(connState):
+ return .reconnecting(connState.observedConnectionState)
+ case let .disconnecting(connState):
+ return .disconnecting(connState.observedConnectionState)
+ case .disconnected:
+ return .disconnected
+ case let .error(blockedState):
+ return .error(blockedState.observedBlockedState)
+ }
+ }
+}
+
+extension ConnectionState {
+ /// Map `ConnectionState` to `ObservedConnectionState`.
+ var observedConnectionState: ObservedConnectionState {
+ ObservedConnectionState(
+ selectedRelay: selectedRelay,
+ relayConstraints: relayConstraints,
+ networkReachability: networkReachability,
+ connectionAttemptCount: connectionAttemptCount
+ )
+ }
+}
+
+extension BlockedState {
+ /// Map `BlockedState` to `ObservedBlockedState`
+ var observedBlockedState: ObservedBlockedState {
+ return ObservedBlockedState(reason: reason, relayConstraints: relayConstraints)
+ }
+}
diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActor+Extensions.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActor+Extensions.swift
index 71bd13c057..3bd2c56315 100644
--- a/ios/PacketTunnelCore/Actor/PacketTunnelActor+Extensions.swift
+++ b/ios/PacketTunnelCore/Actor/PacketTunnelActor+Extensions.swift
@@ -9,11 +9,11 @@
import Foundation
extension PacketTunnelActor {
- /// Returns a stream yielding new value when `state` changes.
- /// The stream starts with current `state` and ends upon moving to `.disconnected` state.
- public var states: AsyncStream<State> {
+ /// Returns a stream yielding `ObservedState`.
+ /// Note that the stream yields current value when created.
+ public var observedStates: AsyncStream<ObservedState> {
AsyncStream { continuation in
- let cancellable = self.$state.sink { newState in
+ let cancellable = $observedState.sink { newState in
continuation.yield(newState)
// Finish stream once entered `.disconnected` state.
@@ -28,10 +28,10 @@ extension PacketTunnelActor {
}
}
- /// Wait until the `state` moved to `.connected`.
+ /// Wait until the `observedState` moved to `.connected`.
/// Should return if the state is `.disconnected` as this is the final state of actor.
public func waitUntilConnected() async {
- for await newState in states {
+ for await newState in observedStates {
switch newState {
case .connected, .disconnected:
// Return once either desired or final state is reached.
@@ -43,9 +43,9 @@ extension PacketTunnelActor {
}
}
- /// Wait until the `state` moved to `.disiconnected`.
+ /// Wait until the `observedState` moved to `.disiconnected`.
public func waitUntilDisconnected() async {
- for await newState in states {
+ for await newState in observedStates {
if case .disconnected = newState {
return
}
diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift
index c82b0f8ccb..8d432ae3d1 100644
--- a/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift
+++ b/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift
@@ -25,12 +25,15 @@ import class WireGuardKitTypes.PrivateKey
same anyway.
*/
public actor PacketTunnelActor {
- @Published internal(set) public var state: State = .initial {
+ var state: State = .initial {
didSet {
logger.debug("\(state.logFormat())")
+ observedState = state.observedState
}
}
+ @Published internal(set) public var observedState: ObservedState = .initial
+
let logger = Logger(label: "PacketTunnelActor")
let timings: PacketTunnelActorTimings
diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActorProtocol.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActorProtocol.swift
index d5acf6bae3..749b30713a 100644
--- a/ios/PacketTunnelCore/Actor/PacketTunnelActorProtocol.swift
+++ b/ios/PacketTunnelCore/Actor/PacketTunnelActorProtocol.swift
@@ -9,7 +9,7 @@
import Foundation
public protocol PacketTunnelActorProtocol {
- var state: State { get async }
+ var observedState: ObservedState { get async }
func reconnect(to nextRelay: NextRelay)
func notifyKeyRotation(date: Date?)
diff --git a/ios/PacketTunnelCore/Actor/State+Extensions.swift b/ios/PacketTunnelCore/Actor/State+Extensions.swift
index 6e6d40bfb7..66583b13b4 100644
--- a/ios/PacketTunnelCore/Actor/State+Extensions.swift
+++ b/ios/PacketTunnelCore/Actor/State+Extensions.swift
@@ -37,50 +37,6 @@ extension State {
}
}
- var packetTunnelStatus: PacketTunnelStatus {
- var status = PacketTunnelStatus()
-
- switch self {
- case let .connecting(connState),
- let .connected(connState),
- let .reconnecting(connState),
- let .disconnecting(connState):
- switch connState.networkReachability {
- case .reachable:
- status.isNetworkReachable = true
- case .unreachable:
- status.isNetworkReachable = false
- case .undetermined:
- // TODO: fix me
- status.isNetworkReachable = true
- }
-
- status.numberOfFailedAttempts = connState.connectionAttemptCount
- status.tunnelRelay = connState.selectedRelay.packetTunnelRelay
-
- case .disconnected, .initial:
- break
-
- case let .error(blockedState):
- status.blockedStateReason = blockedState.reason
- }
-
- return status
- }
-
- public var relayConstraints: RelayConstraints? {
- switch self {
- case let .connecting(connState), let .connected(connState), let .reconnecting(connState):
- return connState.relayConstraints
-
- case let .error(blockedState):
- return blockedState.relayConstraints
-
- case .initial, .disconnecting, .disconnected:
- return nil
- }
- }
-
// MARK: - Logging
func logFormat() -> String {
diff --git a/ios/PacketTunnelCore/Actor/State.swift b/ios/PacketTunnelCore/Actor/State.swift
index eba9f1baa8..943cb0317b 100644
--- a/ios/PacketTunnelCore/Actor/State.swift
+++ b/ios/PacketTunnelCore/Actor/State.swift
@@ -54,7 +54,7 @@ import class WireGuardKitTypes.PrivateKey
`.connecting`, `.reconnecting`, `.error` can be interrupted if the tunnel is requested to stop, which should segue actor towards `.disconnected` state.
*/
-public enum State {
+enum State {
/// Initial state at the time when actor is initialized but before the first connection attempt.
case initial
@@ -83,7 +83,7 @@ public enum State {
}
/// Policy describing what WG key to use for tunnel communication.
-public enum KeyPolicy {
+enum KeyPolicy {
/// Use current key stored in device data.
case useCurrent
@@ -92,12 +92,12 @@ public enum KeyPolicy {
}
/// Enum describing network availability.
-public enum NetworkReachability: Equatable {
+public enum NetworkReachability: Equatable, Codable {
case undetermined, reachable, unreachable
}
/// Data associated with states that hold connection data.
-public struct ConnectionState {
+struct ConnectionState {
/// Current selected relay.
public var selectedRelay: SelectedRelay
@@ -130,7 +130,7 @@ public struct ConnectionState {
}
/// Data associated with error state.
-public struct BlockedState {
+struct BlockedState {
/// Reason why block state was entered.
public var reason: BlockedStateReason
@@ -195,12 +195,12 @@ public enum BlockedStateReason: String, Codable, Equatable {
}
/// Legal states that can precede error state.
-public enum StatePriorToBlockedState {
+enum StatePriorToBlockedState {
case initial, connecting, connected, reconnecting
}
/// Target state the actor should transition into upon request to either start (connect) or reconnect.
-public enum TargetStateForReconnect {
+enum TargetStateForReconnect {
case reconnecting, connecting
}
@@ -217,7 +217,7 @@ public enum NextRelay: Equatable, Codable {
}
/// Describes the reason for reconnection request.
-public enum ReconnectReason {
+enum ReconnectReason {
/// Initiated by user.
case userInitiated
diff --git a/ios/PacketTunnelCore/IPC/AppMessageHandler.swift b/ios/PacketTunnelCore/IPC/AppMessageHandler.swift
index d72e2bf05b..4ad557f7ba 100644
--- a/ios/PacketTunnelCore/IPC/AppMessageHandler.swift
+++ b/ios/PacketTunnelCore/IPC/AppMessageHandler.swift
@@ -47,7 +47,7 @@ public struct AppMessageHandler {
return nil
case .getTunnelStatus:
- return await encodeReply(packetTunnelActor.state.packetTunnelStatus)
+ return await encodeReply(packetTunnelActor.observedState.packetTunnelStatus)
case .privateKeyRotation:
packetTunnelActor.notifyKeyRotation(date: Date())
diff --git a/ios/PacketTunnelCoreTests/AppMessageHandlerTests.swift b/ios/PacketTunnelCoreTests/AppMessageHandlerTests.swift
index bea5a83e8b..d11dd47802 100644
--- a/ios/PacketTunnelCoreTests/AppMessageHandlerTests.swift
+++ b/ios/PacketTunnelCoreTests/AppMessageHandlerTests.swift
@@ -17,7 +17,6 @@ final class AppMessageHandlerTests: XCTestCase {
func testHandleAppMessageForSendURLRequest() async throws {
let sendRequestExpectation = expectation(description: "Expect sending request")
- let actor = PacketTunnelActorStub()
let urlRequestProxy = URLRequestProxyStub(sendRequestExpectation: sendRequestExpectation)
let appMessageHandler = createAppMessageHandler(urlRequestProxy: urlRequestProxy)
@@ -37,7 +36,6 @@ final class AppMessageHandlerTests: XCTestCase {
func testHandleAppMessageForCancelURLRequest() async throws {
let cancelRequestExpectation = expectation(description: "Expect cancelling request")
- let actor = PacketTunnelActorStub()
let urlRequestProxy = URLRequestProxyStub(cancelRequestExpectation: cancelRequestExpectation)
let appMessageHandler = createAppMessageHandler(urlRequestProxy: urlRequestProxy)
diff --git a/ios/PacketTunnelCoreTests/Mocks/PacketTunnelActorStub.swift b/ios/PacketTunnelCoreTests/Mocks/PacketTunnelActorStub.swift
index 80c22971df..9dbc8f18fc 100644
--- a/ios/PacketTunnelCoreTests/Mocks/PacketTunnelActorStub.swift
+++ b/ios/PacketTunnelCoreTests/Mocks/PacketTunnelActorStub.swift
@@ -11,12 +11,12 @@ import PacketTunnelCore
import XCTest
struct PacketTunnelActorStub: PacketTunnelActorProtocol {
- let innerState: State = .disconnected
+ let innerState: ObservedState = .disconnected
var stateExpectation: XCTestExpectation?
var reconnectExpectation: XCTestExpectation?
var keyRotationExpectation: XCTestExpectation?
- var state: State {
+ var observedState: ObservedState {
get async {
stateExpectation?.fulfill()
return innerState
diff --git a/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift b/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift
index 3bdf0b062f..e17f48c330 100644
--- a/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift
+++ b/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift
@@ -40,7 +40,7 @@ final class PacketTunnelActorTests: XCTestCase {
let allExpectations = [initialStateExpectation, connectingExpectation, connectedStateExpectation]
- stateSink = await actor.$state
+ stateSink = await actor.$observedState
.receive(on: DispatchQueue.main)
.sink { newState in
switch newState {
@@ -71,7 +71,7 @@ final class PacketTunnelActorTests: XCTestCase {
let allExpectations = [initialStateExpectation, connectingExpectation, connectedStateExpectation]
- stateSink = await actor.$state
+ stateSink = await actor.$observedState
.receive(on: DispatchQueue.main)
.sink { newState in
switch newState {
@@ -102,7 +102,7 @@ final class PacketTunnelActorTests: XCTestCase {
let connectingStateExpectation = expectation(description: "Expect connecting state")
connectingStateExpectation.expectedFulfillmentCount = 5
var nextAttemptCount: UInt = 0
- stateSink = await actor.$state
+ stateSink = await actor.$observedState
.receive(on: DispatchQueue.main)
.sink { newState in
switch newState {
@@ -136,7 +136,7 @@ final class PacketTunnelActorTests: XCTestCase {
let reconnectingStateExpectation = expectation(description: "Expect reconnecting state")
reconnectingStateExpectation.expectedFulfillmentCount = 5
var nextAttemptCount: UInt = 0
- stateSink = await actor.$state
+ stateSink = await actor.$observedState
.receive(on: DispatchQueue.main)
.sink { newState in
switch newState {
@@ -214,7 +214,7 @@ final class PacketTunnelActorTests: XCTestCase {
let actor = PacketTunnelActor.mock(blockedStateErrorMapper: blockedStateMapper, settingsReader: settingsReader)
- stateSink = await actor.$state
+ stateSink = await actor.$observedState
.receive(on: DispatchQueue.main)
.sink { newState in
switch newState {
@@ -241,7 +241,7 @@ final class PacketTunnelActorTests: XCTestCase {
let disconnectedStateExpectation = expectation(description: "Expect disconnected state")
let connectedStateExpectation = expectation(description: "Expect connected state")
- let expression: (State) -> Bool = { if case .connected = $0 { true } else { false } }
+ let expression: (ObservedState) -> Bool = { if case .connected = $0 { true } else { false } }
await expect(expression, on: actor) {
connectedStateExpectation.fulfill()
@@ -284,7 +284,7 @@ final class PacketTunnelActorTests: XCTestCase {
didStopObserverExpectation.expectedFulfillmentCount = 2
pathObserver.onStop = { didStopObserverExpectation.fulfill() }
- let expression: (State) -> Bool = { if case .connected = $0 { true } else { false } }
+ let expression: (ObservedState) -> Bool = { if case .connected = $0 { true } else { false } }
await expect(expression, on: actor) {
connectedStateExpectation.fulfill()
@@ -309,7 +309,7 @@ final class PacketTunnelActorTests: XCTestCase {
let errorStateExpectation = expectation(description: "Should not enter error state")
errorStateExpectation.isInverted = true
- stateSink = await actor.$state
+ stateSink = await actor.$observedState
.receive(on: DispatchQueue.main)
.sink { newState in
switch newState {
@@ -337,7 +337,7 @@ final class PacketTunnelActorTests: XCTestCase {
let reconnectingStateExpectation = expectation(description: "Expect initial state")
reconnectingStateExpectation.isInverted = true
- let expression: (State) -> Bool = { if case .reconnecting = $0 { true } else { false } }
+ let expression: (ObservedState) -> Bool = { if case .reconnecting = $0 { true } else { false } }
await expect(expression, on: actor) {
reconnectingStateExpectation.fulfill()
@@ -365,7 +365,7 @@ final class PacketTunnelActorTests: XCTestCase {
let reconnectingStateExpectation = expectation(description: "Expect initial state")
reconnectingStateExpectation.isInverted = true
- let expression: (State) -> Bool = { if case .reconnecting = $0 { true } else { false } }
+ let expression: (ObservedState) -> Bool = { if case .reconnecting = $0 { true } else { false } }
await expect(expression, on: actor) { reconnectingStateExpectation.fulfill() }
@@ -390,7 +390,7 @@ final class PacketTunnelActorTests: XCTestCase {
let actor = PacketTunnelActor.mock(tunnelMonitor: tunnelMonitor)
let connectedExpectation = expectation(description: "Expect connected state")
- let expression: (State) -> Bool = { if case .connected = $0 { return true } else { return false } }
+ let expression: (ObservedState) -> Bool = { if case .connected = $0 { return true } else { return false } }
await expect(expression, on: actor) {
connectedExpectation.fulfill()
}
@@ -406,8 +406,8 @@ final class PacketTunnelActorTests: XCTestCase {
}
extension PacketTunnelActorTests {
- func expect(_ state: State, on actor: PacketTunnelActor, _ action: @escaping () -> Void) async {
- stateSink = await actor.$state.receive(on: DispatchQueue.main).sink { newState in
+ func expect(_ state: ObservedState, on actor: PacketTunnelActor, _ action: @escaping () -> Void) async {
+ stateSink = await actor.$observedState.receive(on: DispatchQueue.main).sink { newState in
if state == newState {
action()
}
@@ -415,11 +415,11 @@ extension PacketTunnelActorTests {
}
func expect(
- _ expression: @escaping (State) -> Bool,
+ _ expression: @escaping (ObservedState) -> Bool,
on actor: PacketTunnelActor,
_ action: @escaping () -> Void
) async {
- stateSink = await actor.$state.receive(on: DispatchQueue.main).sink { newState in
+ stateSink = await actor.$observedState.receive(on: DispatchQueue.main).sink { newState in
if expression(newState) {
action()
}
@@ -427,10 +427,4 @@ extension PacketTunnelActorTests {
}
}
-extension State: Equatable {
- public static func == (lhs: State, rhs: State) -> Bool {
- lhs.name == rhs.name
- }
-}
-
// swiftlint:disable:this file_length