aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GTMiPhone.xcodeproj/project.pbxproj16
-rw-r--r--UnitTesting/GTMIPhoneSecurityLibraryTest.m75
-rwxr-xr-xUnitTesting/RunIPhoneLaunchDaemons.sh43
-rwxr-xr-xUnitTesting/RunIPhoneUnitTest.sh28
4 files changed, 115 insertions, 47 deletions
diff --git a/GTMiPhone.xcodeproj/project.pbxproj b/GTMiPhone.xcodeproj/project.pbxproj
index 41d7fb0..d241ce9 100644
--- a/GTMiPhone.xcodeproj/project.pbxproj
+++ b/GTMiPhone.xcodeproj/project.pbxproj
@@ -34,6 +34,10 @@
1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; };
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
+ 23220A06152C9E980060CB7D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 23220A05152C9E980060CB7D /* Security.framework */; };
+ 234E175D152CBB4900CF3542 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 23220A05152C9E980060CB7D /* Security.framework */; };
+ 234E17DC152CECFB00CF3542 /* GTMIPhoneSecurityLibraryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 234E17DB152CECFB00CF3542 /* GTMIPhoneSecurityLibraryTest.m */; };
+ 234E17DD152CECFB00CF3542 /* GTMIPhoneSecurityLibraryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 234E17DB152CECFB00CF3542 /* GTMIPhoneSecurityLibraryTest.m */; };
448D61FB11AC1F1B0097ACBC /* GTMUIImage+Resize_100x50_flipped.png in Resources */ = {isa = PBXBuildFile; fileRef = 448D61B111AC1AAD0097ACBC /* GTMUIImage+Resize_100x50_flipped.png */; };
448D61FC11AC1F250097ACBC /* GTMUIImage+Resize_50x100_flipped.png in Resources */ = {isa = PBXBuildFile; fileRef = 448D61B011AC1AAD0097ACBC /* GTMUIImage+Resize_50x100_flipped.png */; };
6294461C0EDE178D009295EA /* GTMNSArray+MergeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 629446190EDE177A009295EA /* GTMNSArray+MergeTest.m */; };
@@ -319,6 +323,8 @@
1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
1D6058910D05DD3D006BFB54 /* GTMiPhoneTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GTMiPhoneTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ 23220A05152C9E980060CB7D /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
+ 234E17DB152CECFB00CF3542 /* GTMIPhoneSecurityLibraryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMIPhoneSecurityLibraryTest.m; sourceTree = "<group>"; };
32CA4F630368D1EE00C91783 /* GTM_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTM_Prefix.pch; sourceTree = "<group>"; };
448D61B011AC1AAD0097ACBC /* GTMUIImage+Resize_50x100_flipped.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "GTMUIImage+Resize_50x100_flipped.png"; path = "TestData/GTMUIImage+Resize_50x100_flipped.png"; sourceTree = "<group>"; };
448D61B111AC1AAD0097ACBC /* GTMUIImage+Resize_100x50_flipped.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "GTMUIImage+Resize_100x50_flipped.png"; path = "TestData/GTMUIImage+Resize_100x50_flipped.png"; sourceTree = "<group>"; };
@@ -506,6 +512,7 @@
8BC04D480DB0088500C2D1CA /* libz.dylib in Frameworks */,
8B3AA9340E0336AC007E31B5 /* CFNetwork.framework in Frameworks */,
8B5A9E200E71CB6C005DA441 /* AddressBook.framework in Frameworks */,
+ 23220A06152C9E980060CB7D /* Security.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -521,6 +528,7 @@
F4D20F2514852D130001600C /* UIKit.framework in Frameworks */,
F4D20F2614852D130001600C /* libz.dylib in Frameworks */,
F4D20F4E148532D50001600C /* AddressBook.framework in Frameworks */,
+ 234E175D152CBB4900CF3542 /* Security.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -570,6 +578,7 @@
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
+ 23220A05152C9E980060CB7D /* Security.framework */,
8B3AA9330E0336AC007E31B5 /* CFNetwork.framework */,
8B5A9E1F0E71CB6C005DA441 /* AddressBook.framework */,
8BC04D470DB0088500C2D1CA /* libz.dylib */,
@@ -774,6 +783,7 @@
8B5547C70DB3BBF20014CC1C /* GTMUIKit+UnitTesting.m */,
8B5547C80DB3BBF20014CC1C /* GTMUIKit+UnitTesting.h */,
8B5547C90DB3BBF20014CC1C /* GTMUIKit+UnitTestingTest.m */,
+ 234E17DB152CECFB00CF3542 /* GTMIPhoneSecurityLibraryTest.m */,
67A7820A0E00927400EBF506 /* GTMIPhoneUnitTestDelegate.h */,
67A7820B0E00927400EBF506 /* GTMIPhoneUnitTestDelegate.m */,
8BC047DD0DAE928A00C2D1CA /* GTMIPhoneUnitTestMain.m */,
@@ -1036,7 +1046,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "# Nuke coverage data earch run\nexport GTM_REMOVE_GCOV_DATA=1\n# Run the unit tests in this test bundle.\n\"${SRCROOT}/UnitTesting/RunIPhoneUnitTest.sh\"\n";
+ shellScript = "# Nuke coverage data earch run\nexport GTM_REMOVE_GCOV_DATA=1\n\n# Enable launch daemons for security tests.\nexport GTM_DISABLE_IPHONE_LAUNCH_DAEMONS=0\n\n# Run the unit tests in this test bundle.\n${SRCROOT}/UnitTesting/RunIPhoneUnitTest.sh\n";
};
F4D20EA814852BFB0001600C /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@@ -1087,6 +1097,7 @@
8B7DCEAD0DFF4CA60017E983 /* GTMUnitTestDevLog.m in Sources */,
67A7820C0E00927400EBF506 /* GTMIPhoneUnitTestDelegate.m in Sources */,
8B3AA8F30E032FC7007E31B5 /* GTMNSString+URLArguments.m in Sources */,
+ F4746721129703600022C1FB /* GTMSenTestCaseTest.m in Sources */,
8B3AA8F40E032FC7007E31B5 /* GTMNSString+URLArgumentsTest.m in Sources */,
8B41EC0F0E0711D40040CF9F /* GTMValidatingContainersTest.m in Sources */,
8B41EC100E0711D40040CF9F /* GTMValidatingContainers.m in Sources */,
@@ -1131,7 +1142,6 @@
8BFFCD7811C1934900E45777 /* GTMNSObject+KeyValueObservingTest.m in Sources */,
8B2908B211F8E7070064F50F /* GTMNSFileHandle+UniqueName.m in Sources */,
8B2908B311F8E7070064F50F /* GTMNSFileHandle+UniqueNameTest.m in Sources */,
- F4746721129703600022C1FB /* GTMSenTestCaseTest.m in Sources */,
9340CF9F140550CE0026DDC9 /* GTMFadeTruncatingLabel.m in Sources */,
9340CFA0140550CE0026DDC9 /* GTMFadeTruncatingLabelTest.m in Sources */,
169E1E2F1459AAE100E6F562 /* GTMUILocalizer.m in Sources */,
@@ -1141,6 +1151,7 @@
8B6FF394151A664600B0642B /* GTMNSThread+Blocks.m in Sources */,
8B6FF396151A664600B0642B /* GTMNSThread+BlocksTest.m in Sources */,
8B6FF39A151A670100B0642B /* GTMFoundationUnitTestingUtilities.m in Sources */,
+ 234E17DC152CECFB00CF3542 /* GTMIPhoneSecurityLibraryTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1229,6 +1240,7 @@
8B6FF395151A664600B0642B /* GTMNSThread+Blocks.m in Sources */,
8B6FF397151A664600B0642B /* GTMNSThread+BlocksTest.m in Sources */,
8B6FF39B151A670100B0642B /* GTMFoundationUnitTestingUtilities.m in Sources */,
+ 234E17DD152CECFB00CF3542 /* GTMIPhoneSecurityLibraryTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/UnitTesting/GTMIPhoneSecurityLibraryTest.m b/UnitTesting/GTMIPhoneSecurityLibraryTest.m
new file mode 100644
index 0000000..951ca98
--- /dev/null
+++ b/UnitTesting/GTMIPhoneSecurityLibraryTest.m
@@ -0,0 +1,75 @@
+//
+// GTMIPhoneSecurityLibraryTest.m
+//
+// Copyright 2012 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 "GTMSenTestCase.h"
+
+// Tests that using the keychain library within unit tests works correctly.
+@interface GTMIPhoneSecurityLibraryTest : GTMTestCase
+@end
+
+@implementation GTMIPhoneSecurityLibraryTest
+
+static NSString * const kAccount = @"GTMTestingSecurityAccount";
+static NSString * const kService = @"GTMTestingSecurityService";
+static NSString * const kPassword = @"GTMTestingSecurityPassword";
+
+- (NSMutableDictionary *)keychainQueryItem {
+ return [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ (id)kSecClassGenericPassword, (id)kSecClass,
+ kAccount, (id)kSecAttrAccount,
+ kService, (id)kSecAttrService,
+ nil];
+}
+
+- (void)assertCorrectPassword {
+ NSMutableDictionary *keychainQueryItem = [self keychainQueryItem];
+ [keychainQueryItem setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
+ [keychainQueryItem setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
+
+ CFDataRef result = NULL;
+ OSStatus status = SecItemCopyMatching((CFDictionaryRef)keychainQueryItem,
+ (CFTypeRef *)&result);
+ STAssertEquals(status,
+ (OSStatus)noErr,
+ @"Error retrieving password from keychain");
+ STAssertNotNULL(result, @"No password found");
+ NSString *password =
+ [[[NSString alloc] initWithData:(NSData *)result
+ encoding:NSUTF8StringEncoding] autorelease];
+ STAssertEqualStrings(kPassword, password, @"Unexpected password found");
+ CFRelease(result);
+}
+
+- (void)testSecurityCalls {
+ NSMutableDictionary *passwordItem = [self keychainQueryItem];
+ NSData *passwordData = [kPassword dataUsingEncoding:NSUTF8StringEncoding];
+ [passwordItem setObject:passwordData forKey:(id)kSecValueData];
+
+ OSStatus result = SecItemAdd((CFDictionaryRef)passwordItem, NULL);
+ STAssertTrue(result == noErr || result == errSecDuplicateItem,
+ @"Unexpected result code: %d",
+ result);
+ [self assertCorrectPassword];
+
+ // Test that accessing the keychain will continue to work after a delay.
+ NSDate *sleepUntil = [NSDate dateWithTimeIntervalSinceNow:30];
+ [[NSRunLoop mainRunLoop] runUntilDate:sleepUntil];
+ [self assertCorrectPassword];
+}
+
+@end
diff --git a/UnitTesting/RunIPhoneLaunchDaemons.sh b/UnitTesting/RunIPhoneLaunchDaemons.sh
deleted file mode 100755
index da230ac..0000000
--- a/UnitTesting/RunIPhoneLaunchDaemons.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash
-# RunIPhoneLaunchDaemons.sh
-# Copyright 2010 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.
-#
-# Runs all unittests through the iPhone simulator. We don't handle running them
-# on the device. To run on the device just choose "run".
-
-# Starts up securityd for us so that we can access the keychain from our tests.
-# Turns out that when you run the simulator without the UI front end, that
-# some iPhone launch daemons aren't started correctly.
-# This script starts up securityd for us.
-# We may need to startup other services in the future.
-# This script is launched by launchd.
-#
-# arg1 - root to the iPhone SDK being used
-# arg2 - path to the user directory to use
-
-set -o errexit
-set -o nounset
-# Uncomment the next line to trace execution.
-#set -o verbose
-
-# These both need to be set to the root of the iPhone SDK for iPhone
-# apps to be able to find their frameworks.
-export DYLD_ROOT_PATH="$1"
-export IPHONE_SIMULATOR_ROOT="$1"
-
-# This needs to be set to the user's directory to find preference files.
-export CFFIXED_USER_HOME="$2"
-
-"$IPHONE_SIMULATOR_ROOT/usr/libexec/securityd"
diff --git a/UnitTesting/RunIPhoneUnitTest.sh b/UnitTesting/RunIPhoneUnitTest.sh
index 7721fcd..ce3f2dc 100755
--- a/UnitTesting/RunIPhoneUnitTest.sh
+++ b/UnitTesting/RunIPhoneUnitTest.sh
@@ -74,6 +74,26 @@ GTMXcodeNote() {
echo ${ThisScript}:${1}: note: GTM ${2}
}
+# Creates a file containing the plist for the securityd daemon and prints the
+# filename to stdout.
+GTMCreateLaunchDaemonPlist() {
+ local plist_file
+ plist_file="$TMPDIR/securityd.$$.plist"
+ echo $plist_file
+
+ # Create the plist file with PlistBuddy.
+ /usr/libexec/PlistBuddy \
+ -c "Add :Label string RunIPhoneLaunchDaemons" \
+ -c "Add :ProgramArguments array" \
+ -c "Add :ProgramArguments: string \"$IPHONE_SIMULATOR_ROOT/usr/libexec/securityd\"" \
+ -c "Add :EnvironmentVariables dict" \
+ -c "Add :EnvironmentVariables:DYLD_ROOT_PATH string \"$IPHONE_SIMULATOR_ROOT\"" \
+ -c "Add :EnvironmentVariables:IPHONE_SIMULATOR_ROOT string \"$IPHONE_SIMULATOR_ROOT\"" \
+ -c "Add :EnvironmentVariables:CFFIXED_USER_HOME string \"$CFFIXED_USER_HOME\"" \
+ -c "Add :MachServices dict" \
+ -c "Add :MachServices:com.apple.securityd bool YES" "$plist_file" > /dev/null
+}
+
if [ "$PLATFORM_NAME" == "iphonesimulator" ]; then
# We kill the iPhone simulator because otherwise we run into issues where
# the unittests fail becuase the simulator is currently running, and
@@ -121,9 +141,13 @@ if [ "$PLATFORM_NAME" == "iphonesimulator" ]; then
# presence as 'launchctl remove' will kill this script if run from within an
# Xcode build.
launchctl list | grep RunIPhoneLaunchDaemons && launchctl remove RunIPhoneLaunchDaemons
+
# If we want to test anything that interacts with the keychain, we need
- # securityd up and running. See RunIPhoneLaunchDaemons.sh for details.
- launchctl submit -l RunIPhoneLaunchDaemons -- "${ScriptDir}/RunIPhoneLaunchDaemons.sh" $IPHONE_SIMULATOR_ROOT $CFFIXED_USER_HOME
+ # securityd up and running.
+ LAUNCH_DAEMON_PLIST="$(GTMCreateLaunchDaemonPlist)"
+ launchctl load $LAUNCH_DAEMON_PLIST
+ rm $LAUNCH_DAEMON_PLIST
+
# No matter how we exit, we want to shut down our launchctl job.
trap "launchctl remove RunIPhoneLaunchDaemons" INT TERM EXIT
fi