]>
Commit | Line | Data |
---|---|---|
427c49bc A |
1 | // |
2 | // sc-103-syncupdate.c | |
3 | // sec | |
4 | // | |
5 | // Created by John Hurley on 9/6/12. | |
6 | // | |
7 | // | |
8 | ||
9 | // Run on 2 devices: | |
10 | // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_103_syncupdate -v -- -i alice | |
11 | // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_103_syncupdate -v -- -i bob | |
12 | // Run on 2 devices: | |
13 | // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i | |
14 | // /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_101_accountsync -v -- -i | |
15 | ||
16 | #include <AssertMacros.h> | |
17 | ||
18 | #include <stdio.h> | |
19 | #include <stdlib.h> | |
20 | #include <unistd.h> | |
21 | #include <xpc/xpc.h> | |
22 | ||
23 | #include <Security/SecBase.h> | |
24 | #include <Security/SecItem.h> | |
25 | #include <Security/SecItemPriv.h> | |
26 | ||
27 | #include <CKBridge/SOSCloudKeychainClient.h> | |
28 | #include <SecureObjectSync/SOSCloudCircle.h> | |
29 | ||
30 | #include <notify.h> | |
31 | #include <dispatch/dispatch.h> | |
32 | #include <getopt.h> | |
33 | ||
34 | #include <utilities/SecCFWrappers.h> | |
35 | #include <utilities/debugging.h> | |
36 | #include <utilities/SecCFRelease.h> | |
37 | ||
38 | #include "SOSCircle_regressions.h" | |
39 | #include "SOSRegressionUtilities.h" | |
40 | #include "SOSCloudKeychainConstants.h" | |
41 | ||
42 | #define xsecdebug(format...) secerror(format) | |
43 | ||
44 | static dispatch_group_t sDispatchGroup = NULL; | |
45 | ||
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 | |
51 | ||
52 | static dispatch_queue_t requestqueue; | |
53 | ||
54 | static dispatch_source_t exitTimerSource; | |
55 | ||
56 | static uint64_t failCounter = 0; | |
57 | static uint64_t putAttemptCounter = 0; | |
58 | static uint64_t itemsChangedCount = 0; | |
59 | ||
60 | ||
61 | // MARK: ----- Debug Routines ----- | |
62 | ||
63 | static void tearDown(void) | |
64 | { | |
65 | xsecdebug("exit"); | |
66 | CFRunLoopStop(CFRunLoopGetMain()); | |
67 | } | |
68 | ||
69 | // MARK: ----- Get Cycle Tester ----- | |
70 | ||
71 | static void initCyclerTests(dispatch_group_t dgroup) | |
72 | { | |
73 | /* | |
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 | |
78 | */ | |
79 | ||
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); | |
84 | ||
85 | dispatch_source_set_event_handler(exitTimerSource, | |
86 | ^{ | |
87 | xsecdebug("Test Exit: %lld", failCounter); | |
88 | printf("Test Exit: fail: %lld, total: %lld, changed: %lld\n", failCounter, putAttemptCounter, itemsChangedCount); | |
89 | tearDown(); | |
90 | exit(0); | |
91 | }); | |
92 | } | |
93 | ||
94 | static void updateSyncingEnabledSwitch() | |
95 | { | |
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); | |
101 | } | |
102 | ||
103 | static void requestToJoinCircle() | |
104 | { | |
105 | // Set the visual state of switch based on membership in circle | |
106 | bool bx; | |
107 | CFErrorRef error = NULL; | |
108 | SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error); | |
109 | pass("ccstatus: %d, error: %@", ccstatus, error); | |
110 | if (ccstatus == kSOSCCInCircle) | |
111 | return; | |
112 | ||
113 | if (ccstatus == kSOSCCNotInCircle) | |
114 | { | |
115 | pass("Not in circle, requesting admission"); | |
116 | bx = SOSCCRequestToJoinCircle(&error); | |
117 | if (!bx) | |
118 | pass("SOSCCRequestToJoinCircle error: %@", error); | |
119 | } | |
120 | else | |
121 | if (ccstatus == kSOSCCRequestPending) | |
122 | pass("Not in circle, admission pending"); | |
123 | } | |
124 | ||
125 | static void handleEnableSyncing(bool turningOn) | |
126 | { | |
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 | |
129 | { | |
130 | pass("Keychain syncing is being turned ON"); | |
131 | dispatch_async(workq, ^ | |
132 | { | |
133 | CFErrorRef error = NULL; | |
134 | bool bx = SOSCCResetToOffering(&error); | |
135 | if (bx) | |
136 | pass("ResetToOffering OK"); | |
137 | else | |
138 | pass("ResetToOffering fail: %@", error); | |
139 | ||
140 | requestToJoinCircle(); | |
141 | updateSyncingEnabledSwitch(); | |
142 | dispatch_group_leave(sDispatchGroup); | |
143 | }); | |
144 | } | |
145 | else | |
146 | { | |
147 | pass("Keychain syncing is being turned OFF"); | |
148 | CFErrorRef error = NULL; | |
149 | bool bx = SOSCCRemoveThisDeviceFromCircle(&error); | |
150 | updateSyncingEnabledSwitch(); | |
151 | if (!bx) | |
152 | pass("SOSCCRemoveThisDeviceFromCircle fail: %@", error); | |
153 | } | |
154 | } | |
155 | ||
156 | // MARK: ----- start of all tests ----- | |
157 | ||
158 | static void initialEstablish(void) | |
159 | { | |
160 | dispatch_group_enter(sDispatchGroup); | |
161 | dispatch_group_notify(sDispatchGroup, requestqueue, ^ | |
162 | { | |
163 | printf("Exiting via dispatch_group_notify; all work done\n"); | |
164 | CFRunLoopStop(CFRunLoopGetMain()); | |
165 | // exit(0); | |
166 | }); | |
167 | handleEnableSyncing(true); | |
168 | ||
169 | #if 0 | |
170 | CFErrorRef error = NULL; | |
171 | bool bx = false; | |
172 | SOSCCStatus sccStatus = SOSCCThisDeviceIsInCircle(&error); | |
173 | if (sccStatus == kSOSCCNotInCircle) | |
174 | bx = SOSCCResetToOffering(&error); | |
175 | else | |
176 | bx = SOSCCRequestToJoinCircle(&error); | |
177 | if (!bx) | |
178 | xsecdebug("circle establish error: %@", error); | |
179 | ok(bx, "Circle established"); | |
180 | #endif | |
181 | } | |
182 | ||
183 | // MARK: ---------- Main ---------- | |
184 | ||
185 | // define the options table for the command line | |
186 | static const struct option options[] = | |
187 | { | |
188 | { "verbose", optional_argument, NULL, 'v' }, | |
189 | { } | |
190 | }; | |
191 | ||
192 | static int kTestCount = 22; | |
193 | ||
194 | int sc_103_syncupdate(int argc, char *const *argv) | |
195 | { | |
196 | extern char *optarg; | |
197 | int arg, argSlot; | |
198 | ||
199 | while (argSlot = -1, (arg = getopt_long(argc, (char * const *)argv, "i:v", options, &argSlot)) != -1) | |
200 | switch (arg) | |
201 | { | |
202 | default: | |
203 | secerror("arg: %s", optarg); | |
204 | break; | |
205 | } | |
206 | ||
207 | plan_tests(kTestCount); | |
208 | ||
209 | SKIP: | |
210 | { | |
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); | |
215 | initialEstablish(); | |
216 | } | |
217 | ||
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"); | |
223 | ||
224 | return 0; | |
225 | } | |
226 | ||
227 | ||
228 |