summaryrefslogtreecommitdiffhomepage
path: root/ios
diff options
context:
space:
mode:
authorJon Petersson <jon.petersson@kvadrat.se>2024-09-09 14:10:57 +0200
committerEmīls <emils@mullvad.net>2024-09-10 22:05:59 +0200
commit747747ea6f0a7f1a96c2495c95d496bdea1fa5bb (patch)
tree46d8c2cefaf242db4edf1b76fb44c7e0f6b4a532 /ios
parentde91617a8bbbdeb69ad46533fa003915bcbe81a6 (diff)
downloadmullvadvpn-747747ea6f0a7f1a96c2495c95d496bdea1fa5bb.tar.xz
mullvadvpn-747747ea6f0a7f1a96c2495c95d496bdea1fa5bb.zip
Store the raw JSON payload from the getRelays API call
Diffstat (limited to 'ios')
-rw-r--r--ios/MullvadREST/ApiHandlers/RESTAPIProxy.swift7
-rw-r--r--ios/MullvadREST/Relay/CachedRelays.swift2
-rw-r--r--ios/MullvadREST/Relay/IPOverrideWrapper.swift12
-rw-r--r--ios/MullvadREST/Relay/RelayCache.swift43
-rw-r--r--ios/MullvadREST/Relay/StoredRelays.swift43
-rw-r--r--ios/MullvadREST/Transport/Shadowsocks/ShadowsocksRelaySelector.swift2
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj4
-rw-r--r--ios/MullvadVPN/RelayCacheTracker/RelayCacheTracker.swift38
-rw-r--r--ios/MullvadVPNTests/MullvadREST/Relay/RelayCacheTests.swift22
-rw-r--r--ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorWrapperTests.swift15
-rw-r--r--ios/MullvadVPNTests/MullvadSettings/IPOverrideWrapperTests.swift12
-rw-r--r--ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift1
-rw-r--r--ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift1
13 files changed, 138 insertions, 64 deletions
diff --git a/ios/MullvadREST/ApiHandlers/RESTAPIProxy.swift b/ios/MullvadREST/ApiHandlers/RESTAPIProxy.swift
index 24d02d36e7..691781ef4c 100644
--- a/ios/MullvadREST/ApiHandlers/RESTAPIProxy.swift
+++ b/ios/MullvadREST/ApiHandlers/RESTAPIProxy.swift
@@ -107,13 +107,14 @@ extension REST {
switch httpStatus {
case let httpStatus where httpStatus.isSuccess:
return .decoding {
- let serverRelays = try self.responseDecoder.decode(
+ // Discarding result since we're only interested in knowing that it's parseable.
+ _ = try self.responseDecoder.decode(
ServerRelaysResponse.self,
from: data
)
let newEtag = response.value(forHTTPHeaderField: HTTPHeader.etag)
- return .newContent(newEtag, serverRelays)
+ return .newContent(newEtag, data)
}
case .notModified where etag != nil:
@@ -284,7 +285,7 @@ extension REST {
public enum ServerRelaysCacheResponse {
case notModified
- case newContent(_ etag: String?, _ value: ServerRelaysResponse)
+ case newContent(_ etag: String?, _ rawData: Data)
}
private struct CreateApplePaymentRequest: Encodable {
diff --git a/ios/MullvadREST/Relay/CachedRelays.swift b/ios/MullvadREST/Relay/CachedRelays.swift
index f22b236e87..b1f8c706c0 100644
--- a/ios/MullvadREST/Relay/CachedRelays.swift
+++ b/ios/MullvadREST/Relay/CachedRelays.swift
@@ -8,7 +8,7 @@
import Foundation
-/// A struct that represents the relay cache on disk
+/// A struct that represents the relay cache in memory
public struct CachedRelays: Codable, Equatable {
/// E-tag returned by server
public let etag: String?
diff --git a/ios/MullvadREST/Relay/IPOverrideWrapper.swift b/ios/MullvadREST/Relay/IPOverrideWrapper.swift
index 84516130d1..1ac2c4dc7d 100644
--- a/ios/MullvadREST/Relay/IPOverrideWrapper.swift
+++ b/ios/MullvadREST/Relay/IPOverrideWrapper.swift
@@ -18,21 +18,23 @@ public class IPOverrideWrapper: RelayCacheProtocol {
self.ipOverrideRepository = ipOverrideRepository
}
- public func read() throws -> CachedRelays {
+ public func read() throws -> StoredRelays {
let cache = try relayCache.read()
let relayResponse = apply(overrides: ipOverrideRepository.fetchAll(), to: cache.relays)
+ let rawData = try REST.Coding.makeJSONEncoder().encode(relayResponse)
- return CachedRelays(relays: relayResponse, updatedAt: cache.updatedAt)
+ return try StoredRelays(etag: cache.etag, rawData: rawData, updatedAt: cache.updatedAt)
}
- public func readPrebundledRelays() throws -> CachedRelays {
+ public func readPrebundledRelays() throws -> StoredRelays {
let prebundledRelays = try relayCache.readPrebundledRelays()
let relayResponse = apply(overrides: ipOverrideRepository.fetchAll(), to: prebundledRelays.relays)
+ let rawData = try REST.Coding.makeJSONEncoder().encode(relayResponse)
- return CachedRelays(relays: relayResponse, updatedAt: prebundledRelays.updatedAt)
+ return try StoredRelays(etag: prebundledRelays.etag, rawData: rawData, updatedAt: prebundledRelays.updatedAt)
}
- public func write(record: CachedRelays) throws {
+ public func write(record: StoredRelays) throws {
try relayCache.write(record: record)
}
diff --git a/ios/MullvadREST/Relay/RelayCache.swift b/ios/MullvadREST/Relay/RelayCache.swift
index eedf3b997a..966d3a810d 100644
--- a/ios/MullvadREST/Relay/RelayCache.swift
+++ b/ios/MullvadREST/Relay/RelayCache.swift
@@ -12,59 +12,66 @@ import MullvadTypes
public protocol RelayCacheProtocol {
/// Reads from a cached list,
/// which falls back to reading from prebundled relays if there was no cache hit
- func read() throws -> CachedRelays
+ func read() throws -> StoredRelays
/// Reads the relays file that were prebundled with the app installation.
///
/// > Warning: Prefer `read()` over this unless there is an explicit need to read
/// relays from the bundle, because those might contain stale data.
- func readPrebundledRelays() throws -> CachedRelays
- func write(record: CachedRelays) throws
+ func readPrebundledRelays() throws -> StoredRelays
+ func write(record: StoredRelays) throws
}
/// - Warning: `RelayCache` should not be used directly. It should be used through `IPOverrideWrapper` to have
/// ip overrides applied.
public final class RelayCache: RelayCacheProtocol {
- private let fileCache: any FileCacheProtocol<CachedRelays>
+ private let fileURL: URL
+ private let fileCache: any FileCacheProtocol<StoredRelays>
/// Designated initializer
public init(cacheDirectory: URL) {
- fileCache = FileCache(fileURL: cacheDirectory.appendingPathComponent("relays.json", isDirectory: false))
+ fileURL = cacheDirectory.appendingPathComponent("relays.json", isDirectory: false)
+ fileCache = FileCache(fileURL: fileURL)
}
/// Initializer that accepts a custom FileCache implementation. Used in tests.
- init(fileCache: some FileCacheProtocol<CachedRelays>) {
+ init(fileCache: some FileCacheProtocol<StoredRelays>) {
+ fileURL = FileManager.default.temporaryDirectory.appendingPathComponent("relays.json", isDirectory: false)
self.fileCache = fileCache
}
- /// Safely read the cache file from disk using file coordinator and fallback to prebundled
- /// relays in case if the relay cache file is missing.
- public func read() throws -> CachedRelays {
+ /// Safely read the cache file from disk using file coordinator and fallback in the following manner:
+ /// 1. If there is a file but it's not decodable, try to parse into the old cache format. If it's still
+ /// not decodable, read the pre-bundled data.
+ /// 2. If there is no file, read from the pre-bundled data.
+ public func read() throws -> StoredRelays {
do {
return try fileCache.read()
- } catch {
- if error is DecodingError || (error as? CocoaError)?.code == .fileReadNoSuchFile {
+ } catch is DecodingError {
+ do {
+ let oldFormatFileCache = FileCache<CachedRelays>(fileURL: fileURL)
+ return try StoredRelays(cachedRelays: try oldFormatFileCache.read())
+ } catch {
return try readPrebundledRelays()
- } else {
- throw error
}
+ } catch {
+ return try readPrebundledRelays()
}
}
/// Safely write the cache file on disk using file coordinator.
- public func write(record: CachedRelays) throws {
+ public func write(record: StoredRelays) throws {
try fileCache.write(record)
}
/// Read pre-bundled relays file from disk.
- public func readPrebundledRelays() throws -> CachedRelays {
+ public func readPrebundledRelays() throws -> StoredRelays {
guard let prebundledRelaysFileURL = Bundle(for: Self.self).url(forResource: "relays", withExtension: "json")
else { throw CocoaError(.fileNoSuchFile) }
let data = try Data(contentsOf: prebundledRelaysFileURL)
- let relays = try REST.Coding.makeJSONDecoder().decode(REST.ServerRelaysResponse.self, from: data)
- return CachedRelays(
- relays: relays,
+ return try StoredRelays(
+ rawData: data,
updatedAt: Date(timeIntervalSince1970: 0)
)
}
diff --git a/ios/MullvadREST/Relay/StoredRelays.swift b/ios/MullvadREST/Relay/StoredRelays.swift
new file mode 100644
index 0000000000..9700a03496
--- /dev/null
+++ b/ios/MullvadREST/Relay/StoredRelays.swift
@@ -0,0 +1,43 @@
+//
+// StoredRelays.swift
+// MullvadVPNUITests
+//
+// Created by Jon Petersson on 2024-09-09.
+// Copyright © 2024 Mullvad VPN AB. All rights reserved.
+//
+
+import Foundation
+
+/// A struct that represents the relay cache on disk
+public struct StoredRelays: Codable, Equatable {
+ /// E-tag returned by server
+ public let etag: String?
+
+ /// The raw relay JSON data stored within the cache entry
+ public let rawData: Data
+
+ /// The date when this cache was last updated
+ public let updatedAt: Date
+
+ /// Relays parsed from the JSON data
+ public let relays: REST.ServerRelaysResponse
+
+ /// `CachedRelays` representation
+ public var cachedRelays: CachedRelays {
+ CachedRelays(etag: etag, relays: relays, updatedAt: updatedAt)
+ }
+
+ public init(etag: String? = nil, rawData: Data, updatedAt: Date) throws {
+ self.etag = etag
+ self.rawData = rawData
+ self.updatedAt = updatedAt
+ relays = try REST.Coding.makeJSONDecoder().decode(REST.ServerRelaysResponse.self, from: rawData)
+ }
+
+ public init(cachedRelays: CachedRelays) throws {
+ etag = cachedRelays.etag
+ rawData = try REST.Coding.makeJSONEncoder().encode(cachedRelays.relays)
+ updatedAt = cachedRelays.updatedAt
+ relays = cachedRelays.relays
+ }
+}
diff --git a/ios/MullvadREST/Transport/Shadowsocks/ShadowsocksRelaySelector.swift b/ios/MullvadREST/Transport/Shadowsocks/ShadowsocksRelaySelector.swift
index c0d83bc701..2cc3058798 100644
--- a/ios/MullvadREST/Transport/Shadowsocks/ShadowsocksRelaySelector.swift
+++ b/ios/MullvadREST/Transport/Shadowsocks/ShadowsocksRelaySelector.swift
@@ -43,6 +43,6 @@ final public class ShadowsocksRelaySelector: ShadowsocksRelaySelectorProtocol {
public func getBridges() throws -> REST.ServerShadowsocks? {
let cachedRelays = try relayCache.read()
- return RelaySelector.Shadowsocks.tcpBridge(from: cachedRelays.relays)
+ return RelaySelector.Shadowsocks.tcpBridge(from: try cachedRelays.relays)
}
}
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index 9bee09d01b..3874f7550c 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -577,6 +577,7 @@
7A9FA1422A2E3306000B728D /* CheckboxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FA1412A2E3306000B728D /* CheckboxView.swift */; };
7A9FA1442A2E3FE5000B728D /* CheckableSettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FA1432A2E3FE5000B728D /* CheckableSettingsCell.swift */; };
7AA513862BC91C6B00D081A4 /* LogRotationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AA513852BC91C6B00D081A4 /* LogRotationTests.swift */; };
+ 7AA7046A2C8EFE2B0045699D /* StoredRelays.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AA704682C8EFE050045699D /* StoredRelays.swift */; };
7AB2B6702BA1EB8C00B03E3B /* ListCustomListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB2B66E2BA1EB8C00B03E3B /* ListCustomListViewController.swift */; };
7AB2B6712BA1EB8C00B03E3B /* ListCustomListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB2B66F2BA1EB8C00B03E3B /* ListCustomListCoordinator.swift */; };
7AB3BEB52BD7A6CB00E34384 /* LocationViewControllerWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB3BEB42BD7A6CB00E34384 /* LocationViewControllerWrapper.swift */; };
@@ -1888,6 +1889,7 @@
7A9FA1412A2E3306000B728D /* CheckboxView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxView.swift; sourceTree = "<group>"; };
7A9FA1432A2E3FE5000B728D /* CheckableSettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckableSettingsCell.swift; sourceTree = "<group>"; };
7AA513852BC91C6B00D081A4 /* LogRotationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogRotationTests.swift; sourceTree = "<group>"; };
+ 7AA704682C8EFE050045699D /* StoredRelays.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoredRelays.swift; sourceTree = "<group>"; };
7AB2B66E2BA1EB8C00B03E3B /* ListCustomListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListCustomListViewController.swift; sourceTree = "<group>"; };
7AB2B66F2BA1EB8C00B03E3B /* ListCustomListCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListCustomListCoordinator.swift; sourceTree = "<group>"; };
7AB3BEB42BD7A6CB00E34384 /* LocationViewControllerWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationViewControllerWrapper.swift; sourceTree = "<group>"; };
@@ -4159,6 +4161,7 @@
7AEBA5292C2179F20018BEC5 /* RelaySelectorWrapper.swift */,
F0B894F02BF751E300817A42 /* RelayWithDistance.swift */,
F0B894EE2BF751C500817A42 /* RelayWithLocation.swift */,
+ 7AA704682C8EFE050045699D /* StoredRelays.swift */,
);
path = Relay;
sourceTree = "<group>";
@@ -5190,6 +5193,7 @@
A90763B32B2857D50045ADF0 /* Socks5Authentication.swift in Sources */,
06799ADB28F98E4800ACD94E /* RESTProxyFactory.swift in Sources */,
F0DDE4182B220458006B57A7 /* ShadowsocksConfiguration.swift in Sources */,
+ 7AA7046A2C8EFE2B0045699D /* StoredRelays.swift in Sources */,
06799AF228F98E4800ACD94E /* RESTAccessTokenManager.swift in Sources */,
A90763B12B2857D50045ADF0 /* Socks5Endpoint.swift in Sources */,
06799AF328F98E4800ACD94E /* RESTAuthenticationProxy.swift in Sources */,
diff --git a/ios/MullvadVPN/RelayCacheTracker/RelayCacheTracker.swift b/ios/MullvadVPN/RelayCacheTracker/RelayCacheTracker.swift
index 2d2d0d384e..27f1caa1fa 100644
--- a/ios/MullvadVPN/RelayCacheTracker/RelayCacheTracker.swift
+++ b/ios/MullvadVPN/RelayCacheTracker/RelayCacheTracker.swift
@@ -63,7 +63,7 @@ final class RelayCacheTracker: RelayCacheTrackerProtocol {
cache = relayCache
do {
- cachedRelays = try cache.read()
+ cachedRelays = try cache.read().cachedRelays
try hotfixRelaysThatDoNotHaveDaita()
} catch {
logger.error(
@@ -89,8 +89,8 @@ final class RelayCacheTracker: RelayCacheTrackerProtocol {
// If the cached relays already have daita information, this fix is not necessary
guard daitaPropertyMissing else { return }
- let preBundledRelays = try cache.readPrebundledRelays()
- let preBundledDaitaRelays = preBundledRelays.relays.wireguard.relays.filter { $0.daita == true }
+ let preBundledRelays = try cache.readPrebundledRelays().relays
+ let preBundledDaitaRelays = preBundledRelays.wireguard.relays.filter { $0.daita == true }
var cachedRelaysWithFixedDaita = cachedRelays.relays.wireguard.relays
// For each daita enabled relay in the prebundled relays
@@ -119,9 +119,19 @@ final class RelayCacheTracker: RelayCacheTrackerProtocol {
bridge: cachedRelays.relays.bridge
)
- let updatedCachedRelays = CachedRelays(relays: updatedRelays, updatedAt: Date())
+ let updatedRawRelayData = try REST.Coding.makeJSONEncoder().encode(updatedRelays)
+ let updatedCachedRelays = try StoredRelays(
+ etag: cachedRelays.etag,
+ rawData: updatedRawRelayData,
+ updatedAt: cachedRelays.updatedAt
+ )
+
try cache.write(record: updatedCachedRelays)
- self.cachedRelays = updatedCachedRelays
+ self.cachedRelays = CachedRelays(
+ etag: cachedRelays.etag,
+ relays: updatedRelays,
+ updatedAt: cachedRelays.updatedAt
+ )
}
func startPeriodicUpdates() {
@@ -196,7 +206,7 @@ final class RelayCacheTracker: RelayCacheTrackerProtocol {
}
func refreshCachedRelays() throws {
- let newCachedRelays = try cache.read()
+ let newCachedRelays = try cache.read().cachedRelays
relayCacheLock.lock()
cachedRelays = newCachedRelays
@@ -244,8 +254,8 @@ final class RelayCacheTracker: RelayCacheTrackerProtocol {
-> Result<RelaysFetchResult, Error> {
result.tryMap { response -> RelaysFetchResult in
switch response {
- case let .newContent(etag, relays):
- try self.storeResponse(etag: etag, relays: relays)
+ case let .newContent(etag, rawData):
+ try self.storeResponse(etag: etag, rawData: rawData)
return .newContent
@@ -262,18 +272,14 @@ final class RelayCacheTracker: RelayCacheTrackerProtocol {
}
}
- private func storeResponse(etag: String?, relays: REST.ServerRelaysResponse) throws {
- let numRelays = relays.wireguard.relays.count
-
- logger.info("Downloaded \(numRelays) relays.")
-
- let newCachedRelays = CachedRelays(
+ private func storeResponse(etag: String?, rawData: Data) throws {
+ let newCachedData = try StoredRelays(
etag: etag,
- relays: relays,
+ rawData: rawData,
updatedAt: Date()
)
- try cache.write(record: newCachedRelays)
+ try cache.write(record: newCachedData)
try refreshCachedRelays()
}
diff --git a/ios/MullvadVPNTests/MullvadREST/Relay/RelayCacheTests.swift b/ios/MullvadVPNTests/MullvadREST/Relay/RelayCacheTests.swift
index fffd9e3383..6d96995742 100644
--- a/ios/MullvadVPNTests/MullvadREST/Relay/RelayCacheTests.swift
+++ b/ios/MullvadVPNTests/MullvadREST/Relay/RelayCacheTests.swift
@@ -12,7 +12,7 @@ import XCTest
final class RelayCacheTests: XCTestCase {
func testReadCache() throws {
let fileCache = MockFileCache(
- initialState: .exists(CachedRelays(relays: .mock(), updatedAt: .distantPast))
+ initialState: .exists(try StoredRelays(rawData: try .mock(), updatedAt: .distantPast))
)
let cache = RelayCache(fileCache: fileCache)
let relays = try XCTUnwrap(cache.read())
@@ -22,17 +22,17 @@ final class RelayCacheTests: XCTestCase {
func testWriteCache() throws {
let fileCache = MockFileCache(
- initialState: .exists(CachedRelays(relays: .mock(), updatedAt: .distantPast))
+ initialState: .exists(try StoredRelays(rawData: try .mock(), updatedAt: .distantPast))
)
let cache = RelayCache(fileCache: fileCache)
- let newCachedRelays = CachedRelays(relays: .mock(), updatedAt: Date())
+ let newCachedRelays = try StoredRelays(rawData: try .mock(), updatedAt: Date())
try cache.write(record: newCachedRelays)
XCTAssertEqual(fileCache.getState(), .exists(newCachedRelays))
}
func testReadPrebundledRelaysWhenNoCacheIsStored() throws {
- let fileCache = MockFileCache<CachedRelays>(initialState: .fileNotFound)
+ let fileCache = MockFileCache<StoredRelays>(initialState: .fileNotFound)
let cache = RelayCache(fileCache: fileCache)
XCTAssertNoThrow(try cache.read())
@@ -42,7 +42,7 @@ final class RelayCacheTests: XCTestCase {
extension REST.ServerRelaysResponse {
static func mock(
serverRelays: [REST.ServerRelay] = [],
- brideRelays: [REST.BridgeRelay] = []
+ bridgeRelays: [REST.BridgeRelay] = []
) -> Self {
REST.ServerRelaysResponse(
locations: [:],
@@ -52,7 +52,17 @@ extension REST.ServerRelaysResponse {
portRanges: [],
relays: serverRelays
),
- bridge: REST.ServerBridges(shadowsocks: [], relays: brideRelays)
+ bridge: REST.ServerBridges(shadowsocks: [], relays: bridgeRelays)
)
}
}
+
+extension Data {
+ static func mock(
+ serverRelays: [REST.ServerRelay] = [],
+ bridgeRelays: [REST.BridgeRelay] = []
+ ) throws -> Data {
+ let relays = REST.ServerRelaysResponse.mock(serverRelays: serverRelays, bridgeRelays: bridgeRelays)
+ return try REST.Coding.makeJSONEncoder().encode(relays)
+ }
+}
diff --git a/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorWrapperTests.swift b/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorWrapperTests.swift
index 2cd6b37c9c..beca599c5f 100644
--- a/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorWrapperTests.swift
+++ b/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorWrapperTests.swift
@@ -12,12 +12,6 @@
import XCTest
class RelaySelectorWrapperTests: XCTestCase {
- let fileCache = MockFileCache(
- initialState: .exists(CachedRelays(
- relays: ServerRelaysResponseStubs.sampleRelays,
- updatedAt: .distantPast
- ))
- )
let multihopWithDaitaConstraints = RelayConstraints(
entryLocations: .only(UserSelectedRelays(locations: [.country("es")])), // Relay with DAITA.
exitLocations: .only(UserSelectedRelays(locations: [.country("us")]))
@@ -37,7 +31,14 @@ class RelaySelectorWrapperTests: XCTestCase {
)
var relayCache: RelayCache!
- override func setUp() {
+ override func setUpWithError() throws {
+ let fileCache = MockFileCache(
+ initialState: .exists(try StoredRelays(
+ rawData: try REST.Coding.makeJSONEncoder().encode(ServerRelaysResponseStubs.sampleRelays),
+ updatedAt: .distantPast
+ ))
+ )
+
relayCache = RelayCache(fileCache: fileCache)
}
diff --git a/ios/MullvadVPNTests/MullvadSettings/IPOverrideWrapperTests.swift b/ios/MullvadVPNTests/MullvadSettings/IPOverrideWrapperTests.swift
index a5e0d742e6..c694f50f90 100644
--- a/ios/MullvadVPNTests/MullvadSettings/IPOverrideWrapperTests.swift
+++ b/ios/MullvadVPNTests/MullvadSettings/IPOverrideWrapperTests.swift
@@ -19,7 +19,7 @@ final class IPOverrideWrapperTests: XCTestCase {
]
let fileCache = MockFileCache(
- initialState: .exists(CachedRelays(relays: .mock(serverRelays: relays), updatedAt: .distantPast))
+ initialState: .exists(try StoredRelays(rawData: try .mock(serverRelays: relays), updatedAt: .distantPast))
)
let override = try IPOverride(hostname: "Host 1", ipv4Address: .loopback, ipv6Address: .broadcast)
@@ -32,12 +32,12 @@ final class IPOverrideWrapperTests: XCTestCase {
let storedCache = try overrideWrapper.read()
// Assert that relay was overridden.
- let host1 = storedCache.relays.wireguard.relays.first
+ let host1 = try storedCache.relays.wireguard.relays.first
XCTAssertEqual(host1?.ipv4AddrIn, .loopback)
XCTAssertEqual(host1?.ipv6AddrIn, .broadcast)
// Assert that relay was NOT overridden.
- let host2 = storedCache.relays.wireguard.relays.last
+ let host2 = try storedCache.relays.wireguard.relays.last
XCTAssertEqual(host2?.ipv4AddrIn, .any)
XCTAssertEqual(host2?.ipv6AddrIn, .any)
}
@@ -49,7 +49,7 @@ final class IPOverrideWrapperTests: XCTestCase {
]
let fileCache = MockFileCache(
- initialState: .exists(CachedRelays(relays: .mock(brideRelays: relays), updatedAt: .distantPast))
+ initialState: .exists(try StoredRelays(rawData: try .mock(bridgeRelays: relays), updatedAt: .distantPast))
)
let override = try IPOverride(hostname: "Host 1", ipv4Address: .loopback, ipv6Address: .broadcast)
@@ -62,11 +62,11 @@ final class IPOverrideWrapperTests: XCTestCase {
let storedCache = try overrideWrapper.read()
// Assert that relay was overridden.
- let host1 = storedCache.relays.bridge.relays.first
+ let host1 = try storedCache.relays.bridge.relays.first
XCTAssertEqual(host1?.ipv4AddrIn, .loopback)
// Assert that relay was NOT overridden.
- let host2 = storedCache.relays.bridge.relays.last
+ let host2 = try storedCache.relays.bridge.relays.last
XCTAssertEqual(host2?.ipv4AddrIn, .any)
}
}
diff --git a/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift b/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift
index 8c76b54312..b33f6e5af2 100644
--- a/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift
+++ b/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift
@@ -115,6 +115,7 @@ class TunnelManagerTests: XCTestCase {
}
/// This test verifies tunnel gets out of `blockedState` after constraints are satisfied.
+ // swiftlint:disable:next function_body_length
func testExitBlockedStateAfterSatisfyingConstraints() async throws {
let blockedExpectation = expectation(description: "Relay constraints aren't satisfied!")
let connectedExpectation = expectation(description: "Connected!")
diff --git a/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift b/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift
index f266a602a1..00a067342b 100644
--- a/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift
+++ b/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift
@@ -209,7 +209,6 @@ final class PacketTunnelActorTests: XCTestCase {
3. The issue goes away on the second attempt to read settings.
4. An actor should transition through `.connecting` towards`.connected` state.
*/
- // swiftlint:disable:next function_body_length
func testLockedDeviceErrorOnBoot() async throws {
let initialStateExpectation = expectation(description: "Expect initial state")
let errorStateExpectation = expectation(description: "Expect error state")