this repo has no description
at fixPythonPipStalling 396 lines 12 kB view raw
1/* 2 * Copyright (c) 2016, 2017 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#import "SCTest.h" 25#import "SCTestUtils.h" 26 27@interface SCTestDynamicStore : SCTest 28@property SCDynamicStoreRef store; 29@property dispatch_semaphore_t sem; 30@property int counter; 31@end 32 33@implementation SCTestDynamicStore 34 35+ (NSString *)command 36{ 37 return @"dynamic_store"; 38} 39 40+ (NSString *)commandDescription 41{ 42 return @"Tests the SCDynamicStore code path"; 43} 44 45- (instancetype)initWithOptions:(NSDictionary *)options 46{ 47 self = [super initWithOptions:options]; 48 if (self) { 49 _store = SCDynamicStoreCreate(kCFAllocatorDefault, 50 CFSTR("SCTest"), 51 NULL, 52 NULL); 53 if (_store == NULL) { 54 SCTestLog("Could not create session"); 55 ERR_EXIT; 56 } 57 } 58 return self; 59} 60 61- (void)dealloc 62{ 63 if (self.store != NULL) { 64 CFRelease(self.store); 65 self.store = NULL; 66 } 67} 68 69- (void)start 70{ 71 CFStringRef key; 72 if (self.options[kSCTestDynamicStoreOptionDNS]) { 73 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCEntNetDNS); 74 CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key); 75 SCTestLog("%@ : %@", key, value); 76 CFRelease(key); 77 } 78 79 if (self.options[kSCTestDynamicStoreOptionIPv4]) { 80 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCEntNetIPv4); 81 CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key); 82 SCTestLog("%@ : %@", key, value); 83 CFRelease(key); 84 } 85 86 if (self.options[kSCTestDynamicStoreOptionIPv6]) { 87 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCEntNetIPv6); 88 CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key); 89 SCTestLog("%@ : %@", key, value); 90 CFRelease(key); 91 } 92 93 if (self.options[kSCTestDynamicStoreOptionProxies]) { 94 key = SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCEntNetProxies); 95 CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key); 96 SCTestLog("%@ : %@", key, value); 97 CFRelease(key); 98 } 99 100 [self cleanupAndExitWithErrorCode:0]; 101} 102 103- (void)cleanupAndExitWithErrorCode:(int)error 104{ 105 [super cleanupAndExitWithErrorCode:error]; 106} 107 108- (BOOL)setup 109{ 110 return YES; 111} 112 113- (BOOL)unitTest 114{ 115 if(![self setup]) { 116 return NO; 117 } 118 119 BOOL allUnitTestsPassed = YES; 120 allUnitTestsPassed &= [self unitTestSetAndRemoveValue]; 121 allUnitTestsPassed &= [self unitTestCopyMultiple]; 122 allUnitTestsPassed &= [self unitTestSCDynamicStoreCallbackStress]; 123 allUnitTestsPassed &= [self unitTestSCDynamicStoreSetMultipleStress]; 124 125 if(![self tearDown]) { 126 return NO; 127 } 128 129 return allUnitTestsPassed; 130} 131 132- (BOOL)tearDown 133{ 134 return YES; 135} 136 137- (BOOL)unitTestSetAndRemoveValue 138{ 139 int iterations = 1000; 140 NSDictionary *bogusValue; 141 SCTestDynamicStore *test; 142 143 test = [[SCTestDynamicStore alloc] initWithOptions:self.options]; 144 bogusValue = @{@"Pretty":@"Useless"}; 145 146 for (int i = 0; i < iterations; i++) { 147 NSUUID *uuid = [NSUUID UUID]; 148 CFStringRef key; 149 BOOL ok; 150 151 key = SCDynamicStoreKeyCreateNetworkServiceEntity(kCFAllocatorDefault, 152 CFSTR("SCTest"), 153 (__bridge CFStringRef)uuid.UUIDString, 154 kSCEntNetDNS); 155 ok = SCDynamicStoreSetValue(test.store, key, (__bridge CFDictionaryRef)bogusValue); 156 if (!ok) { 157 SCTestLog("Failed to set value in SCDynamicStore. Error: %s", SCErrorString(SCError())); 158 CFRelease(key); 159 return NO; 160 } 161 162 ok = SCDynamicStoreRemoveValue(test.store, key); 163 if (!ok) { 164 SCTestLog("Failed to remove value from SCDynamicStore. Error: %s", SCErrorString(SCError())); 165 CFRelease(key); 166 return NO; 167 } 168 169 CFRelease(key); 170 } 171 172 SCTestLog("Successfully completed setAndRemove unit test"); 173 return YES; 174} 175 176- (BOOL)unitTestCopyMultiple 177{ 178 NSString *pattern; 179 SCTestDynamicStore *test; 180 CFArrayRef keyList; 181 int iterations = 1000; 182 183 test = [[SCTestDynamicStore alloc] initWithOptions:self.options]; 184 pattern = (__bridge_transfer NSString *)SCDynamicStoreKeyCreate(kCFAllocatorDefault, 185 CFSTR("%@/%@/%@/%@/%@"), 186 kSCDynamicStoreDomainState, 187 kSCCompNetwork, 188 kSCCompInterface, 189 kSCCompAnyRegex, 190 kSCCompAnyRegex); 191 192 keyList = SCDynamicStoreCopyKeyList(test.store, (__bridge CFStringRef)pattern); 193 for (int i = 0; i < iterations; i++) { 194 CFDictionaryRef value = SCDynamicStoreCopyMultiple(test.store, keyList, NULL); 195 if (value == NULL) { 196 SCTestLog("Failed to copy multiple values from SCDynamicStore. Error: %s", SCErrorString(SCError())); 197 CFRelease(keyList); 198 return NO; 199 } 200 CFRelease(value); 201 } 202 CFRelease(keyList); 203 204 pattern = (__bridge_transfer NSString *)SCDynamicStoreKeyCreate(kCFAllocatorDefault, 205 CFSTR("%@/%@/%@/%@/%@"), 206 kSCDynamicStoreDomainSetup, 207 kSCCompNetwork, 208 kSCCompService, 209 kSCCompAnyRegex, 210 kSCCompAnyRegex); 211 212 keyList = SCDynamicStoreCopyKeyList(test.store, (__bridge CFStringRef)pattern); 213 for (int i = 0; i < iterations; i++) { 214 CFDictionaryRef value = SCDynamicStoreCopyMultiple(test.store, keyList, NULL); 215 if (value == NULL) { 216 SCTestLog("Failed to copy multiple values from SCDynamicStore. Error: %s", SCErrorString(SCError())); 217 CFRelease(keyList); 218 return NO; 219 } 220 CFRelease(value); 221 } 222 CFRelease(keyList); 223 224 SCTestLog("Successfully completed copyMultiple unit test"); 225 return YES; 226} 227 228void 229myTestCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *ctx) 230{ 231#pragma unused(store) 232#pragma unused(changedKeys) 233 SCTestDynamicStore *test = (__bridge SCTestDynamicStore *)ctx; 234 test.counter++; 235 if (test.sem != NULL) { 236 dispatch_semaphore_signal(test.sem); 237 } 238} 239 240- (BOOL)unitTestSCDynamicStoreCallbackStress 241{ 242 SCTestDynamicStore *test; 243 int iterations = 100; 244 NSString *testKey = @"State:/myTestKey"; 245 BOOL ok; 246 dispatch_queue_t callbackQ; 247 248 test = [[SCTestDynamicStore alloc] initWithOptions:self.options]; 249 if (test.store != NULL) { 250 CFRelease(test.store); 251 test.store = NULL; 252 } 253 254 SCDynamicStoreContext ctx = {0, (__bridge void * _Nullable)(test), CFRetain, CFRelease, NULL}; 255 test.store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("SCTest"), myTestCallback, &ctx); 256 257 ok = SCDynamicStoreSetNotificationKeys(test.store, (__bridge CFArrayRef)@[testKey], NULL); 258 if (!ok) { 259 SCTestLog("Failed to set notification keys. Error: %s", SCErrorString(SCError())); 260 return NO; 261 } 262 263 callbackQ = dispatch_queue_create("SCTestDynamicStore callback queue", NULL); 264 ok = SCDynamicStoreSetDispatchQueue(test.store, callbackQ); 265 if (!ok) { 266 SCTestLog("Failed to set dispatch queue. Error: %s", SCErrorString(SCError())); 267 return NO; 268 } 269 270 for (int i = 0; i < iterations; i++) { 271 NSUUID *uuid = [NSUUID UUID]; 272 ok = SCDynamicStoreSetValue(test.store, (__bridge CFStringRef)testKey, (__bridge CFStringRef)uuid.UUIDString); 273 if (!ok) { 274 SCTestLog("Failed to set value. Error: %s", SCErrorString(SCError())); 275 return NO; 276 } 277 // Perform a write to Dynamic Store every 10ms. 278 [test waitFor:0.01]; 279 } 280 281 ok = SCDynamicStoreRemoveValue(test.store, (__bridge CFStringRef)testKey); 282 if (!ok) { 283 SCTestLog("Failed to remove value. Error: %s", SCErrorString(SCError())); 284 return NO; 285 } 286 287 if (test.counter < iterations) { 288 // Not all callbacks were received 289 SCTestLog("Not all SCDynamicStore callbacks were received (%d/%d). Something went wrong", test.counter, iterations); 290 return NO; 291 } 292 293 SCTestLog("Successfully completed SCDynamicStore callbacks unit test"); 294 return YES; 295} 296 297- (BOOL)unitTestSCDynamicStoreSetMultipleStress 298{ 299 SCTestDynamicStore *test; 300 int iterations = 100; 301 NSMutableArray *testKeyArray; 302 NSMutableDictionary *testSetDictionary; 303 int expectedCallbackCount = 0; 304 BOOL ok; 305 dispatch_queue_t callbackQ; 306 uint8_t waitTime = 1; // second 307 308 test = [[SCTestDynamicStore alloc] initWithOptions:self.options]; 309 if (test.store != NULL) { 310 CFRelease(test.store); 311 test.store = NULL; 312 } 313 314 SCDynamicStoreContext ctx = {0, (__bridge void * _Nullable)(test), CFRetain, CFRelease, NULL}; 315 test.store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("SCTest"), myTestCallback, &ctx); 316 test.sem = dispatch_semaphore_create(0); 317 318 testKeyArray = [[NSMutableArray alloc] init]; 319 320 for (int i = 0; i < iterations; i++) { 321 NSUUID *uuid = [NSUUID UUID]; 322 NSString *str = [NSString stringWithFormat:@"State:/%@", uuid]; 323 [testKeyArray addObject:str]; 324 } 325 326 testSetDictionary = [[NSMutableDictionary alloc] init]; 327 for (NSString *key in testKeyArray) { 328 NSUUID *uuid = [NSUUID UUID]; 329 [testSetDictionary setObject:@[uuid.UUIDString] forKey:key]; 330 } 331 332 callbackQ = dispatch_queue_create("SCTestDynamicStore callback queue", NULL); 333 ok = SCDynamicStoreSetNotificationKeys(test.store, (__bridge CFArrayRef)testKeyArray, NULL); 334 if (!ok) { 335 SCTestLog("Failed to set notification keys. Error: %s", SCErrorString(SCError())); 336 return NO; 337 } 338 339 ok = SCDynamicStoreSetDispatchQueue(test.store, callbackQ); 340 if (!ok) { 341 SCTestLog("Failed to set dispatch queue. Error: %s", SCErrorString(SCError())); 342 return NO; 343 } 344 345 ok = SCDynamicStoreSetMultiple(test.store, (__bridge CFDictionaryRef)testSetDictionary, NULL, NULL); 346 if (!ok) { 347 SCTestLog("Failed to set multiple keys. Error: %s", SCErrorString(SCError())); 348 return NO; 349 } else { 350 expectedCallbackCount++; // One callback for set multiple 351 } 352 353 if(dispatch_semaphore_wait(test.sem, dispatch_time(DISPATCH_TIME_NOW, waitTime * NSEC_PER_SEC))) { 354 SCTestLog("Failed to get a callback when multiple keys are set"); 355 return NO; 356 } 357 358 ok = SCDynamicStoreSetMultiple(test.store, NULL, NULL, (__bridge CFArrayRef)testKeyArray); 359 if (!ok) { 360 SCTestLog("Failed to set multiple keys. Error: %s", SCErrorString(SCError())); 361 return NO; 362 } else { 363 expectedCallbackCount++; // One callback for fake notification 364 } 365 366 if(dispatch_semaphore_wait(test.sem, dispatch_time(DISPATCH_TIME_NOW, waitTime * NSEC_PER_SEC))) { 367 SCTestLog("Failed to get a callback when multiple keys are notified"); 368 return NO; 369 } 370 371 ok = SCDynamicStoreSetMultiple(test.store, NULL, (__bridge CFArrayRef)testKeyArray, NULL); 372 if (!ok) { 373 SCTestLog("Failed to set multiple keys. Error: %s", SCErrorString(SCError())); 374 return NO; 375 } else { 376 expectedCallbackCount++; // One callback for key removal 377 } 378 379 if(dispatch_semaphore_wait(test.sem, dispatch_time(DISPATCH_TIME_NOW, waitTime * NSEC_PER_SEC))) { 380 SCTestLog("Failed to get a callback when multiple keys are removed"); 381 return NO; 382 } 383 384 if (test.counter < expectedCallbackCount) { 385 // Not all callbacks were received 386 SCTestLog("Not all SCDynamicStore callbacks were received (%d/%d). Something went wrong", test.counter, expectedCallbackCount); 387 return NO; 388 } 389 390 SCTestLog("Successfully completed SCDynamicStore set multiple unit test"); 391 return YES; 392 393} 394 395 396@end