5 // Created by John Hurley on 9/6/12.
10 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_103_syncupdate -v -- -i alice
11 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_103_syncupdate -v -- -i bob
13 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i
14 // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i
16 #include <AssertMacros.h>
23 #include <Security/SecBase.h>
24 #include <Security/SecItem.h>
25 #include <Security/SecItemPriv.h>
27 #include <CKBridge/SOSCloudKeychainClient.h>
28 #include <SecureObjectSync/SOSCloudCircle.h>
31 #include <dispatch/dispatch.h>
34 #include <utilities/SecCFWrappers.h>
35 #include <utilities/debugging.h>
36 #include <utilities/SecCFRelease.h>
38 #include "SOSCircle_regressions.h"
39 #include "SOSRegressionUtilities.h"
40 #include "SOSCloudKeychainConstants.h"
42 #define xsecdebug(format...) secerror(format)
44 static dispatch_group_t sDispatchGroup
= NULL
;
46 static const uint64_t putTestInterval
= 10ull * NSEC_PER_SEC
;
47 static const uint64_t leeway
= 1ull * NSEC_PER_SEC
;
48 static const uint64_t syncInterval
= 60ull * NSEC_PER_SEC
; // seconds
49 static const uint64_t putDelay
= 10ull * NSEC_PER_SEC
; // seconds; should probably be longer than syncedefaultsd latency (6 sec)
50 static const uint64_t exitDelay
= 180ull * NSEC_PER_SEC
; // seconds
52 static dispatch_queue_t requestqueue
;
54 static dispatch_source_t exitTimerSource
;
56 static uint64_t failCounter
= 0;
57 static uint64_t putAttemptCounter
= 0;
58 static uint64_t itemsChangedCount
= 0;
61 // MARK: ----- Debug Routines -----
63 static void tearDown(void)
66 CFRunLoopStop(CFRunLoopGetMain());
69 // MARK: ----- Get Cycle Tester -----
71 static void initCyclerTests(dispatch_group_t dgroup
)
74 We set up two timer sources:
75 - getRequestsource waits 5 seconds, then gets every 5 seconds
76 - exitTimerSource fires once after 300 seconds (5 minutes)
77 All are created suspended, so they don't start yet
80 uint64_t delay
= exitDelay
;
81 dispatch_time_t exitFireTime
= dispatch_time(DISPATCH_TIME_NOW
, delay
);
82 exitTimerSource
= dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER
, (uintptr_t)NULL
, 0, requestqueue
);
83 dispatch_source_set_timer(exitTimerSource
, exitFireTime
, 0ull, leeway
);
85 dispatch_source_set_event_handler(exitTimerSource
,
87 xsecdebug("Test Exit: %lld", failCounter
);
88 printf("Test Exit: fail: %lld, total: %lld, changed: %lld\n", failCounter
, putAttemptCounter
, itemsChangedCount
);
94 static void updateSyncingEnabledSwitch()
96 // Set the visual state of switch based on membership in circle
97 CFErrorRef error
= NULL
;
98 SOSCCStatus ccstatus
= SOSCCThisDeviceIsInCircle(&error
);
99 // [_syncingEnabled setOn:(BOOL)(ccstatus == kSOSCCInCircle) animated:NO];
100 pass("ccstatus: %d, error: %@", ccstatus
, error
);
103 static void requestToJoinCircle()
105 // Set the visual state of switch based on membership in circle
107 CFErrorRef error
= NULL
;
108 SOSCCStatus ccstatus
= SOSCCThisDeviceIsInCircle(&error
);
109 pass("ccstatus: %d, error: %@", ccstatus
, error
);
110 if (ccstatus
== kSOSCCInCircle
)
113 if (ccstatus
== kSOSCCNotInCircle
)
115 pass("Not in circle, requesting admission");
116 bx
= SOSCCRequestToJoinCircle(&error
);
118 pass("SOSCCRequestToJoinCircle error: %@", error
);
121 if (ccstatus
== kSOSCCRequestPending
)
122 pass("Not in circle, admission pending");
125 static void handleEnableSyncing(bool turningOn
)
127 dispatch_queue_t workq
= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0);
128 if (turningOn
) // i.e. we are trying to turn on syncing
130 pass("Keychain syncing is being turned ON");
131 dispatch_async(workq
, ^
133 CFErrorRef error
= NULL
;
134 bool bx
= SOSCCResetToOffering(&error
);
136 pass("ResetToOffering OK");
138 pass("ResetToOffering fail: %@", error
);
140 requestToJoinCircle();
141 updateSyncingEnabledSwitch();
142 dispatch_group_leave(sDispatchGroup
);
147 pass("Keychain syncing is being turned OFF");
148 CFErrorRef error
= NULL
;
149 bool bx
= SOSCCRemoveThisDeviceFromCircle(&error
);
150 updateSyncingEnabledSwitch();
152 pass("SOSCCRemoveThisDeviceFromCircle fail: %@", error
);
156 // MARK: ----- start of all tests -----
158 static void initialEstablish(void)
160 dispatch_group_enter(sDispatchGroup
);
161 dispatch_group_notify(sDispatchGroup
, requestqueue
, ^
163 printf("Exiting via dispatch_group_notify; all work done\n");
164 CFRunLoopStop(CFRunLoopGetMain());
167 handleEnableSyncing(true);
170 CFErrorRef error
= NULL
;
172 SOSCCStatus sccStatus
= SOSCCThisDeviceIsInCircle(&error
);
173 if (sccStatus
== kSOSCCNotInCircle
)
174 bx
= SOSCCResetToOffering(&error
);
176 bx
= SOSCCRequestToJoinCircle(&error
);
178 xsecdebug("circle establish error: %@", error
);
179 ok(bx
, "Circle established");
183 // MARK: ---------- Main ----------
185 // define the options table for the command line
186 static const struct option options
[] =
188 { "verbose", optional_argument
, NULL
, 'v' },
192 static int kTestCount
= 22;
194 int sc_103_syncupdate(int argc
, char *const *argv
)
199 while (argSlot
= -1, (arg
= getopt_long(argc
, (char * const *)argv
, "i:v", options
, &argSlot
)) != -1)
203 secerror("arg: %s", optarg
);
207 plan_tests(kTestCount
);
211 skip("Skipping ckdclient tests because CloudKeychainProxy.xpc is not installed", kTestCount
, XPCServiceInstalled());
212 sDispatchGroup
= dispatch_group_create();
213 requestqueue
= dispatch_queue_create("sc_103_syncupdate", DISPATCH_QUEUE_CONCURRENT
);
214 initCyclerTests(sDispatchGroup
);
218 dispatch_group_wait(sDispatchGroup
, DISPATCH_TIME_FOREVER
);
219 pass("Tests are running...");
220 printf("Tests are running...\n");
221 CFRunLoopRun(); // Wait for it...
222 pass("Exit from run loop");