Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[Author: jonwall]

Change RunIPhoneUnitTest.sh to launch securityd directly.

This fixes a bug where keychain library functions called from unit tests
would fail after a period of inactivity. We will now launch the security
daemon via launchctl load with a custom plist configuration, rather than
via RunIPhoneLaunchDaemons.sh.

R=dmaclach,thomasvl
APPROVED=thomasvl
DELTA=159  (112 added, 44 deleted, 3 changed)

git-svn-id: http://google-toolbox-for-mac.googlecode.com/svn/trunk@529 7dc7ac4e-7543-0410-b95c-c1676fc8e2a3
  • Loading branch information...
commit 57d658fae021f644ea134134bf1a978ea34ac3db 1 parent 73b4925
gtm.daemon authored
View
16 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;
};
View
75 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
View
43 UnitTesting/RunIPhoneLaunchDaemons.sh
@@ -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"
View
28 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
Please sign in to comment.
Something went wrong with that request. Please try again.