Something went wrong. Try again.
Cider Isn't Darwin Emulation, Really
Something went wrong. Try again.
Objective-C
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397/* * Copyright (c) 2016, 2017 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */
#import "SCTest.h"#import "SCTestUtils.h"
@interface SCTestDynamicStore : SCTest@property SCDynamicStoreRef store;@property dispatch_semaphore_t sem;@property int counter;@end
@implementation SCTestDynamicStore
+ (NSString *)command{ return @"dynamic_store";}
+ (NSString *)commandDescription{ return @"Tests the SCDynamicStore code path";}
- (instancetype)initWithOptions:(NSDictionary *)options{ self = [super initWithOptions:options]; if (self) { _store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("SCTest"), NULL, NULL); if (_store == NULL) { SCTestLog("Could not create session"); ERR_EXIT; } } return self;}
- (void)dealloc{ if (self.store != NULL) { CFRelease(self.store); self.store = NULL; }}
- (void)start{ CFStringRef key; if (self.options[kSCTestDynamicStoreOptionDNS]) { key = SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCEntNetDNS); CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key); SCTestLog("%@ : %@", key, value); CFRelease(key); }
if (self.options[kSCTestDynamicStoreOptionIPv4]) { key = SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCEntNetIPv4); CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key); SCTestLog("%@ : %@", key, value); CFRelease(key); }
if (self.options[kSCTestDynamicStoreOptionIPv6]) { key = SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCEntNetIPv6); CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key); SCTestLog("%@ : %@", key, value); CFRelease(key); }
if (self.options[kSCTestDynamicStoreOptionProxies]) { key = SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, kSCDynamicStoreDomainState, kSCEntNetProxies); CFPropertyListRef value = SCDynamicStoreCopyValue(self.store, key); SCTestLog("%@ : %@", key, value); CFRelease(key); }
[self cleanupAndExitWithErrorCode:0];}
- (void)cleanupAndExitWithErrorCode:(int)error{ [super cleanupAndExitWithErrorCode:error];}
- (BOOL)setup{ return YES;}
- (BOOL)unitTest{ if(![self setup]) { return NO; }
BOOL allUnitTestsPassed = YES; allUnitTestsPassed &= [self unitTestSetAndRemoveValue]; allUnitTestsPassed &= [self unitTestCopyMultiple]; allUnitTestsPassed &= [self unitTestSCDynamicStoreCallbackStress]; allUnitTestsPassed &= [self unitTestSCDynamicStoreSetMultipleStress];
if(![self tearDown]) { return NO; }
return allUnitTestsPassed;}
- (BOOL)tearDown{ return YES;}
- (BOOL)unitTestSetAndRemoveValue{ int iterations = 1000; NSDictionary *bogusValue; SCTestDynamicStore *test;
test = [[SCTestDynamicStore alloc] initWithOptions:self.options]; bogusValue = @{@"Pretty":@"Useless"};
for (int i = 0; i < iterations; i++) { NSUUID *uuid = [NSUUID UUID]; CFStringRef key; BOOL ok;
key = SCDynamicStoreKeyCreateNetworkServiceEntity(kCFAllocatorDefault, CFSTR("SCTest"), (__bridge CFStringRef)uuid.UUIDString, kSCEntNetDNS); ok = SCDynamicStoreSetValue(test.store, key, (__bridge CFDictionaryRef)bogusValue); if (!ok) { SCTestLog("Failed to set value in SCDynamicStore. Error: %s", SCErrorString(SCError())); CFRelease(key); return NO; }
ok = SCDynamicStoreRemoveValue(test.store, key); if (!ok) { SCTestLog("Failed to remove value from SCDynamicStore. Error: %s", SCErrorString(SCError())); CFRelease(key); return NO; }
CFRelease(key); }
SCTestLog("Successfully completed setAndRemove unit test"); return YES;}
- (BOOL)unitTestCopyMultiple{ NSString *pattern; SCTestDynamicStore *test; CFArrayRef keyList; int iterations = 1000;
test = [[SCTestDynamicStore alloc] initWithOptions:self.options]; pattern = (__bridge_transfer NSString *)SCDynamicStoreKeyCreate(kCFAllocatorDefault, CFSTR("%@/%@/%@/%@/%@"), kSCDynamicStoreDomainState, kSCCompNetwork, kSCCompInterface, kSCCompAnyRegex, kSCCompAnyRegex);
keyList = SCDynamicStoreCopyKeyList(test.store, (__bridge CFStringRef)pattern); for (int i = 0; i < iterations; i++) { CFDictionaryRef value = SCDynamicStoreCopyMultiple(test.store, keyList, NULL); if (value == NULL) { SCTestLog("Failed to copy multiple values from SCDynamicStore. Error: %s", SCErrorString(SCError())); CFRelease(keyList); return NO; } CFRelease(value); } CFRelease(keyList);
pattern = (__bridge_transfer NSString *)SCDynamicStoreKeyCreate(kCFAllocatorDefault, CFSTR("%@/%@/%@/%@/%@"), kSCDynamicStoreDomainSetup, kSCCompNetwork, kSCCompService, kSCCompAnyRegex, kSCCompAnyRegex);
keyList = SCDynamicStoreCopyKeyList(test.store, (__bridge CFStringRef)pattern); for (int i = 0; i < iterations; i++) { CFDictionaryRef value = SCDynamicStoreCopyMultiple(test.store, keyList, NULL); if (value == NULL) { SCTestLog("Failed to copy multiple values from SCDynamicStore. Error: %s", SCErrorString(SCError())); CFRelease(keyList); return NO; } CFRelease(value); } CFRelease(keyList);
SCTestLog("Successfully completed copyMultiple unit test"); return YES;}
voidmyTestCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *ctx){#pragma unused(store)#pragma unused(changedKeys) SCTestDynamicStore *test = (__bridge SCTestDynamicStore *)ctx; test.counter++; if (test.sem != NULL) { dispatch_semaphore_signal(test.sem); }}
- (BOOL)unitTestSCDynamicStoreCallbackStress{ SCTestDynamicStore *test; int iterations = 100; NSString *testKey = @"State:/myTestKey"; BOOL ok; dispatch_queue_t callbackQ;
test = [[SCTestDynamicStore alloc] initWithOptions:self.options]; if (test.store != NULL) { CFRelease(test.store); test.store = NULL; }
SCDynamicStoreContext ctx = {0, (__bridge void * _Nullable)(test), CFRetain, CFRelease, NULL}; test.store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("SCTest"), myTestCallback, &ctx);
ok = SCDynamicStoreSetNotificationKeys(test.store, (__bridge CFArrayRef)@[testKey], NULL); if (!ok) { SCTestLog("Failed to set notification keys. Error: %s", SCErrorString(SCError())); return NO; }
callbackQ = dispatch_queue_create("SCTestDynamicStore callback queue", NULL); ok = SCDynamicStoreSetDispatchQueue(test.store, callbackQ); if (!ok) { SCTestLog("Failed to set dispatch queue. Error: %s", SCErrorString(SCError())); return NO; }
for (int i = 0; i < iterations; i++) { NSUUID *uuid = [NSUUID UUID]; ok = SCDynamicStoreSetValue(test.store, (__bridge CFStringRef)testKey, (__bridge CFStringRef)uuid.UUIDString); if (!ok) { SCTestLog("Failed to set value. Error: %s", SCErrorString(SCError())); return NO; } // Perform a write to Dynamic Store every 10ms. [test waitFor:0.01]; }
ok = SCDynamicStoreRemoveValue(test.store, (__bridge CFStringRef)testKey); if (!ok) { SCTestLog("Failed to remove value. Error: %s", SCErrorString(SCError())); return NO; }
if (test.counter < iterations) { // Not all callbacks were received SCTestLog("Not all SCDynamicStore callbacks were received (%d/%d). Something went wrong", test.counter, iterations); return NO; }
SCTestLog("Successfully completed SCDynamicStore callbacks unit test"); return YES;}
- (BOOL)unitTestSCDynamicStoreSetMultipleStress{ SCTestDynamicStore *test; int iterations = 100; NSMutableArray *testKeyArray; NSMutableDictionary *testSetDictionary; int expectedCallbackCount = 0; BOOL ok; dispatch_queue_t callbackQ; uint8_t waitTime = 1; // second
test = [[SCTestDynamicStore alloc] initWithOptions:self.options]; if (test.store != NULL) { CFRelease(test.store); test.store = NULL; }
SCDynamicStoreContext ctx = {0, (__bridge void * _Nullable)(test), CFRetain, CFRelease, NULL}; test.store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("SCTest"), myTestCallback, &ctx); test.sem = dispatch_semaphore_create(0);
testKeyArray = [[NSMutableArray alloc] init];
for (int i = 0; i < iterations; i++) { NSUUID *uuid = [NSUUID UUID]; NSString *str = [NSString stringWithFormat:@"State:/%@", uuid]; [testKeyArray addObject:str]; }
testSetDictionary = [[NSMutableDictionary alloc] init]; for (NSString *key in testKeyArray) { NSUUID *uuid = [NSUUID UUID]; [testSetDictionary setObject:@[uuid.UUIDString] forKey:key]; }
callbackQ = dispatch_queue_create("SCTestDynamicStore callback queue", NULL); ok = SCDynamicStoreSetNotificationKeys(test.store, (__bridge CFArrayRef)testKeyArray, NULL); if (!ok) { SCTestLog("Failed to set notification keys. Error: %s", SCErrorString(SCError())); return NO; }
ok = SCDynamicStoreSetDispatchQueue(test.store, callbackQ); if (!ok) { SCTestLog("Failed to set dispatch queue. Error: %s", SCErrorString(SCError())); return NO; }
ok = SCDynamicStoreSetMultiple(test.store, (__bridge CFDictionaryRef)testSetDictionary, NULL, NULL); if (!ok) { SCTestLog("Failed to set multiple keys. Error: %s", SCErrorString(SCError())); return NO; } else { expectedCallbackCount++; // One callback for set multiple }
if(dispatch_semaphore_wait(test.sem, dispatch_time(DISPATCH_TIME_NOW, waitTime * NSEC_PER_SEC))) { SCTestLog("Failed to get a callback when multiple keys are set"); return NO; }
ok = SCDynamicStoreSetMultiple(test.store, NULL, NULL, (__bridge CFArrayRef)testKeyArray); if (!ok) { SCTestLog("Failed to set multiple keys. Error: %s", SCErrorString(SCError())); return NO; } else { expectedCallbackCount++; // One callback for fake notification }
if(dispatch_semaphore_wait(test.sem, dispatch_time(DISPATCH_TIME_NOW, waitTime * NSEC_PER_SEC))) { SCTestLog("Failed to get a callback when multiple keys are notified"); return NO; }
ok = SCDynamicStoreSetMultiple(test.store, NULL, (__bridge CFArrayRef)testKeyArray, NULL); if (!ok) { SCTestLog("Failed to set multiple keys. Error: %s", SCErrorString(SCError())); return NO; } else { expectedCallbackCount++; // One callback for key removal }
if(dispatch_semaphore_wait(test.sem, dispatch_time(DISPATCH_TIME_NOW, waitTime * NSEC_PER_SEC))) { SCTestLog("Failed to get a callback when multiple keys are removed"); return NO; }
if (test.counter < expectedCallbackCount) { // Not all callbacks were received SCTestLog("Not all SCDynamicStore callbacks were received (%d/%d). Something went wrong", test.counter, expectedCallbackCount); return NO; }
SCTestLog("Successfully completed SCDynamicStore set multiple unit test"); return YES;
}
@end