5 // Created by Mitch Adler on 6/18/13.
9 #ifndef SEC_SOSAccountTesting_h
10 #define SEC_SOSAccountTesting_h
12 #include <CoreFoundation/CoreFoundation.h>
13 #include <SecureObjectSync/SOSAccount.h>
19 #define kAccountsAgreeTestMin 9
20 #define kAccountsAgreeTestPerPeer 1
21 #define accountsAgree(x) (kAccountsAgreeTestMin + kAccountsAgreeTestPerPeer * (x))
23 static void unretired_peers_is_subset(const char* label
, CFArrayRef peers
, CFArrayRef allowed_peers
)
25 CFArrayForEach(peers
, ^(const void *value
) {
26 SOSPeerInfoRef pi
= (SOSPeerInfoRef
) value
;
27 CFErrorRef leftError
= NULL
;
28 CFErrorRef rightError
= NULL
;
30 ok(SOSPeerInfoIsRetirementTicket(pi
) || SOSPeerInfoIsCloudIdentity(pi
) || CFArrayContainsValue(allowed_peers
, CFRangeMake(0, CFArrayGetCount(allowed_peers
)), pi
), "Peer is allowed (%s) Peer: %@, Allowed %@", label
, pi
, allowed_peers
);
32 CFReleaseNull(leftError
);
33 CFReleaseNull(rightError
);
37 static void accounts_agree_internal(char *label
, SOSAccountRef left
, SOSAccountRef right
, bool check_peers
)
39 CFErrorRef error
= NULL
;
41 CFArrayRef leftPeers
= SOSAccountCopyActivePeers(left
, &error
);
42 ok(leftPeers
, "Left peers (%@) - %s", error
, label
);
45 CFArrayRef rightPeers
= SOSAccountCopyActivePeers(right
, &error
);
46 ok(rightPeers
, "Right peers (%@) - %s", error
, label
);
49 ok(CFEqual(leftPeers
, rightPeers
), "Matching peers (%s) Left: %@, Right: %@", label
, leftPeers
, rightPeers
);
52 CFMutableArrayRef allowed_identities
= CFArrayCreateMutableForCFTypes(kCFAllocatorDefault
);
54 CFArrayRef leftIdentities
= SOSAccountCopyAccountIdentityPeerInfos(left
, kCFAllocatorDefault
, &error
);
55 ok(leftIdentities
, "Get identities (%@)", error
);
58 CFArrayAppendArray(allowed_identities
, leftIdentities
, CFRangeMake(0, CFArrayGetCount(leftIdentities
)));
60 CFReleaseNull(leftIdentities
);
62 CFArrayRef rightIdentities
= SOSAccountCopyAccountIdentityPeerInfos(right
, kCFAllocatorDefault
, &error
);
63 ok(rightIdentities
, "Get identities (%@)", error
);
66 CFArrayAppendArray(allowed_identities
, rightIdentities
, CFRangeMake(0, CFArrayGetCount(rightIdentities
)));
68 CFReleaseNull(rightIdentities
);
70 unretired_peers_is_subset(label
, leftPeers
, allowed_identities
);
73 CFReleaseNull(leftPeers
);
74 CFReleaseNull(rightPeers
);
77 CFArrayRef leftConcurringPeers
= SOSAccountCopyConcurringPeers(left
, &error
);
78 ok(leftConcurringPeers
, "Left peers (%@) - %s", error
, label
);
80 CFArrayRef rightConcurringPeers
= SOSAccountCopyConcurringPeers(right
, &error
);
81 ok(rightConcurringPeers
, "Right peers (%@) - %s", error
, label
);
83 ok(CFEqual(leftConcurringPeers
, rightConcurringPeers
), "Matching concurring peers Left: %@, Right: %@", leftConcurringPeers
, rightConcurringPeers
);
85 CFReleaseNull(leftConcurringPeers
);
86 CFReleaseNull(rightConcurringPeers
);
89 CFArrayRef leftApplicants
= SOSAccountCopyApplicants(left
, &error
);
90 ok(leftApplicants
, "Left Applicants (%@) - %s", error
, label
);
92 CFArrayRef rightApplicants
= SOSAccountCopyApplicants(right
, &error
);
93 ok(rightApplicants
, "Left Applicants (%@) - %s", error
, label
);
95 ok(CFEqual(leftApplicants
, rightApplicants
), "Matching applicants (%s) Left: %@, Right: %@", label
, leftApplicants
, rightApplicants
);
97 CFReleaseNull(leftApplicants
);
98 CFReleaseNull(rightApplicants
);
102 static inline void accounts_agree(char *label
, SOSAccountRef left
, SOSAccountRef right
)
104 accounts_agree_internal(label
, left
, right
, true);
112 static CFMutableDictionaryRef
ExtractPendingChanges(CFMutableDictionaryRef changes
)
114 CFMutableDictionaryRef extracted
= CFDictionaryCreateMutableCopy(kCFAllocatorDefault
, 0, changes
);
116 CFDictionaryRemoveAllValues(changes
);
121 #define kFeedChangesToMultieTestCountPer 1
122 static inline void FeedChangesToMulti(CFMutableDictionaryRef changes
, ...)
124 CFDictionaryRef changes_to_send
= ExtractPendingChanges(changes
);
126 SOSAccountRef account
;
128 secerror("Change block: %@", changes_to_send
);
130 CFErrorRef error
= NULL
;
132 va_start(argp
, changes
);
133 while((account
= va_arg(argp
, SOSAccountRef
)) != NULL
) {
134 ok(SOSAccountHandleUpdates(account
, changes_to_send
, &error
), "SOSAccountHandleUpdates failed (%@)", error
);
135 CFReleaseNull(error
);
139 static inline void InjectChangeToMulti(CFStringRef changeKey
, CFStringRef changeValue
, ...)
141 CFMutableDictionaryRef changes_to_send
= CFDictionaryCreateMutable(NULL
, 1, NULL
, NULL
);
142 CFDictionaryAddValue(changes_to_send
, changeKey
, changeValue
);
144 SOSAccountRef account
;
146 secerror("Change block: %@", changes_to_send
);
148 CFErrorRef error
= NULL
;
150 va_start(argp
, changeValue
);
151 while((account
= va_arg(argp
, SOSAccountRef
)) != NULL
) {
152 ok(SOSAccountHandleUpdates(account
, changes_to_send
, &error
), "SOSAccountHandleUpdates failed (%@)", error
);
153 CFReleaseNull(error
);
155 CFReleaseNull(changes_to_send
);
160 #define kFeedChangesToTestCount 1
161 static inline void FeedChangesTo(CFMutableDictionaryRef changes
, SOSAccountRef account
)
163 CFDictionaryRef changes_to_send
= ExtractPendingChanges(changes
);
165 secerror("Change block: %@", changes_to_send
);
167 CFErrorRef error
= NULL
;
168 ok(SOSAccountHandleUpdates(account
, changes_to_send
, &error
), "SOSAccountHandleUpdates failed (%@)", error
);
169 CFReleaseNull(error
);
170 CFReleaseNull(changes_to_send
);
174 static SOSAccountRef
CreateAccountForLocalChanges(CFMutableDictionaryRef changes
, CFStringRef name
, CFStringRef data_source_name
)
176 SOSAccountKeyInterestBlock interest_block
= ^(bool getNewKeysOnly
, CFArrayRef alwaysKeys
, CFArrayRef afterFirstUnlockKeys
, CFArrayRef unlockedKeys
) {};
177 SOSAccountDataUpdateBlock update_block
= ^ bool (CFDictionaryRef keys
, CFErrorRef
*error
) {
178 CFDictionaryForEach(keys
, ^(const void *key
, const void *value
) {
179 CFDictionarySetValue(changes
, key
, value
);
184 SOSDataSourceFactoryRef factory
= SOSTestDataSourceFactoryCreate();
185 SOSTestDataSourceFactoryAddDataSource(factory
, data_source_name
, SOSTestDataSourceCreate());
187 CFDictionaryRef gestalt
= SOSCreatePeerGestaltFromName(name
);
189 SOSAccountRef result
= SOSAccountCreate(kCFAllocatorDefault
, gestalt
, factory
, interest_block
, update_block
);
191 CFReleaseNull(gestalt
);
197 static inline int countPeers(SOSAccountRef account
) {
198 CFErrorRef error
= NULL
;
201 peers
= SOSAccountCopyPeers(account
, &error
);
202 int retval
= (int) CFArrayGetCount(peers
);
203 CFReleaseNull(error
);
204 CFReleaseNull(peers
);
208 static inline int countActivePeers(SOSAccountRef account
) {
209 CFErrorRef error
= NULL
;
212 peers
= SOSAccountCopyActivePeers(account
, &error
);
213 int retval
= (int) CFArrayGetCount(peers
);
214 CFReleaseNull(error
);
215 CFReleaseNull(peers
);
219 static inline int countActiveValidPeers(SOSAccountRef account
) {
220 CFErrorRef error
= NULL
;
223 peers
= SOSAccountCopyActiveValidPeers(account
, &error
);
224 int retval
= (int) CFArrayGetCount(peers
);
225 CFReleaseNull(error
);
226 CFReleaseNull(peers
);
230 static inline int countApplicants(SOSAccountRef account
) {
231 CFErrorRef error
= NULL
;
232 CFArrayRef applicants
= SOSAccountCopyApplicants(account
, &error
);
235 if(applicants
) retval
= (int)CFArrayGetCount(applicants
);
236 CFReleaseNull(error
);
237 CFReleaseNull(applicants
);
242 static inline void showActiveValidPeers(SOSAccountRef account
) {
243 CFErrorRef error
= NULL
;
246 peers
= SOSAccountCopyActiveValidPeers(account
, &error
);
247 CFArrayForEach(peers
, ^(const void *value
) {
248 SOSPeerInfoRef pi
= (SOSPeerInfoRef
) value
;
249 ok(0, "Active Valid Peer %@", pi
);
251 CFReleaseNull(peers
);