summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2022-06-08 12:23:57 +0200
committerAndrej Mihajlov <and@mullvad.net>2022-06-08 12:31:16 +0200
commit24d1318b92113ef92703d504e90587b052959b31 (patch)
tree6a1879bdfe92f7fbe16a69a35911e3bf813e56d8
parenta003d0c2a63042e339456f2566c7d0e2b9ae95b1 (diff)
downloadmullvadvpn-24d1318b92113ef92703d504e90587b052959b31.tar.xz
mullvadvpn-24d1318b92113ef92703d504e90587b052959b31.zip
Add tests
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj40
-rw-r--r--ios/MullvadVPNTests/OperationConditionTests.swift144
-rw-r--r--ios/MullvadVPNTests/OperationObserverTests.swift68
3 files changed, 244 insertions, 8 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index 3f4b6b5e80..6d6c7ff27b 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -21,6 +21,7 @@
58095C552760F02500890776 /* UpdateAddressCacheOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58095C542760F02500890776 /* UpdateAddressCacheOperation.swift */; };
58095C572760F47900890776 /* api-ip-address.json in Resources */ = {isa = PBXBuildFile; fileRef = 58095C562760F47900890776 /* api-ip-address.json */; };
58095C592762155700890776 /* RESTRetryStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58095C582762155700890776 /* RESTRetryStrategy.swift */; };
+ 580CBFB82848D503007878F0 /* OperationConditionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580CBFB72848D503007878F0 /* OperationConditionTests.swift */; };
580EE22424B3243100F9D8A1 /* AsyncBlockOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580EE22324B3243100F9D8A1 /* AsyncBlockOperation.swift */; };
580F8B8328197881002E0998 /* TunnelSettingsV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580F8B8228197881002E0998 /* TunnelSettingsV2.swift */; };
580F8B8428197884002E0998 /* TunnelSettingsV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580F8B8228197881002E0998 /* TunnelSettingsV2.swift */; };
@@ -71,6 +72,16 @@
5838318B27C40A3900000571 /* Pinger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5838318A27C40A3900000571 /* Pinger.swift */; };
583DA21425FA4B5C00318683 /* LocationDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583DA21325FA4B5C00318683 /* LocationDataSource.swift */; };
583E1E1B2848DE1C004838B3 /* ResultOperation+Fallible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58059DE128468255002B1049 /* ResultOperation+Fallible.swift */; };
+ 583E1E1C2848DE1C004838B3 /* AsyncOperationQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 589D28782846250500F9A7B3 /* AsyncOperationQueue.swift */; };
+ 583E1E1E2848DE1C004838B3 /* OperationCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 589D28772846250500F9A7B3 /* OperationCondition.swift */; };
+ 583E1E202848DE1C004838B3 /* OperationObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 589D28792846250500F9A7B3 /* OperationObserver.swift */; };
+ 583E1E222848DE1C004838B3 /* GroupOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 589D28812846306C00F9A7B3 /* GroupOperation.swift */; };
+ 583E1E232848DE1C004838B3 /* OperationCompletion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5840BE34279EDB16002836BA /* OperationCompletion.swift */; };
+ 583E1E252848DE1C004838B3 /* ResultOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F7D26427EB50A300E4D821 /* ResultOperation.swift */; };
+ 583E1E262848DE1C004838B3 /* ResultBlockOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5842102D282D3FC200F24E46 /* ResultBlockOperation.swift */; };
+ 583E1E282848DE1C004838B3 /* BackgroundObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 589D287F28462CB000F9A7B3 /* BackgroundObserver.swift */; };
+ 583E1E2A2848DF67004838B3 /* OperationObserverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583E1E292848DF67004838B3 /* OperationObserverTests.swift */; };
+ 583E1E2C2848E1A1004838B3 /* WireGuardKitTypes in Frameworks */ = {isa = PBXBuildFile; productRef = 583E1E2B2848E1A1004838B3 /* WireGuardKitTypes */; };
5840250122B1124600E4CFEC /* IPAddress+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5840250022B1124600E4CFEC /* IPAddress+Codable.swift */; };
5840250222B1124600E4CFEC /* IPAddress+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5840250022B1124600E4CFEC /* IPAddress+Codable.swift */; };
5840250422B11AB700E4CFEC /* MullvadEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5840250322B11AB700E4CFEC /* MullvadEndpoint.swift */; };
@@ -177,7 +188,6 @@
5883A09E266A5AF7003EFFCB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 587B7543266922BF00DEF7E9 /* Localizable.strings */; };
588527B2276B3F0700BAA373 /* LoadTunnelConfigurationOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 588527B1276B3F0700BAA373 /* LoadTunnelConfigurationOperation.swift */; };
588527B4276B4F2F00BAA373 /* SetAccountOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 588527B3276B4F2F00BAA373 /* SetAccountOperation.swift */; };
- 58871D1E25D535A3002297FA /* WireGuardKit in Frameworks */ = {isa = PBXBuildFile; productRef = 58871D1D25D535A3002297FA /* WireGuardKit */; };
58871D2325D535D2002297FA /* IPAddressRange+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5850366725A47AC700A43E93 /* IPAddressRange+Codable.swift */; };
5888AD83227B11080051EB06 /* SelectLocationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5888AD82227B11080051EB06 /* SelectLocationCell.swift */; };
5888AD87227B17950051EB06 /* SelectLocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5888AD86227B17950051EB06 /* SelectLocationViewController.swift */; };
@@ -345,6 +355,7 @@
58095C542760F02500890776 /* UpdateAddressCacheOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateAddressCacheOperation.swift; sourceTree = "<group>"; };
58095C562760F47900890776 /* api-ip-address.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "api-ip-address.json"; sourceTree = "<group>"; };
58095C582762155700890776 /* RESTRetryStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RESTRetryStrategy.swift; sourceTree = "<group>"; };
+ 580CBFB72848D503007878F0 /* OperationConditionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationConditionTests.swift; sourceTree = "<group>"; };
580EE22324B3243100F9D8A1 /* AsyncBlockOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncBlockOperation.swift; sourceTree = "<group>"; };
580F8B8228197881002E0998 /* TunnelSettingsV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelSettingsV2.swift; sourceTree = "<group>"; };
580F8B8528197958002E0998 /* DNSSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSSettings.swift; sourceTree = "<group>"; };
@@ -378,6 +389,7 @@
5835B7CB233B76CB0096D79F /* TunnelManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelManager.swift; sourceTree = "<group>"; };
5838318A27C40A3900000571 /* Pinger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pinger.swift; sourceTree = "<group>"; };
583DA21325FA4B5C00318683 /* LocationDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationDataSource.swift; sourceTree = "<group>"; };
+ 583E1E292848DF67004838B3 /* OperationObserverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationObserverTests.swift; sourceTree = "<group>"; };
5840250022B1124600E4CFEC /* IPAddress+Codable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IPAddress+Codable.swift"; sourceTree = "<group>"; };
5840250322B11AB700E4CFEC /* MullvadEndpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MullvadEndpoint.swift; sourceTree = "<group>"; };
5840BE34279EDB16002836BA /* OperationCompletion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationCompletion.swift; sourceTree = "<group>"; };
@@ -560,8 +572,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 583E1E2C2848E1A1004838B3 /* WireGuardKitTypes in Frameworks */,
584789EC2652A1A2000E45FB /* Logging in Frameworks */,
- 58871D1E25D535A3002297FA /* WireGuardKit in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -778,6 +790,8 @@
58B0A2A1238EE67E00BC001D /* MullvadVPNTests */ = {
isa = PBXGroup;
children = (
+ 583E1E292848DF67004838B3 /* OperationObserverTests.swift */,
+ 580CBFB72848D503007878F0 /* OperationConditionTests.swift */,
582AE3112440CA0D00E6733A /* AccountTokenInputTests.swift */,
5896AE85246D6AD8005B36CB /* CustomDateComponentsFormattingTests.swift */,
58B0A2A4238EE67E00BC001D /* Info.plist */,
@@ -1017,8 +1031,8 @@
);
name = MullvadVPNTests;
packageProductDependencies = (
- 58871D1D25D535A3002297FA /* WireGuardKit */,
584789EB2652A1A2000E45FB /* Logging */,
+ 583E1E2B2848E1A1004838B3 /* WireGuardKitTypes */,
);
productName = MullvadVPNTests;
productReference = 58B0A2A0238EE67E00BC001D /* MullvadVPNTests.xctest */;
@@ -1202,6 +1216,8 @@
files = (
582AE3132440CA2700E6733A /* AccountTokenInput.swift in Sources */,
58CAF4EF26025954007C5886 /* SimulatorTunnelProvider.swift in Sources */,
+ 583E1E232848DE1C004838B3 /* OperationCompletion.swift in Sources */,
+ 583E1E222848DE1C004838B3 /* GroupOperation.swift in Sources */,
58B0A2AA238EE6A900BC001D /* RelaySelector.swift in Sources */,
5896AE86246D6AD8005B36CB /* CustomDateComponentsFormattingTests.swift in Sources */,
5807E2C3243203E700F5FF30 /* String+Split.swift in Sources */,
@@ -1213,20 +1229,28 @@
58B0A2AC238EE6D500BC001D /* IPAddress+Codable.swift in Sources */,
58B0A2AD238EE6EC00BC001D /* MullvadEndpoint.swift in Sources */,
58FAEDF4245088B300CB0F5B /* KeychainError.swift in Sources */,
+ 583E1E252848DE1C004838B3 /* ResultOperation.swift in Sources */,
+ 583E1E262848DE1C004838B3 /* ResultBlockOperation.swift in Sources */,
+ 583E1E2A2848DF67004838B3 /* OperationObserverTests.swift in Sources */,
5896AE88246D7FAF005B36CB /* CustomDateComponentsFormatting.swift in Sources */,
5857F23824C8446700CF6F47 /* AsyncBlockOperation.swift in Sources */,
582AE3122440CA0D00E6733A /* AccountTokenInputTests.swift in Sources */,
585DA8A526B14EE000B8C587 /* PacketTunnelStatus.swift in Sources */,
58B0A2A9238EE6A100BC001D /* RelayConstraints.swift in Sources */,
+ 583E1E282848DE1C004838B3 /* BackgroundObserver.swift in Sources */,
5807E2C2243203D000F5FF30 /* StringTests.swift in Sources */,
5819C2142726CC8D00D6EC38 /* DataSourceSnapshotTests.swift in Sources */,
585DA8A326B14E0D00B8C587 /* ServerRelaysResponse.swift in Sources */,
+ 583E1E1E2848DE1C004838B3 /* OperationCondition.swift in Sources */,
+ 583E1E1C2848DE1C004838B3 /* AsyncOperationQueue.swift in Sources */,
5820676226E75D8500655B05 /* REST.swift in Sources */,
58A8055E2716EA6700681642 /* AnyIPAddress.swift in Sources */,
583E1E1B2848DE1C004838B3 /* ResultOperation+Fallible.swift in Sources */,
5857F23024C843ED00CF6F47 /* ChainedError.swift in Sources */,
58A8BE81239FBE62006B74AC /* IPEndpoint.swift in Sources */,
58871D2325D535D2002297FA /* IPAddressRange+Codable.swift in Sources */,
+ 580CBFB82848D503007878F0 /* OperationConditionTests.swift in Sources */,
+ 583E1E202848DE1C004838B3 /* OperationObserver.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1907,6 +1931,11 @@
package = 58BA79192578F092006FAEA0 /* XCRemoteSwiftPackageReference "wireguard-apple" */;
productName = WireGuardKitTypes;
};
+ 583E1E2B2848E1A1004838B3 /* WireGuardKitTypes */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 58BA79192578F092006FAEA0 /* XCRemoteSwiftPackageReference "wireguard-apple" */;
+ productName = WireGuardKitTypes;
+ };
584789EB2652A1A2000E45FB /* Logging */ = {
isa = XCSwiftPackageProductDependency;
package = 585834F624D2BC1F00A8AF56 /* XCRemoteSwiftPackageReference "swift-log" */;
@@ -1922,11 +1951,6 @@
package = 585834F624D2BC1F00A8AF56 /* XCRemoteSwiftPackageReference "swift-log" */;
productName = Logging;
};
- 58871D1D25D535A3002297FA /* WireGuardKit */ = {
- isa = XCSwiftPackageProductDependency;
- package = 58BA79192578F092006FAEA0 /* XCRemoteSwiftPackageReference "wireguard-apple" */;
- productName = WireGuardKit;
- };
58BA791A2578F092006FAEA0 /* WireGuardKit */ = {
isa = XCSwiftPackageProductDependency;
package = 58BA79192578F092006FAEA0 /* XCRemoteSwiftPackageReference "wireguard-apple" */;
diff --git a/ios/MullvadVPNTests/OperationConditionTests.swift b/ios/MullvadVPNTests/OperationConditionTests.swift
new file mode 100644
index 0000000000..297b8128ee
--- /dev/null
+++ b/ios/MullvadVPNTests/OperationConditionTests.swift
@@ -0,0 +1,144 @@
+//
+// OperationConditionTests.swift
+// MullvadVPNTests
+//
+// Created by pronebird on 02/06/2022.
+// Copyright © 2022 Mullvad VPN AB. All rights reserved.
+//
+
+import XCTest
+
+class OperationConditionTests: XCTestCase {
+ func testTrueCondition() {
+ let expectConditionEvaluation = expectation(description: "Expect condition evaluation")
+ let expectOperationToExecute = expectation(description: "Expect operation to execute")
+
+ let operation = AsyncBlockOperation {
+ expectOperationToExecute.fulfill()
+ }
+
+ let blockCondition = BlockCondition { op, completion in
+ expectConditionEvaluation.fulfill()
+ completion(true)
+ }
+
+ operation.addCondition(blockCondition)
+
+ let operationQueue = AsyncOperationQueue()
+ operationQueue.addOperation(operation)
+
+ waitForExpectations(timeout: 1)
+ }
+
+ func testFalseCondition() {
+ let expectConditionEvaluation = expectation(description: "Expect condition evaluation")
+ let expectOperationToNeverExecute = expectation(
+ description: "Expect operation to never execute"
+ )
+ expectOperationToNeverExecute.isInverted = true
+
+ let operation = AsyncBlockOperation {
+ expectOperationToNeverExecute.fulfill()
+ }
+
+ let blockCondition = BlockCondition { op, completion in
+ expectConditionEvaluation.fulfill()
+ completion(false)
+ }
+
+ operation.addCondition(blockCondition)
+
+ let operationQueue = AsyncOperationQueue()
+ operationQueue.addOperation(operation)
+
+ waitForExpectations(timeout: 1)
+ }
+
+ func testNoCancelledDependenciesCondition() {
+ let expectToNeverExecute = expectation(description: "Expect child to never execute.")
+ expectToNeverExecute.isInverted = true
+
+ let parent = BlockOperation()
+ parent.cancel()
+
+ let child = AsyncBlockOperation {
+ expectToNeverExecute.fulfill()
+ }
+ child.addDependency(parent)
+ child.addCondition(NoCancelledDependenciesCondition())
+
+ let operationQueue = AsyncOperationQueue()
+ operationQueue.addOperations([parent, child], waitUntilFinished: false)
+
+ waitForExpectations(timeout: 1)
+ }
+
+ func testNoFailedDependenciesCondition() {
+ let expectToNeverExecute = expectation(description: "Expect child to never execute.")
+ expectToNeverExecute.isInverted = true
+
+ let parent = ResultBlockOperation<(), URLError> {
+ throw URLError(.badURL)
+ }
+
+ let child = AsyncBlockOperation {
+ expectToNeverExecute.fulfill()
+ }
+ child.addDependency(parent)
+ child.addCondition(NoFailedDependenciesCondition(ignoreCancellations: false))
+
+ let operationQueue = AsyncOperationQueue()
+ operationQueue.addOperations([parent, child], waitUntilFinished: false)
+
+ waitForExpectations(timeout: 1)
+ }
+
+ func testNoFailedDependenciesIgnoringCancellationsCondition() {
+ let expectToExecute = expectation(description: "Expect child to execute.")
+
+ let parent = BlockOperation()
+ parent.cancel()
+
+ let child = AsyncBlockOperation {
+ expectToExecute.fulfill()
+ }
+ child.addDependency(parent)
+ child.addCondition(NoFailedDependenciesCondition(ignoreCancellations: true))
+
+ let operationQueue = AsyncOperationQueue()
+ operationQueue.addOperations([parent, child], waitUntilFinished: false)
+
+ waitForExpectations(timeout: 1)
+ }
+
+ func testMutuallyExclusiveCondition() {
+ let expectFirstOperationExecution = expectation(
+ description: "Expect first operation to execute first"
+ )
+ let expectSecondOperationExecution = expectation(
+ description: "Expect second operation to execute last"
+ )
+
+ let exclusiveCategory = "exclusiveOperations"
+ let operationQueue = AsyncOperationQueue()
+
+ let firstOperation = AsyncBlockOperation { op in
+ DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
+ expectFirstOperationExecution.fulfill()
+ op.finish()
+ }
+ }
+ firstOperation.addCondition(MutuallyExclusive(category: exclusiveCategory))
+
+ let secondOperation = AsyncBlockOperation {
+ expectSecondOperationExecution.fulfill()
+ }
+ secondOperation.addCondition(MutuallyExclusive(category: exclusiveCategory))
+
+ operationQueue.addOperations([firstOperation, secondOperation], waitUntilFinished: false)
+
+ let expectations = [expectFirstOperationExecution, expectSecondOperationExecution]
+ wait(for: expectations, timeout: 2, enforceOrder: true)
+ }
+
+}
diff --git a/ios/MullvadVPNTests/OperationObserverTests.swift b/ios/MullvadVPNTests/OperationObserverTests.swift
new file mode 100644
index 0000000000..ab4c29f6e3
--- /dev/null
+++ b/ios/MullvadVPNTests/OperationObserverTests.swift
@@ -0,0 +1,68 @@
+//
+// OperationObserverTests.swift
+// MullvadVPNTests
+//
+// Created by pronebird on 02/06/2022.
+// Copyright © 2022 Mullvad VPN AB. All rights reserved.
+//
+
+import XCTest
+
+class OperationObserverTests: XCTestCase {
+
+ func testBlockObserver() throws {
+ let expectDidAttach = expectation(description: "didAttach handler")
+ let expectDidStart = expectation(description: "didStart handler")
+ let expectDidCancel = expectation(description: "didCancel handler")
+ expectDidCancel.isInverted = true
+ let expectDidFinish = expectation(description: "didAttach handler")
+
+ let operation = AsyncBlockOperation()
+ operation.addBlockObserver(OperationBlockObserver(
+ didAttach: { op in
+ expectDidAttach.fulfill()
+ }, didStart: { op in
+ expectDidStart.fulfill()
+ }, didCancel: { op in
+ expectDidCancel.fulfill()
+ }, didFinish: { op in
+ expectDidFinish.fulfill()
+ }
+ ))
+
+ let operationQueue = AsyncOperationQueue()
+ operationQueue.addOperation(operation)
+
+ let expectations = [expectDidCancel, expectDidAttach, expectDidStart, expectDidFinish]
+ wait(for: expectations, timeout: 1, enforceOrder: true)
+ }
+
+ func testBlockObserverWithCancelledOperation() {
+ let expectDidAttach = expectation(description: "didAttach handler")
+ let expectDidStart = expectation(description: "didStart handler")
+ expectDidStart.isInverted = true
+ let expectDidCancel = expectation(description: "didCancel handler")
+ let expectDidFinish = expectation(description: "didAttach handler")
+
+ let operation = AsyncBlockOperation()
+ operation.addBlockObserver(OperationBlockObserver(
+ didAttach: { op in
+ expectDidAttach.fulfill()
+ }, didStart: { op in
+ expectDidStart.fulfill()
+ }, didCancel: { op in
+ expectDidCancel.fulfill()
+ }, didFinish: { op in
+ expectDidFinish.fulfill()
+ }
+ ))
+ operation.cancel()
+
+ let operationQueue = AsyncOperationQueue()
+ operationQueue.addOperation(operation)
+
+ let expectations = [expectDidAttach, expectDidCancel, expectDidStart, expectDidFinish]
+ wait(for: expectations, timeout: 1, enforceOrder: true)
+ }
+
+}