aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Thomas Van Lenten <thomasvl@google.com>2016-04-29 13:59:11 -0400
committerGravatar Thomas Van Lenten <thomasvl@google.com>2016-04-29 13:59:11 -0400
commitb1656a461d5864c9c2662b9e329c29dfc8c9f777 (patch)
treedf5299ac367df7b0512d81af6d7a7ecca4fb6a8e
parentc485d79b9289a4f6ff1402babbf44b6fba0aa6e7 (diff)
parent296d521919da2cebe0e5074cc8b6b2b5fdb85fd6 (diff)
Merge pull request #114 from thomasvl/update
Testing/Utils updates
-rw-r--r--AppKit/GTMGoogleSearch.m4
-rw-r--r--DebugUtils/GTMDebugThreadValidation.h59
-rw-r--r--DebugUtils/GTMDebugThreadValidation.m22
-rw-r--r--DebugUtils/GTMSynchronizationAsserts.h124
-rw-r--r--DebugUtils/GTMSynchronizationAsserts.m93
-rw-r--r--DebugUtils/GTMSynchronizationAssertsTest.m288
-rw-r--r--Foundation/GTMNSAppleScript+Handler.m15
-rw-r--r--ReleaseNotes.md1
-rw-r--r--UnitTesting/GTMSenTestCase.h193
-rw-r--r--UnitTesting/GTMSenTestCase.m76
-rwxr-xr-xUnitTesting/RunIPhoneUnitTest.sh15
-rwxr-xr-xUnitTesting/RunMacOSUnitTests.sh151
-rwxr-xr-xUnitTesting/RuniOSUnitTestsUnderSimulator.sh15
13 files changed, 544 insertions, 512 deletions
diff --git a/AppKit/GTMGoogleSearch.m b/AppKit/GTMGoogleSearch.m
index 320c71d..9384ade 100644
--- a/AppKit/GTMGoogleSearch.m
+++ b/AppKit/GTMGoogleSearch.m
@@ -100,8 +100,10 @@ static LanguageDefaultInfo kLanguageListDefaultMappingTable[] = {
};
// the notification we use for syncing up instances in different processes
-static NSString *const kNotificationName
+#if GTM_GOOGLE_SEARCH_SUPPORTS_DISTRIBUTED_NOTIFICATIONS
+static NSString *const kNotificationName
= @"com.google.GoogleSearchAllApps.prefsWritten";
+#endif
// this is the bundle id we use for the pref file used for all apps
static CFStringRef const kAllAppsBuildIdentifier
diff --git a/DebugUtils/GTMDebugThreadValidation.h b/DebugUtils/GTMDebugThreadValidation.h
index 0636159..3f50f17 100644
--- a/DebugUtils/GTMDebugThreadValidation.h
+++ b/DebugUtils/GTMDebugThreadValidation.h
@@ -1,7 +1,7 @@
//
// GTMDebugThreadValidation.h
//
-// Copyright 2008 Google Inc.
+// Copyright 2016 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -16,40 +16,29 @@
// the License.
//
-#if DEBUG
#import "GTMDefines.h"
#import <Foundation/Foundation.h>
-// GTMAssertRunningOnMainThread will allow you to verify that you are
-// currently running on the main thread. This can be useful for checking
-// under DEBUG to make sure that code that requires being run on the main thread
-// is doing so. Use the GTMAssertRunningOnMainThread macro, don't use
-// the _GTMAssertRunningOnMainThread or _GTMIsRunningOnMainThread
-// helper functions.
-
-// On Leopard and above we can just use NSThread functionality.
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
-BOOL _GTMIsRunningOnMainThread(void);
-#else // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
-#import <Foundation/Foundation.h>
-GTM_INLINE BOOL _GTMIsRunningOnMainThread(void) {
- return [NSThread isMainThread];
-}
-#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
-
-GTM_INLINE void _GTMAssertRunningOnMainThread(const char *func,
- const char *file,
- int lineNum) {
- _GTMDevAssert(_GTMIsRunningOnMainThread(),
- @"%s not being run on main thread (%s - %d)",
- func, file, lineNum);
-}
-
-#define GTMAssertRunningOnMainThread() \
- (_GTMAssertRunningOnMainThread(__func__, __FILE__, __LINE__))
-
-#else // DEBUG
-
-#define GTMAssertRunningOnMainThread() do { } while (0)
-
-#endif // DEBUG
+// GTMCheckCurrentQueue, GTMIsCurrentQueue
+//
+// GTMCheckCurrentQueue takes a target queue and uses _GTMDevAssert to
+// report if that is not the currently executing queue.
+//
+// GTMIsCurrentQueue takes a target queue and returns true if the target queue
+// is the currently executing dispatch queue. This can be passed to another
+// assertion call in debug builds; it should never be used in release code.
+//
+// The dispatch queue must have a label.
+#define GTMCheckCurrentQueue(targetQueue) \
+ _GTMDevAssert(GTMIsCurrentQueue(targetQueue), \
+ @"Current queue is %s (expected %s)", \
+ _GTMQueueName(DISPATCH_CURRENT_QUEUE_LABEL), \
+ _GTMQueueName(targetQueue))
+
+#define GTMIsCurrentQueue(targetQueue) \
+ (strcmp(_GTMQueueName(DISPATCH_CURRENT_QUEUE_LABEL), \
+ _GTMQueueName(targetQueue)) == 0)
+
+#define _GTMQueueName(queue) \
+ (strlen(dispatch_queue_get_label(queue)) > 0 ? \
+ dispatch_queue_get_label(queue) : "unnamed")
diff --git a/DebugUtils/GTMDebugThreadValidation.m b/DebugUtils/GTMDebugThreadValidation.m
index 30ee757..f2af8a0 100644
--- a/DebugUtils/GTMDebugThreadValidation.m
+++ b/DebugUtils/GTMDebugThreadValidation.m
@@ -1,7 +1,7 @@
//
// GTMDebugThreadValidation.m
//
-// Copyright 2008 Google Inc.
+// Copyright 2016 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -16,22 +16,4 @@
// the License.
//
-#import "GTMDebugThreadValidation.h"
-
-#if DEBUG && MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
-
-static NSThread *gGTMMainThread = nil;
-
-static __attribute__((constructor)) void _GTMInitThread(void) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- gGTMMainThread = [NSThread currentThread];
- [gGTMMainThread retain];
- [pool release];
-}
-
-
-BOOL _GTMIsRunningOnMainThread(void) {
- return [[NSThread currentThread] isEqual:gGTMMainThread];
-}
-
-#endif // DEBUG && MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
+// No implementation source currently needed.
diff --git a/DebugUtils/GTMSynchronizationAsserts.h b/DebugUtils/GTMSynchronizationAsserts.h
new file mode 100644
index 0000000..b026565
--- /dev/null
+++ b/DebugUtils/GTMSynchronizationAsserts.h
@@ -0,0 +1,124 @@
+//
+// GTMSynchronizationAsserts.h
+//
+// Copyright 2016 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+
+#if !__has_feature(objc_arc)
+#error "This file needs to be compiled with ARC enabled."
+#endif
+
+#import <Foundation/Foundation.h>
+
+#import "GTMDefines.h" // For _GTMDevAssert.
+
+// Macros to monitor synchronization blocks in debug builds.
+//
+// These report problems using _GTMDevAssert, which may be defined by the
+// project or by GTMDefines.h
+//
+// GTMMonitorSynchronized Start monitoring a top-level-only @sync scope.
+// Asserts if already inside a monitored @sync scope.
+// GTMMonitorRecursiveSynchronized Start monitoring a top-level or recursive @sync
+// scope.
+// GTMCheckSynchronized Assert that the current execution is inside a monitored @sync
+// scope.
+// GTMCheckNotSynchronized Assert that the current execution is not inside a monitored
+// @sync scope.
+//
+// Example usage:
+//
+// - (void)myExternalMethod {
+// @synchronized(self) {
+// GTMMonitorSynchronized(self)
+//
+// - (void)myInternalMethod {
+// GTMCheckSynchronized(self);
+//
+// - (void)callMyCallbacks {
+// GTMCheckNotSynchronized(self);
+//
+// GTMCheckNotSynchronized is available for verifying the code isn't
+// in a deadlockable @sync state, important when posting notifications and
+// invoking callbacks.
+//
+// Don't use GTMCheckNotSynchronized immediately before a @sync scope; the
+// normal recursiveness check of GTMMonitorSynchronized can catch those.
+
+#if DEBUG
+
+ #define __GTMMonitorSynchronizedVariableInner(varname, counter) \
+ varname ## counter
+ #define __GTMMonitorSynchronizedVariable(varname, counter) \
+ __GTMMonitorSynchronizedVariableInner(varname, counter)
+
+ #define GTMMonitorSynchronized(obj) \
+ NS_VALID_UNTIL_END_OF_SCOPE id \
+ __GTMMonitorSynchronizedVariable(__monitor, __COUNTER__) = \
+ [[GTMSyncMonitorInternal alloc] initWithSynchronizationObject:obj \
+ allowRecursive:NO \
+ functionName:__func__]
+
+ #define GTMMonitorRecursiveSynchronized(obj) \
+ NS_VALID_UNTIL_END_OF_SCOPE id \
+ __GTMMonitorSynchronizedVariable(__monitor, __COUNTER__) = \
+ [[GTMSyncMonitorInternal alloc] initWithSynchronizationObject:obj \
+ allowRecursive:YES \
+ functionName:__func__]
+
+ #define GTMCheckSynchronized(obj) { \
+ _GTMDevAssert( \
+ [GTMSyncMonitorInternal functionsHoldingSynchronizationOnObject:obj], \
+ @"GTMCheckSynchronized(" #obj ") failed: not sync'd" \
+ @" on " #obj " in %s. Call stack:\n%@", \
+ __func__, [NSThread callStackSymbols]); \
+ }
+
+ #define GTMCheckNotSynchronized(obj) { \
+ _GTMDevAssert( \
+ ![GTMSyncMonitorInternal functionsHoldingSynchronizationOnObject:obj], \
+ @"GTMCheckNotSynchronized(" #obj ") failed: was sync'd" \
+ @" on " #obj " in %s by %@. Call stack:\n%@", __func__, \
+ [GTMSyncMonitorInternal functionsHoldingSynchronizationOnObject:obj], \
+ [NSThread callStackSymbols]); \
+ }
+
+// GTMSyncMonitorInternal is a private class that keeps track of the
+// beginning and end of synchronized scopes, relying on ARC to release
+// it at the end of a scope.
+//
+// This class should not be used directly, but only via the
+// GTMMonitorSynchronized macro.
+@interface GTMSyncMonitorInternal : NSObject {
+ NSValue *_objectKey; // The synchronize target object.
+ const char *_functionName; // The function containing the monitored sync block.
+}
+
+- (instancetype)initWithSynchronizationObject:(id)object
+ allowRecursive:(BOOL)allowRecursive
+ functionName:(const char *)functionName;
+// Return the names of the functions that hold sync on the object, or nil if none.
++ (NSArray *)functionsHoldingSynchronizationOnObject:(id)object;
+@end
+
+#else
+
+ // !DEBUG
+ #define GTMMonitorSynchronized(obj) do { } while (0)
+ #define GTMMonitorRecursiveSynchronized(obj) do { } while (0)
+ #define GTMCheckSynchronized(obj) do { } while (0)
+ #define GTMCheckNotSynchronized(obj) do { } while (0)
+
+#endif // DEBUG
diff --git a/DebugUtils/GTMSynchronizationAsserts.m b/DebugUtils/GTMSynchronizationAsserts.m
new file mode 100644
index 0000000..6c76550
--- /dev/null
+++ b/DebugUtils/GTMSynchronizationAsserts.m
@@ -0,0 +1,93 @@
+//
+// GTMSyncAsserts.m
+//
+// Copyright 2016 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+
+#import "GTMSynchronizationAsserts.h"
+
+#if DEBUG
+
+@implementation GTMSyncMonitorInternal
+
+- (instancetype)initWithSynchronizationObject:(id)object
+ allowRecursive:(BOOL)allowRecursive
+ functionName:(const char *)functionName {
+ self = [super init];
+ if (self) {
+ // In the thread's dictionary, we keep a counted set of the names
+ // of functions that are synchronizing on the object.
+ Class threadKey = [GTMSyncMonitorInternal class];
+ _objectKey = [NSValue valueWithNonretainedObject:object];
+ _functionName = functionName;
+
+ NSMutableDictionary *threadDict = [NSThread currentThread].threadDictionary;
+ NSMutableDictionary *counters = threadDict[threadKey];
+ if (counters == nil) {
+ counters = [NSMutableDictionary dictionary];
+ threadDict[(id)threadKey] = counters;
+ }
+ NSCountedSet *functionNamesCounter = counters[_objectKey];
+ NSUInteger numberOfSyncingFunctions = functionNamesCounter.count;
+
+ if (!allowRecursive) {
+ BOOL isTopLevelSyncScope = (numberOfSyncingFunctions == 0);
+ NSArray *stack = [NSThread callStackSymbols];
+ _GTMDevAssert(isTopLevelSyncScope,
+ @"*** Recursive sync on %@ at %s; previous sync at %@\n%@",
+ [object class], functionName, functionNamesCounter.allObjects,
+ [stack subarrayWithRange:NSMakeRange(1, stack.count - 1)]);
+ }
+
+ if (!functionNamesCounter) {
+ functionNamesCounter = [NSCountedSet set];
+ counters[_objectKey] = functionNamesCounter;
+ }
+ [functionNamesCounter addObject:@(functionName)];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ Class threadKey = [GTMSyncMonitorInternal class];
+
+ NSMutableDictionary *threadDict = [NSThread currentThread].threadDictionary;
+ NSMutableDictionary *counters = threadDict[threadKey];
+ NSCountedSet *functionNamesCounter = counters[_objectKey];
+ NSString *functionNameStr = @(_functionName);
+ NSUInteger numberOfSyncsByThisFunction = [functionNamesCounter countForObject:functionNameStr];
+ NSArray *stack = [NSThread callStackSymbols];
+ _GTMDevAssert(numberOfSyncsByThisFunction > 0, @"Sync not found on %@ at %s\n%@",
+ [_objectKey.nonretainedObjectValue class], _functionName,
+ [stack subarrayWithRange:NSMakeRange(1, stack.count - 1)]);
+ [functionNamesCounter removeObject:functionNameStr];
+ if (functionNamesCounter.count == 0) {
+ [counters removeObjectForKey:_objectKey];
+ }
+}
+
++ (NSArray *)functionsHoldingSynchronizationOnObject:(id)object {
+ Class threadKey = [GTMSyncMonitorInternal class];
+ NSValue *localObjectKey = [NSValue valueWithNonretainedObject:object];
+
+ NSMutableDictionary *threadDict = [NSThread currentThread].threadDictionary;
+ NSMutableDictionary *counters = threadDict[threadKey];
+ NSCountedSet *functionNamesCounter = counters[localObjectKey];
+ return functionNamesCounter.count > 0 ? functionNamesCounter.allObjects : nil;
+}
+
+@end
+
+#endif // DEBUG
diff --git a/DebugUtils/GTMSynchronizationAssertsTest.m b/DebugUtils/GTMSynchronizationAssertsTest.m
new file mode 100644
index 0000000..f08fc3e
--- /dev/null
+++ b/DebugUtils/GTMSynchronizationAssertsTest.m
@@ -0,0 +1,288 @@
+/* Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import <XCTest/XCTest.h>
+
+#import <objc/runtime.h>
+
+// For testing, force use of the default debug versions of the _GTMDevAssert macro.
+#undef _GTMDevAssert
+#undef NS_BLOCK_ASSERTIONS
+#undef DEBUG
+#define DEBUG 1
+
+#import "GTMSynchronizationAsserts.h"
+
+@interface GTMSynchonizationAssertsTest : XCTestCase
+@end
+
+@implementation GTMSynchonizationAssertsTest
+
+- (void)verifySynchronized {
+ // Test both GTMCheckSynchronized and GTMCheckNotSynchronized assuming we're in a sync block.
+ @try {
+ GTMCheckSynchronized(self);
+ } @catch (NSException *exception) {
+ XCTFail(@"shouldn't have thrown");
+ }
+
+ @try {
+ GTMCheckNotSynchronized(self);
+ XCTFail(@"should have thrown");
+ } @catch (NSException *exception) {
+ }
+}
+
+- (void)verifyNotSynchronized {
+ // Test both GTMCheckSynchronized and GTMCheckNotSynchronized assuming we're not in a sync block.
+ @try {
+ GTMCheckNotSynchronized(self);
+ } @catch (NSException *exception) {
+ XCTFail(@"shouldn't have thrown");
+ }
+
+ @try {
+ GTMCheckSynchronized(self);
+ XCTFail(@"shoul have thrown");
+ } @catch (NSException *exception) {
+ }
+}
+
+- (void)testChecks_SingleMethod {
+ [self verifyNotSynchronized];
+
+ @synchronized(self) {
+ GTMMonitorSynchronized(self);
+ [self verifySynchronized];
+
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ [self verifySynchronized];
+
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ [self verifySynchronized];
+ }
+ }
+ }
+ [self verifyNotSynchronized];
+}
+
+- (void)testChecks_AcrossMethods {
+ [self doIndirectCheckNotSynchronized];
+
+ @synchronized(self) {
+ GTMMonitorSynchronized(self);
+ [self verifySynchronized];
+
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ [self doIndirectCheckSynchronized];
+
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ [self doIndirectCheckSynchronized];
+ }
+ }
+ }
+ [self doIndirectCheckNotSynchronized];
+}
+
+- (void)doIndirectCheckSynchronized {
+ // Verify from a separate method.
+ [self verifySynchronized];
+}
+
+- (void)doIndirectCheckNotSynchronized {
+ // Verify from a separate method.
+ [self verifyNotSynchronized];
+}
+
+#pragma mark Sync Monitor Tests
+
+- (void)testNonrecursiveSync {
+ // Non-recursive monitors.
+ XCTestExpectation *outer = [self expectationWithDescription:@"outer"];
+ XCTestExpectation *inner = [self expectationWithDescription:@"inner"];
+
+ @try {
+ @synchronized(self) {
+ GTMMonitorSynchronized(self);
+ [outer fulfill];
+
+ @synchronized(self) {
+ GTMMonitorSynchronized(self);
+ XCTFail(@"should have thrown");
+ }
+ }
+ } @catch (NSException *exception) {
+ [inner fulfill];
+ }
+
+ [self waitForExpectationsWithTimeout:1 handler:nil];
+}
+
+- (void)testRecursiveSync_SingleMethod {
+ // The inner monitors are recursive.
+ XCTestExpectation *outer = [self expectationWithDescription:@"outer"];
+ XCTestExpectation *inner1 = [self expectationWithDescription:@"inner1"];
+ XCTestExpectation *inner2 = [self expectationWithDescription:@"inner2"];
+
+ @try {
+ @synchronized(self) {
+ GTMMonitorSynchronized(self);
+ [outer fulfill];
+
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ [inner1 fulfill];
+
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ [inner2 fulfill];
+ }
+ }
+ }
+ } @catch (NSException *exception) {
+ XCTFail(@"shouldn't have thrown");
+ }
+
+ [self waitForExpectationsWithTimeout:1 handler:nil];
+}
+
+- (void)testRecursiveSync_AcrossMethods {
+ // The inner monitors are recursive.
+ XCTestExpectation *outer = [self expectationWithDescription:@"outer"];
+ XCTestExpectation *inner1 = [self expectationWithDescription:@"inner1"];
+ XCTestExpectation *inner2 = [self expectationWithDescription:@"inner2"];
+
+ @try {
+ @synchronized(self) {
+ GTMMonitorSynchronized(self);
+ [outer fulfill];
+
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ [inner1 fulfill];
+
+ [self doInnerRecursiveSync];
+ [inner2 fulfill];
+ }
+ }
+ } @catch (NSException *exception) {
+ XCTFail(@"shouldn't have thrown");
+ }
+
+ [self waitForExpectationsWithTimeout:1 handler:nil];
+}
+
+- (void)doInnerRecursiveSync {
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ }
+}
+
+- (void)testRecursiveThenNonrecursiveSync_SingleMethod {
+ // The outer monitors are recursive, but the inner one is not and should throw.
+ XCTestExpectation *outer1 = [self expectationWithDescription:@"outer1"];
+ XCTestExpectation *outer2 = [self expectationWithDescription:@"outer2"];
+ XCTestExpectation *inner = [self expectationWithDescription:@"inner"];
+
+ @try {
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ [outer1 fulfill];
+
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ [outer2 fulfill];
+
+ @synchronized(self) {
+ GTMMonitorSynchronized(self);
+ XCTFail(@"should have thrown");
+ }
+ }
+ }
+ } @catch (NSException *exception) {
+ [inner fulfill];
+ }
+
+ [self waitForExpectationsWithTimeout:1 handler:nil];
+}
+
+- (void)testRecursiveThenNonrecursiveSync_AcrossMethods {
+ // The outer monitors are recursive, but the inner one is not and should throw.
+ XCTestExpectation *outer1 = [self expectationWithDescription:@"outer1"];
+ XCTestExpectation *outer2 = [self expectationWithDescription:@"outer2"];
+ XCTestExpectation *inner = [self expectationWithDescription:@"inner"];
+
+ @try {
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ [outer1 fulfill];
+
+ @synchronized(self) {
+ GTMMonitorRecursiveSynchronized(self);
+ [outer2 fulfill];
+
+ [self doInnerNonrecursiveSync];
+ }
+ }
+ } @catch (NSException *exception) {
+ [inner fulfill];
+ }
+
+ [self waitForExpectationsWithTimeout:1 handler:nil];
+}
+
+- (void)doInnerNonrecursiveSync {
+ @synchronized(self) {
+ GTMMonitorSynchronized(self);
+ XCTFail(@"should have thrown");
+ }
+}
+
+- (void)testSyncOnSeparateObjects {
+ // Verify that monitoring works for distinct sync objects.
+ XCTestExpectation *outer = [self expectationWithDescription:@"outer"];
+ XCTestExpectation *innerA = [self expectationWithDescription:@"innerA"];
+ XCTestExpectation *innerB = [self expectationWithDescription:@"innerB"];
+
+ id obj1 = [[NSObject alloc] init];
+ id obj2 = [[NSObject alloc] init];
+
+ @try {
+ @synchronized(obj1) {
+ GTMMonitorSynchronized(obj1);
+ [outer fulfill];
+
+ @synchronized(obj2) {
+ GTMMonitorSynchronized(obj2);
+ [innerA fulfill];
+
+ @synchronized(obj1) {
+ GTMMonitorSynchronized(obj1);
+ XCTFail(@"should have thrown");
+ }
+ }
+ }
+ } @catch (NSException *exception) {
+ [innerB fulfill];
+ }
+
+ [self waitForExpectationsWithTimeout:1 handler:nil];
+}
+
+@end
diff --git a/Foundation/GTMNSAppleScript+Handler.m b/Foundation/GTMNSAppleScript+Handler.m
index e17ba91..850de58 100644
--- a/Foundation/GTMNSAppleScript+Handler.m
+++ b/Foundation/GTMNSAppleScript+Handler.m
@@ -22,7 +22,6 @@
#import "GTMNSAppleEventDescriptor+Handler.h"
#import "GTMFourCharCode.h"
#import "GTMMethodCheck.h"
-#import "GTMDebugThreadValidation.h"
// Keys for passing AppleScript calls from other threads to the main thread
// and back through gtm_internalExecuteAppleEvent:
@@ -326,7 +325,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:);
}
- (NSAppleEventDescriptor*)gtm_valueDescriptorForProperty:(id)property {
- GTMAssertRunningOnMainThread();
+ _GTMDevAssert([NSThread isMainThread], @"Requires main thread.");
OSAError error = paramErr;
NSAppleEventDescriptor *desc = nil;
NSAppleEventDescriptor *propertyName
@@ -377,7 +376,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:);
}
- (NSSet*)gtm_scriptHandlers {
- GTMAssertRunningOnMainThread();
+ _GTMDevAssert([NSThread isMainThread], @"Requires main thread.");
AEDescList names = { typeNull, NULL };
NSArray *array = nil;
ComponentInstance component = NULL;
@@ -396,7 +395,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:);
}
- (NSSet*)gtm_scriptProperties {
- GTMAssertRunningOnMainThread();
+ _GTMDevAssert([NSThread isMainThread], @"Requires main thread.");
AEDescList names = { typeNull, NULL };
NSArray *array = nil;
ComponentInstance component = NULL;
@@ -415,7 +414,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:);
}
- (OSAID)gtm_genericID:(OSAID)osaID forComponent:(ComponentInstance)component {
- GTMAssertRunningOnMainThread();
+ _GTMDevAssert([NSThread isMainThread], @"Requires main thread.");
ComponentInstance genericComponent = [NSAppleScript _defaultScriptingComponent];
OSAID exactID = osaID;
OSAError error = OSARealToGenericID(genericComponent, &exactID, component);
@@ -428,7 +427,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:);
- (NSAppleEventDescriptor*)descForScriptID:(OSAID)osaID
component:(ComponentInstance)component {
- GTMAssertRunningOnMainThread();
+ _GTMDevAssert([NSThread isMainThread], @"Requires main thread.");
NSAppleEventDescriptor *desc = nil;
// If we have a script, return a typeGTMOSAID, otherwise convert it to
// it's default AEDesc using OSACoerceToDesc with typeWildCard.
@@ -468,7 +467,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:);
}
- (OSAID)gtm_realIDAndComponent:(ComponentInstance*)component {
- GTMAssertRunningOnMainThread();
+ _GTMDevAssert([NSThread isMainThread], @"Requires main thread.");
if (![self isCompiled]) {
NSDictionary *error;
if (![self compileAndReturnError:&error]) {
@@ -487,7 +486,7 @@ GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:);
}
- (void)gtm_internalExecuteAppleEvent:(NSMutableDictionary *)data {
- GTMAssertRunningOnMainThread();
+ _GTMDevAssert([NSThread isMainThread], @"Requires main thread.");
NSDictionary *error = nil;
if (![self isCompiled]) {
[self compileAndReturnError:&error];
diff --git a/ReleaseNotes.md b/ReleaseNotes.md
index 75524a9..339aaa3 100644
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -37,6 +37,7 @@ Changes since 1.6.0<br>
- Removed GTMNSNumber+64Bit methods as obsolete.
+- Removed GTM_ENABLE_LEAKS.
**Release 1.6.0**<br>
Changes since 1.5.1<br>
diff --git a/UnitTesting/GTMSenTestCase.h b/UnitTesting/GTMSenTestCase.h
index b637b43..a96cb20 100644
--- a/UnitTesting/GTMSenTestCase.h
+++ b/UnitTesting/GTMSenTestCase.h
@@ -216,90 +216,6 @@
})
#endif // XCTAssertNULL
-// Generates a failure when a1 is not 'op' to a2. This test is for C scalars.
-// Args:
-// a1: argument 1
-// a2: argument 2
-// op: operation
-// format: A format string as in the printf() function. Can be nil or
-// an empty string but must be present.
-// ...: A variable number of arguments to the format string. Can be absent.
-#ifndef XCTAssertOperation
-#define XCTAssertOperation(a1, a2, op, format...) \
-({ \
- NSString *_failure = nil; \
- @try { \
- __typeof__(a1) _a1value = (a1); \
- __typeof__(a2) _a2value = (a2); \
- if (!(_a1value op _a2value)) { \
- _failure = [NSString stringWithFormat:@"(%@) is not %s (%@)", @(_a1value), #op, @(_a2value)]; \
- } \
- } \
- @catch (NSException *_exception) { \
- _failure = [NSString stringWithFormat:_XCExceptionFormatString, [_exception reason]]; \
- } \
- @catch (...) { \
- _failure = _XCUnknownExceptionString; \
- } \
- if (_failure) { \
- NSString *_expression = [NSString stringWithFormat:@"((%@) %s (%@)) failed: %@", @#a1, #op, @#a2, _failure]; \
- _GTMXCRegisterFailure(_expression, format); \
- } \
-})
-#endif // XCTAssertOperation
-
-// Generates a failure when a1 is not > a2. This test is for C scalars.
-// Args:
-// a1: argument 1
-// a2: argument 2
-// op: operation
-// description: A format string as in the printf() function. Can be nil or
-// an empty string but must be present.
-// ...: A variable number of arguments to the format string. Can be absent.
-#ifndef XCTAssertGreaterThanOrEqual
-#define XCTAssertGreaterThan(a1, a2, format...) \
- XCTAssertOperation(a1, a2, >, ##format)
-#endif // XCTAssertGreaterThan
-
-// Generates a failure when a1 is not >= a2. This test is for C scalars.
-// Args:
-// a1: argument 1
-// a2: argument 2
-// op: operation
-// description: A format string as in the printf() function. Can be nil or
-// an empty string but must be present.
-// ...: A variable number of arguments to the format string. Can be absent.
-#ifndef XCTAssertGreaterThanOrEqual
-#define XCTAssertGreaterThanOrEqual(a1, a2, format...) \
- XCTAssertOperation(a1, a2, >=, ##format)
-#endif // XCTAssertGreaterThanOrEqual
-
-// Generates a failure when a1 is not < a2. This test is for C scalars.
-// Args:
-// a1: argument 1
-// a2: argument 2
-// op: operation
-// description: A format string as in the printf() function. Can be nil or
-// an empty string but must be present.
-// ...: A variable number of arguments to the format string. Can be absent.
-#ifndef XCTAssertLessThan
-#define XCTAssertLessThan(a1, a2, format...) \
- XCTAssertOperation(a1, a2, <, ##format)
-#endif // XCTAssertLessThan
-
-// Generates a failure when a1 is not <= a2. This test is for C scalars.
-// Args:
-// a1: argument 1
-// a2: argument 2
-// op: operation
-// description: A format string as in the printf() function. Can be nil or
-// an empty string but must be present.
-// ...: A variable number of arguments to the format string. Can be absent.
-#ifndef XCTAssertLessThanOrEqual
-#define XCTAssertLessThanOrEqual(a1, a2, format...) \
- XCTAssertOperation(a1, a2, <=, ##format)
-#endif // XCTAssertLessThanOrEqual
-
// Generates a failure when string a1 is not equal to string a2. This call
// differs from XCTAssertEqualObjects in that strings that are different in
// composition (precomposed vs decomposed) will compare equal if their final
@@ -812,100 +728,6 @@ do { \
} \
} while (0)
-// Generates a failure when c-string a1 is equal to c-string a2.
-// Args:
-// a1: string 1
-// a2: string 2
-// description: A format string as in the printf() function. Can be nil or
-// an empty string but must be present.
-// ...: A variable number of arguments to the format string. Can be absent.
-#define STAssertNotEqualCStrings(a1, a2, description, ...) \
-do { \
- @try { \
- const char* _a1value = (a1); \
- const char* _a2value = (a2); \
- if (strcmp(_a1value, _a2value) != 0) continue; \
- [self failWithException:[NSException failureInEqualityBetweenObject:[NSString stringWithUTF8String:_a1value] \
- andObject:[NSString stringWithUTF8String:_a2value] \
- inFile:[NSString stringWithUTF8String:__FILE__] \
- atLine:__LINE__ \
- withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
- } \
- @catch (id anException) { \
- [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \
- exception:anException \
- inFile:[NSString stringWithUTF8String:__FILE__] \
- atLine:__LINE__ \
- withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
- } \
-} while (0)
-
-/*" Generates a failure when a1 is not equal to a2 within + or - accuracy is false.
- This test is for GLKit types (GLKVector, GLKMatrix) where small differences
- could make these items not exactly equal. Do not use this version directly.
- Use the explicit STAssertEqualGLKVectors and STAssertEqualGLKMatrices defined
- below.
- _{a1 The GLKType on the left.}
- _{a2 The GLKType on the right.}
- _{accuracy The maximum difference between a1 and a2 for these values to be
- considered equal.}
- _{description A format string as in the printf() function. Can be nil or
- an empty string but must be present.}
- _{... A variable number of arguments to the format string. Can be absent.}
-"*/
-
-#define STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ...) \
-do { \
- @try { \
- if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \
- [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
- atLine:__LINE__ \
- withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \
- } else { \
- __typeof__(a1) a1GLKValue = (a1); \
- __typeof__(a2) a2GLKValue = (a2); \
- __typeof__(accuracy) accuracyvalue = (accuracy); \
- float *a1FloatValue = ((float*)&a1GLKValue); \
- float *a2FloatValue = ((float*)&a2GLKValue); \
- for (size_t i = 0; i < sizeof(__typeof__(a1)) / sizeof(float); ++i) { \
- float _a1value = a1FloatValue[i]; \
- float _a2value = a2FloatValue[i]; \
- if (STAbsoluteDifference(_a1value, _a2value) > accuracyvalue) { \
- NSMutableArray *strings = [NSMutableArray arrayWithCapacity:sizeof(a1) / sizeof(float)]; \
- NSString *string; \
- for (size_t j = 0; j < sizeof(__typeof__(a1)) / sizeof(float); ++j) { \
- string = [NSString stringWithFormat:@"(%0.3f == %0.3f)", a1FloatValue[j], a2FloatValue[j]]; \
- [strings addObject:string]; \
- } \
- string = [strings componentsJoinedByString:@", "]; \
- NSString *desc = STComposeString(description, ##__VA_ARGS__); \
- desc = [NSString stringWithFormat:@"%@ With Accuracy %0.3f: %@", string, (float)accuracyvalue, desc]; \
- [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
- atLine:__LINE__ \
- withDescription:@"%@", desc]]; \
- break; \
- } \
- } \
- } \
- } \
- @catch (id anException) { \
- [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
- exception:anException \
- inFile:[NSString stringWithUTF8String:__FILE__] \
- atLine:__LINE__ \
- withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
- } \
-} while (0)
-
-#define STAssertEqualGLKVectors(a1, a2, accuracy, description, ...) \
- STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__)
-
-#define STAssertEqualGLKMatrices(a1, a2, accuracy, description, ...) \
- STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__)
-
-#define STAssertEqualGLKQuaternions(a1, a2, accuracy, description, ...) \
- STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__)
-
#endif // GTM_USING_XCTEST
#if GTM_IPHONE_SDK && !GTM_IPHONE_USE_SENTEST && !GTM_USING_XCTEST
// When not using the Xcode provided version, define everything ourselves.
@@ -1469,12 +1291,6 @@ GTM_EXTERN NSString *const SenTestLineNumberKey;
#endif // GTM_IPHONE_SDK && !GTM_IPHONE_USE_SENTEST && !GTM_USING_XCTEST
-#if GTM_IPHONE_SDK
-
-@class UIImage;
-
-#endif // GTM_IPHONE_SDK
-
// All unittest cases in GTM should inherit from GTMTestCase. It makes sure
// to set up our logging system correctly to verify logging calls.
// See GTMUnitTestDevLog.h for details
@@ -1506,13 +1322,4 @@ GTM_EXTERN NSString *const SenTestLineNumberKey;
// "AbstractTest" (case sensitive).
+ (BOOL)isAbstractTestCase;
-#if GTM_IPHONE_SDK
-// Returns the UIImage for the the named |resource|. Asserts that the image is
-// loaded (is non-nil).
-//
-// This is required as while under test, [UIImage imageNamed:...] does not
-// correctly load images from the resources associated with a test class.
-- (UIImage *)imageFromResource:(NSString *)resource;
-#endif // GTM_IPHONE_SDK
-
@end
diff --git a/UnitTesting/GTMSenTestCase.m b/UnitTesting/GTMSenTestCase.m
index ecab057..1de4ca7 100644
--- a/UnitTesting/GTMSenTestCase.m
+++ b/UnitTesting/GTMSenTestCase.m
@@ -422,20 +422,6 @@ static NSInteger MethodSort(id a, id b, void *context) {
return [name rangeOfString:@"AbstractTest"].location != NSNotFound;
}
-#if GTM_IPHONE_SDK
-- (UIImage *)imageFromResource:(NSString *)resource {
- NSBundle *bundle = [NSBundle bundleForClass:[self class]];
- NSString *path = [bundle pathForResource:resource ofType:nil];
- UIImage *image = [UIImage imageWithContentsOfFile:path];
-#if GTM_USING_XCTEST
- XCTAssertNotNil(image, @"Could not load image from resource: %@", path);
-#else
- STAssertNotNil(image, @"Could not load image from resource: %@", path);
-#endif // GTM_USING_XCTEST
- return image;
-}
-#endif
-
+ (NSArray *)testInvocations {
NSArray *invocations = nil;
if (![self isAbstractTestCase]) {
@@ -445,65 +431,3 @@ static NSInteger MethodSort(id a, id b, void *context) {
}
@end
-
-// Leak detection
-#if !GTM_IPHONE_DEVICE && !GTM_SUPPRESS_RUN_LEAKS_HOOK
-// Don't want to get leaks on the iPhone Device as the device doesn't
-// have 'leaks'. The simulator does though.
-
-// COV_NF_START
-// We don't have leak checking on by default, so this won't be hit.
-static void _GTMRunLeaks(void) {
- // This is an atexit handler. It runs leaks for us to check if we are
- // leaking anything in our tests.
- const char* cExclusionsEnv = getenv("GTM_LEAKS_SYMBOLS_TO_IGNORE");
- NSMutableString *exclusions = [NSMutableString string];
- if (cExclusionsEnv) {
- NSString *exclusionsEnv = [NSString stringWithUTF8String:cExclusionsEnv];
- NSArray *exclusionsArray = [exclusionsEnv componentsSeparatedByString:@","];
- NSString *exclusion;
- NSCharacterSet *wcSet = [NSCharacterSet whitespaceCharacterSet];
- GTM_FOREACH_OBJECT(exclusion, exclusionsArray) {
- exclusion = [exclusion stringByTrimmingCharactersInSet:wcSet];
- [exclusions appendFormat:@"-exclude \"%@\" ", exclusion];
- }
- }
- // Clearing out DYLD_ROOT_PATH because iPhone Simulator framework libraries
- // are different from regular OS X libraries and leaks will fail to run
- // because of missing symbols. Also capturing the output of leaks and then
- // pipe rather than a direct pipe, because otherwise if leaks failed,
- // the system() call will still be successful. Bug:
- // http://code.google.com/p/google-toolbox-for-mac/issues/detail?id=56
- NSString *string
- = [NSString stringWithFormat:
- @"LeakOut=`DYLD_ROOT_PATH='' /usr/bin/leaks %@%d` &&"
- @"echo \"$LeakOut\"|/usr/bin/sed -e 's/Leak: /Leaks:0: warning: Leak /'",
- exclusions, getpid()];
- int ret = system([string UTF8String]);
- if (ret) {
- fprintf(stderr,
- "%s:%d: Error: Unable to run leaks. 'system' returned: %d\n",
- __FILE__, __LINE__, ret);
- fflush(stderr);
- }
-}
-// COV_NF_END
-
-static __attribute__((constructor)) void _GTMInstallLeaks(void) {
- BOOL checkLeaks = getenv("GTM_ENABLE_LEAKS") ? YES : NO;
- if (checkLeaks) {
- // COV_NF_START
- // We don't have leak checking on by default, so this won't be hit.
- fprintf(stderr, "Leak Checking Enabled\n");
- fflush(stderr);
- int ret = atexit(&_GTMRunLeaks);
- // To avoid unused variable warning when _GTMDevAssert is stripped.
- (void)ret;
- _GTMDevAssert(ret == 0,
- @"Unable to install _GTMRunLeaks as an atexit handler (%d)",
- errno);
- // COV_NF_END
- }
-}
-
-#endif // !GTM_IPHONE_DEVICE && !GTM_SUPPRESS_RUN_LEAKS_HOOK
diff --git a/UnitTesting/RunIPhoneUnitTest.sh b/UnitTesting/RunIPhoneUnitTest.sh
index 743d1ec..f27f854 100755
--- a/UnitTesting/RunIPhoneUnitTest.sh
+++ b/UnitTesting/RunIPhoneUnitTest.sh
@@ -28,22 +28,11 @@ set -o nounset
# want to turn this off if you enable leaks.
GTM_DISABLE_ZOMBIES=${GTM_DISABLE_ZOMBIES:=1}
-# GTM_ENABLE_LEAKS -
-# Set to a non-zero value to turn on the leaks check. You will probably want
-# to disable zombies, otherwise you will get a lot of false positives.
-
# GTM_DISABLE_TERMINATION
# Set to a non-zero value so that the app doesn't terminate when it's finished
# running tests. This is useful when using it with external tools such
# as Instruments.
-# GTM_LEAKS_SYMBOLS_TO_IGNORE
-# List of comma separated symbols that leaks should ignore. Mainly to control
-# leaks in frameworks you don't have control over.
-# Search this file for GTM_LEAKS_SYMBOLS_TO_IGNORE to see examples.
-# Please feel free to add other symbols as you find them but make sure to
-# reference Radars or other bug systems so we can track them.
-
# GTM_REMOVE_GCOV_DATA
# Before starting the test, remove any *.gcda files for the current run so
# you won't get errors when the source file has changed and the data can't
@@ -194,10 +183,6 @@ elif [ "$PLATFORM_NAME" == "iphonesimulator" ]; then
export OBJC_DEBUG_NIL_SYNC=YES
export OBJC_PRINT_REPLACED_METHODS=YES
- # 6251475 iPhone simulator leaks @ CFHTTPCookieStore shutdown if
- # CFFIXED_USER_HOME empty
- GTM_LEAKS_SYMBOLS_TO_IGNORE="CFHTTPCookieStore"
-
# Start our app.
"$TARGET_BUILD_DIR/$EXECUTABLE_PATH" -RegisterForSystemEvents
diff --git a/UnitTesting/RunMacOSUnitTests.sh b/UnitTesting/RunMacOSUnitTests.sh
index 2f72a12..ed412c0 100755
--- a/UnitTesting/RunMacOSUnitTests.sh
+++ b/UnitTesting/RunMacOSUnitTests.sh
@@ -35,19 +35,6 @@ export TEST_AFTER_BUILD=YES
# want to turn this off if you enable leaks.
GTM_DISABLE_ZOMBIES=${GTM_DISABLE_ZOMBIES:=0}
-# GTM_ENABLE_LEAKS -
-# Set to a non-zero value to turn on the leaks check. You will probably want
-# to disable zombies, otherwise you will get a lot of false positives.
-GTM_ENABLE_LEAKS=${GTM_ENABLE_LEAKS:=0}
-
-# GTM_LEAKS_SYMBOLS_TO_IGNORE
-# List of comma separated symbols that leaks should ignore. Mainly to control
-# leaks in frameworks you don't have control over.
-# Search this file for GTM_LEAKS_SYMBOLS_TO_IGNORE to see examples.
-# Please feel free to add other symbols as you find them but make sure to
-# reference Radars or other bug systems so we can track them.
-GTM_LEAKS_SYMBOLS_TO_IGNORE=${GTM_LEAKS_SYMBOLS_TO_IGNORE:=""}
-
# GTM_DO_NOT_REMOVE_GCOV_DATA
# By default before starting the test, we remove any *.gcda files for the
# current project build configuration so you won't get errors when a source
@@ -96,71 +83,6 @@ sys.exit(subprocess.call(sys.argv[1:]))" "${@}"
fi
}
-# The workaround below is due to
-# Radar 6248062 otest won't run with MallocHistory enabled under rosetta
-# Basically we go through and check what architecture we are running on
-# and which architectures we can support
-AppendToSymbolsLeaksShouldIgnore() {
- if [ "${GTM_LEAKS_SYMBOLS_TO_IGNORE}" = "" ]; then
- GTM_LEAKS_SYMBOLS_TO_IGNORE="${1}"
- else
- GTM_LEAKS_SYMBOLS_TO_IGNORE="${GTM_LEAKS_SYMBOLS_TO_IGNORE}, ${1}"
- fi
-}
-
-AppendToLeakTestArchs() {
- if [ "${LEAK_TEST_ARCHS}" = "" ]; then
- LEAK_TEST_ARCHS="${1}"
- else
- LEAK_TEST_ARCHS="${LEAK_TEST_ARCHS} ${1}"
- fi
-}
-
-AppendToNoLeakTestArchs() {
- if [ "${NO_LEAK_TEST_ARCHS}" = "" ]; then
- NO_LEAK_TEST_ARCHS="${1}"
- else
- NO_LEAK_TEST_ARCHS="${NO_LEAK_TEST_ARCHS} ${1}"
- fi
-}
-
-UpdateArchitecturesToTest() {
- case "${NATIVE_ARCH_ACTUAL}" in
- ppc)
- if [ "${1}" = "ppc" ]; then
- AppendToLeakTestArchs "${1}"
- fi
- ;;
-
- ppc64)
- if [ "${1}" = "ppc" -o "${1}" = "ppc64" ]; then
- AppendToLeakTestArchs "${1}"
- fi
- ;;
-
- i386)
- if [ "${1}" = "i386" ]; then
- AppendToLeakTestArchs "${1}"
- elif [ "${1}" = "ppc" ]; then
- AppendToNoLeakTestArchs "${1}"
- fi
- ;;
-
- x86_64)
- if [ "${1}" = "i386" -o "${1}" = "x86_64" ]; then
- AppendToLeakTestArchs "${1}"
- elif [ "${1}" = "ppc" -o "${1}" = "ppc64" ]; then
- AppendToNoLeakTestArchs "${1}"
- fi
- ;;
-
- *)
- echo "RunMacOSUnitTests.sh Unknown native architecture: ${NATIVE_ARCH_ACTUAL}"
- exit 1
- ;;
- esac
-}
-
SetMemoryVariables() {
# Jack up some memory stress so we can catch more bugs.
@@ -189,68 +111,6 @@ SetMemoryVariables() {
export OBJC_DEBUG_NIL_SYNC=YES
}
-RunTests() {
- if [ "${CURRENT_ARCH}" = "" ]; then
- CURRENT_ARCH=`arch`
- fi
-
- if [ "${ONLY_ACTIVE_ARCH}" = "YES" ]; then
- ARCHS="${CURRENT_ARCH}"
- fi
-
- if [ "${ARCHS}" = "" ]; then
- ARCHS=`arch`
- fi
-
- if [ "${VALID_ARCHS}" = "" ]; then
- VALID_ARCHS=`arch`
- fi
-
- if [ "${NATIVE_ARCH_ACTUAL}" = "" ]; then
- NATIVE_ARCH_ACTUAL=`arch`
- fi
-
- LEAK_TEST_ARCHS=""
- NO_LEAK_TEST_ARCHS=""
-
- for TEST_ARCH in ${ARCHS}; do
- for TEST_VALID_ARCH in ${VALID_ARCHS}; do
- if [ "${TEST_VALID_ARCH}" = "${TEST_ARCH}" ]; then
- UpdateArchitecturesToTest "${TEST_ARCH}"
- fi
- done
- done
-
- # These are symbols that leak on OS 10.5.5
- # radar 6247293 NSCollatorElement leaks in +initialize.
- AppendToSymbolsLeaksShouldIgnore "+[NSCollatorElement initialize]"
- # radar 6247911 The first call to udat_open leaks only on x86_64
- AppendToSymbolsLeaksShouldIgnore "icu::TimeZone::initDefault()"
- # radar 6263983 +[IMService allServices] leaks
- AppendToSymbolsLeaksShouldIgnore "-[IMServiceAgentImpl allServices]"
- # radar 6264034 +[IKSFEffectDescription initialize] Leaks
- AppendToSymbolsLeaksShouldIgnore "+[IKSFEffectDescription initialize]"
- # radar 7598715 Leak when creating new NSColor using lab color space.
- AppendToSymbolsLeaksShouldIgnore "CMSSetLabCLUT"
-
- # Running leaks on architectures that support leaks.
- export MallocStackLogging=YES
- export GTM_LEAKS_SYMBOLS_TO_IGNORE="${GTM_LEAKS_SYMBOLS_TO_IGNORE}"
- ARCHS="${LEAK_TEST_ARCHS}"
- VALID_ARCHS="${LEAK_TEST_ARCHS}"
- GTMXcodeNote ${LINENO} "Leak checking enabled for $ARCHS. Ignoring leaks from $GTM_LEAKS_SYMBOLS_TO_IGNORE."
- SetMemoryVariables
- MaybeFlock "${SYSTEM_DEVELOPER_DIR}/Tools/RunTargetUnitTests"
-
- # Running leaks on architectures that don't support leaks.
- unset MallocStackLogging
- unset GTM_ENABLE_LEAKS
- ARCHS="${NO_LEAK_TEST_ARCHS}"
- VALID_ARCHS="${NO_LEAK_TEST_ARCHS}"
- GTMXcodeNote ${LINENO} "Leak checking disabled for $ARCHS due to no support for leaks on platform".
- MaybeFlock "${SYSTEM_DEVELOPER_DIR}/Tools/RunTargetUnitTests"
-}
-
if [ ! $GTM_DO_NOT_REMOVE_GCOV_DATA ]; then
GTM_GCOV_CLEANUP_DIR="${CONFIGURATION_TEMP_DIR}"
if [ $GTM_REMOVE_TARGET_GCOV_ONLY ]; then
@@ -265,12 +125,5 @@ if [ ! $GTM_DO_NOT_REMOVE_GCOV_DATA ]; then
fi
fi
-# If leaks testing is enabled, we have to go through our convoluted path
-# to handle architectures that don't allow us to do leak testing.
-if [ $GTM_ENABLE_LEAKS -ne 0 ]; then
- RunTests
-else
- GTMXcodeNote ${LINENO} "Leak checking disabled."
- SetMemoryVariables
- MaybeFlock "${SYSTEM_DEVELOPER_DIR}/Tools/RunTargetUnitTests"
-fi
+SetMemoryVariables
+MaybeFlock "${SYSTEM_DEVELOPER_DIR}/Tools/RunTargetUnitTests"
diff --git a/UnitTesting/RuniOSUnitTestsUnderSimulator.sh b/UnitTesting/RuniOSUnitTestsUnderSimulator.sh
index 975ce78..ac81def 100755
--- a/UnitTesting/RuniOSUnitTestsUnderSimulator.sh
+++ b/UnitTesting/RuniOSUnitTestsUnderSimulator.sh
@@ -51,22 +51,11 @@ GTM_SIMULATOR_USER_HOME=${GTM_SIMULATOR_USER_HOME:=default}
# Space separated set env variables in format of "KEY1=value1 KEY2=value2"
GTM_SIMULATOR_EXTRA_ENV=${GTM_SIMULATOR_EXTRA_ENV:=default}
-# GTM_ENABLE_LEAKS -
-# Set to a non-zero value to turn on the leaks check. You will probably want
-# to disable zombies, otherwise you will get a lot of false positives.
-
# GTM_DISABLE_TERMINATION
# Set to a non-zero value so that the app doesn't terminate when it's finished
# running tests. This is useful when using it with external tools such
# as Instruments.
-# GTM_LEAKS_SYMBOLS_TO_IGNORE
-# List of comma separated symbols that leaks should ignore. Mainly to control
-# leaks in frameworks you don't have control over.
-# Search this file for GTM_LEAKS_SYMBOLS_TO_IGNORE to see examples.
-# Please feel free to add other symbols as you find them but make sure to
-# reference Radars or other bug systems so we can track them.
-
# GTM_REMOVE_GCOV_DATA
# Before starting the test, remove any *.gcda files for the current run so
# you won't get errors when the source file has changed and the data can't
@@ -202,10 +191,6 @@ if [[ $GTM_REMOVE_GCOV_DATA -ne 0 ]]; then
fi
fi
-# 6251475 iPhone Simulator leaks @ CFHTTPCookieStore shutdown if
-# CFFIXED_USER_HOME empty
-GTM_LEAKS_SYMBOLS_TO_IGNORE="CFHTTPCookieStore"
-
#
# Build up the command line to run.
#