]> git.saurik.com Git - apple/security.git/blob - keychain/ot/tests/octagon/OctagonDataPersistenceTests.swift
0b457d231af78a482a1dfa84d2632a1c95e78405
[apple/security.git] / keychain / ot / tests / octagon / OctagonDataPersistenceTests.swift
1 import XCTest
2
3 #if OCTAGON
4
5 class OctagonAccountMetadataClassCPersistenceTests: CloudKitKeychainSyncingMockXCTest {
6
7 override static func setUp() {
8 super.setUp()
9
10 // Turn on NO_SERVER stuff
11 securityd_init_local_spi()
12 }
13
14 func testSaveAndLoad() throws {
15 XCTAssertThrowsError(try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext),
16 "Before doing anything, loading a non-existent account state should fail")
17
18 let state: OTAccountMetadataClassC! = OTAccountMetadataClassC()
19 state.peerID = "asdf"
20 state.icloudAccountState = .ACCOUNT_AVAILABLE
21 state.trustState = .TRUSTED
22
23 XCTAssertNoThrow(try state.saveToKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext), "saving to the keychain should work")
24
25 do {
26 let state2 = try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext)
27 XCTAssertNotNil(state2)
28 XCTAssertEqual(state2.peerID, state.peerID, "peer ID persists through keychain")
29 XCTAssertEqual(state2.icloudAccountState, state.icloudAccountState, "account state persists through keychain")
30 XCTAssertEqual(state2.trustState, state.trustState, "trust state persists through keychain")
31 } catch {
32 XCTFail("error loading from keychain: \(error)")
33 }
34 }
35
36 func testSilentOverwrite() throws {
37 XCTAssertThrowsError(try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext),
38 "Before doing anything, loading a non-existent account state should fail")
39
40 let state: OTAccountMetadataClassC! = OTAccountMetadataClassC()
41 state.peerID = "asdf"
42 state.icloudAccountState = .ACCOUNT_AVAILABLE
43 state.trustState = .TRUSTED
44
45 XCTAssertNoThrow(try state.saveToKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext), "saving to the keychain should work")
46
47 state.peerID = "no wait another peer id"
48 state.icloudAccountState = .ACCOUNT_AVAILABLE
49 state.trustState = .UNTRUSTED
50
51 XCTAssertNoThrow(try state.saveToKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext), "saving to the keychain should work")
52
53 do {
54 let state2 = try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext)
55 XCTAssertNotNil(state2)
56 XCTAssertEqual(state2.peerID, "no wait another peer id", "peer ID persists through keychain")
57 XCTAssertEqual(state2.icloudAccountState, .ACCOUNT_AVAILABLE, "account state persists through keychain")
58 XCTAssertEqual(state2.trustState, .UNTRUSTED, "trust state persists through keychain")
59 } catch {
60 XCTFail("error loading from keychain: \(error)")
61 }
62 }
63
64 func testContainerIndependence() throws {
65 let state1: OTAccountMetadataClassC! = OTAccountMetadataClassC()
66 state1.peerID = "asdf"
67 state1.icloudAccountState = .ACCOUNT_AVAILABLE
68 state1.trustState = .TRUSTED
69
70 let state2: OTAccountMetadataClassC! = OTAccountMetadataClassC()
71 state2.peerID = "anotherPeerID"
72 state2.icloudAccountState = .ACCOUNT_AVAILABLE
73 state2.trustState = .UNTRUSTED
74
75 XCTAssertNoThrow(try state1.saveToKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext), "saving to the keychain should work")
76 XCTAssertNoThrow(try state2.saveToKeychain(forContainer: "second_container", contextID: OTDefaultContext), "saving to the keychain should work")
77
78 do {
79 let state1reloaded = try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext)
80 XCTAssertNotNil(state1reloaded)
81 XCTAssertEqual(state1reloaded.peerID, state1.peerID, "peer ID persists through keychain")
82 XCTAssertEqual(state1reloaded.icloudAccountState, state1.icloudAccountState, "account state persists through keychain")
83 XCTAssertEqual(state1reloaded.trustState, state1.trustState, "trust state persists through keychain")
84 } catch {
85 XCTFail("error loading state1 from keychain: \(error)")
86 }
87
88 do {
89 let state2reloaded = try OTAccountMetadataClassC.loadFromKeychain(forContainer: "second_container", contextID: OTDefaultContext)
90 XCTAssertNotNil(state2reloaded)
91 XCTAssertEqual(state2reloaded.peerID, state2.peerID, "peer ID persists through keychain")
92 XCTAssertEqual(state2reloaded.icloudAccountState, state2.icloudAccountState, "account state persists through keychain")
93 XCTAssertEqual(state2reloaded.trustState, state2.trustState, "trust state persists through keychain")
94 } catch {
95 XCTFail("error loading state2 from keychain: \(error)")
96 }
97 }
98
99 func testContextIndependence() throws {
100 let state1: OTAccountMetadataClassC! = OTAccountMetadataClassC()
101 state1.peerID = "asdf"
102 state1.icloudAccountState = .ACCOUNT_AVAILABLE
103 state1.trustState = .TRUSTED
104
105 let state2: OTAccountMetadataClassC! = OTAccountMetadataClassC()
106 state2.peerID = "anotherPeerID"
107 state2.icloudAccountState = .ACCOUNT_AVAILABLE
108 state2.trustState = .UNTRUSTED
109
110 XCTAssertNoThrow(try state1.saveToKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext), "saving to the keychain should work")
111 XCTAssertNoThrow(try state2.saveToKeychain(forContainer: OTCKContainerName, contextID: "second_context"), "saving to the keychain should work")
112
113 do {
114 let state1reloaded = try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext)
115 XCTAssertNotNil(state1reloaded)
116 XCTAssertEqual(state1reloaded.peerID, state1.peerID, "peer ID persists through keychain")
117 XCTAssertEqual(state1reloaded.icloudAccountState, state1.icloudAccountState, "account state persists through keychain")
118 XCTAssertEqual(state1reloaded.trustState, state1.trustState, "trust state persists through keychain")
119 } catch {
120 XCTFail("error loading state1 from keychain: \(error)")
121 }
122
123 do {
124 let state2reloaded = try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: "second_context")
125 XCTAssertNotNil(state2reloaded)
126 XCTAssertEqual(state2reloaded.peerID, state2.peerID, "peer ID persists through keychain")
127 XCTAssertEqual(state2reloaded.icloudAccountState, state2.icloudAccountState, "account state persists through keychain")
128 XCTAssertEqual(state2reloaded.trustState, state2.trustState, "trust state persists through keychain")
129 } catch {
130 XCTFail("error loading state2 from keychain: \(error)")
131 }
132 }
133
134 func testLoadCorruptedAccountState() throws {
135 XCTAssertThrowsError(try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext),
136 "Before doing anything, loading a non-existent account state should fail")
137
138 let state: OTAccountMetadataClassC! = OTAccountMetadataClassC()
139 state.peerID = "asdf"
140 state.icloudAccountState = .ACCOUNT_AVAILABLE
141 state.trustState = .TRUSTED
142
143 XCTAssertNoThrow(try TestsObjectiveC.saveCoruptDataToKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext), "saving to the keychain should work")
144
145 do {
146 let state2 = try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext)
147 XCTAssertNotNil(state2)
148 XCTAssertEqual(state2.peerID, nil, "peerID should be nil")
149 XCTAssertEqual(state2.icloudAccountState, OTAccountMetadataClassC_AccountState.UNKNOWN, "account state should be OTAccountMetadataClassC_AccountState_UNKNOWN")
150 XCTAssertEqual(state2.trustState, OTAccountMetadataClassC_TrustState.UNKNOWN, "trust state should be OTAccountMetadataClassC_TrustState_UNKNOWN")
151 } catch {
152 XCTFail("error loading from keychain: \(error)")
153 }
154 }
155
156 func testDeleteFromKeychain() throws {
157 let state: OTAccountMetadataClassC! = OTAccountMetadataClassC()
158 state.peerID = "asdf"
159 state.icloudAccountState = .ACCOUNT_AVAILABLE
160 state.trustState = .TRUSTED
161 XCTAssertNoThrow(try state.saveToKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext), "saving to the keychain should work")
162
163 let deleted: Bool = try OTAccountMetadataClassC.deleteFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext)
164 XCTAssertTrue(deleted, "deleteFromKeychain should return true")
165 XCTAssertThrowsError(try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext))
166 }
167 }
168
169 #endif // OCTAGON