| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 | 2 |
| 3 # Copyright (c) 2012 Google Inc. All rights reserved. | 3 # Copyright (c) 2012 Google Inc. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 """ | 7 """ |
| 8 Verifies that device and simulator bundles are built correctly. | 8 Verifies that device and simulator bundles are built correctly. |
| 9 """ | 9 """ |
| 10 | 10 |
| 11 import plistlib | 11 import plistlib |
| 12 import TestGyp | 12 import TestGyp |
| 13 import os | 13 import os |
| 14 import struct | 14 import struct |
| 15 import subprocess | 15 import subprocess |
| 16 import sys | 16 import sys |
| 17 import tempfile | 17 import tempfile |
| 18 | 18 import TestMac |
| 19 if sys.platform == 'darwin': | |
| 20 print "This test is currently disabled: https://crbug.com/483696." | |
| 21 sys.exit(0) | |
| 22 | |
| 23 | 19 |
| 24 def CheckFileType(file, expected): | 20 def CheckFileType(file, expected): |
| 25 proc = subprocess.Popen(['lipo', '-info', file], stdout=subprocess.PIPE) | 21 proc = subprocess.Popen(['lipo', '-info', file], stdout=subprocess.PIPE) |
| 26 o = proc.communicate()[0].strip() | 22 o = proc.communicate()[0].strip() |
| 27 assert not proc.returncode | 23 assert not proc.returncode |
| 28 if not expected in o: | 24 if not expected in o: |
| 29 print 'File: Expected %s, got %s' % (expected, o) | 25 print 'File: Expected %s, got %s' % (expected, o) |
| 30 test.fail_test() | 26 test.fail_test() |
| 31 | 27 |
| 32 def HasCerts(): | 28 def HasCerts(): |
| (...skipping 27 matching lines...) Expand all Loading... |
| 60 test.fail_test() | 56 test.fail_test() |
| 61 | 57 |
| 62 def ParseEntitlements(data): | 58 def ParseEntitlements(data): |
| 63 if len(data) < 8: | 59 if len(data) < 8: |
| 64 return None | 60 return None |
| 65 magic, length = struct.unpack('>II', data[:8]) | 61 magic, length = struct.unpack('>II', data[:8]) |
| 66 if magic != 0xfade7171 or length != len(data): | 62 if magic != 0xfade7171 or length != len(data): |
| 67 return None | 63 return None |
| 68 return data[8:] | 64 return data[8:] |
| 69 | 65 |
| 70 def GetProductVersion(): | 66 def GetXcodeVersionValue(type): |
| 71 args = ['xcodebuild','-version','-sdk','iphoneos','ProductVersion'] | 67 args = ['xcodebuild', '-version', '-sdk', 'iphoneos', type] |
| 72 job = subprocess.Popen(args, stdout=subprocess.PIPE) | 68 job = subprocess.Popen(args, stdout=subprocess.PIPE) |
| 73 return job.communicate()[0].strip() | 69 return job.communicate()[0].strip() |
| 74 | 70 |
| 71 def GetMachineBuild(): |
| 72 args = ['sw_vers', '-buildVersion'] |
| 73 job = subprocess.Popen(args, stdout=subprocess.PIPE) |
| 74 return job.communicate()[0].strip() |
| 75 |
| 75 def CheckPlistvalue(plist, key, expected): | 76 def CheckPlistvalue(plist, key, expected): |
| 76 if key not in plist: | 77 if key not in plist: |
| 77 print '%s not set in plist' % key | 78 print '%s not set in plist' % key |
| 78 test.fail_test() | 79 test.fail_test() |
| 79 return | 80 return |
| 80 actual = plist[key] | 81 actual = plist[key] |
| 81 if actual != expected: | 82 if actual != expected: |
| 82 print 'File: Expected %s, got %s for %s' % (expected, actual, key) | 83 print 'File: Expected %s, got %s for %s' % (expected, actual, key) |
| 83 test.fail_test() | 84 test.fail_test() |
| 84 | 85 |
| 85 def CheckPlistNotSet(plist, key): | 86 def CheckPlistNotSet(plist, key): |
| 86 if key in plist: | 87 if key in plist: |
| 87 print '%s should not be set in plist' % key | 88 print '%s should not be set in plist' % key |
| 88 test.fail_test() | 89 test.fail_test() |
| 89 return | 90 return |
| 90 | 91 |
| 91 def ConvertBinaryPlistToXML(path): | 92 def ConvertBinaryPlistToXML(path): |
| 92 proc = subprocess.call(['plutil', '-convert', 'xml1', path], | 93 proc = subprocess.call(['plutil', '-convert', 'xml1', path], |
| 93 stdout=subprocess.PIPE) | 94 stdout=subprocess.PIPE) |
| 94 | 95 |
| 95 if sys.platform == 'darwin': | 96 if sys.platform == 'darwin': |
| 96 test = TestGyp.TestGyp(formats=['ninja', 'xcode']) | 97 test = TestGyp.TestGyp(formats=['ninja', 'xcode']) |
| 97 | 98 |
| 98 test.run_gyp('test-device.gyp', chdir='app-bundle') | 99 test.run_gyp('test-device.gyp', chdir='app-bundle') |
| 99 | 100 |
| 100 test_configs = ['Default-iphoneos', 'Default'] | 101 test_configs = ['Default-iphoneos', 'Default'] |
| 101 # TODO(justincohen): Disabling 'Default-iphoneos' for xcode until bots are | |
| 102 # configured with signing certs. | |
| 103 if test.format == 'xcode': | |
| 104 test_configs.remove('Default-iphoneos') | |
| 105 | |
| 106 for configuration in test_configs: | 102 for configuration in test_configs: |
| 107 test.set_configuration(configuration) | 103 test.set_configuration(configuration) |
| 108 test.build('test-device.gyp', 'test_app', chdir='app-bundle') | 104 test.build('test-device.gyp', 'test_app', chdir='app-bundle') |
| 109 result_file = test.built_file_path('Test App Gyp.bundle/Test App Gyp', | 105 result_file = test.built_file_path('Test App Gyp.app/Test App Gyp', |
| 110 chdir='app-bundle') | 106 chdir='app-bundle') |
| 111 test.must_exist(result_file) | 107 test.must_exist(result_file) |
| 108 info_plist = test.built_file_path('Test App Gyp.app/Info.plist', |
| 109 chdir='app-bundle') |
| 110 plist = plistlib.readPlist(info_plist) |
| 111 xcode_version = TestMac.Xcode.Version() |
| 112 if xcode_version >= '0720': |
| 113 if len(plist) != 23: |
| 114 print 'plist should have 23 entries, but it has %s' % len(plist) |
| 115 test.fail_test() |
| 112 | 116 |
| 113 info_plist = test.built_file_path('Test App Gyp.bundle/Info.plist', | 117 # Values that will hopefully never change. |
| 114 chdir='app-bundle') | 118 CheckPlistvalue(plist, 'CFBundleDevelopmentRegion', 'English') |
| 115 | 119 CheckPlistvalue(plist, 'CFBundleExecutable', 'Test App Gyp') |
| 116 # plistlib doesn't support binary plists, but that's what Xcode creates. | 120 CheckPlistvalue(plist, 'CFBundleIdentifier', 'com.google.Test App Gyp') |
| 117 if test.format == 'xcode': | 121 CheckPlistvalue(plist, 'CFBundleInfoDictionaryVersion', '6.0') |
| 118 ConvertBinaryPlistToXML(info_plist) | 122 CheckPlistvalue(plist, 'CFBundleName', 'Test App Gyp') |
| 119 plist = plistlib.readPlist(info_plist) | 123 CheckPlistvalue(plist, 'CFBundlePackageType', 'APPL') |
| 120 | 124 CheckPlistvalue(plist, 'CFBundleShortVersionString', '1.0') |
| 125 CheckPlistvalue(plist, 'CFBundleSignature', 'ause') |
| 126 CheckPlistvalue(plist, 'CFBundleVersion', '1') |
| 127 CheckPlistvalue(plist, 'NSMainNibFile', 'MainMenu') |
| 128 CheckPlistvalue(plist, 'NSPrincipalClass', 'NSApplication') |
| 121 CheckPlistvalue(plist, 'UIDeviceFamily', [1, 2]) | 129 CheckPlistvalue(plist, 'UIDeviceFamily', [1, 2]) |
| 122 | 130 |
| 131 # Values that get pulled from xcodebuild. |
| 132 machine_build = GetMachineBuild() |
| 133 platform_version = GetXcodeVersionValue('ProductVersion') |
| 134 sdk_build = GetXcodeVersionValue('ProductBuildVersion') |
| 135 xcode_build = TestMac.Xcode.Build() |
| 136 |
| 137 # Xcode keeps changing what gets included in executable plists, and it |
| 138 # changes between device and simuator builds. Allow the strictest tests for |
| 139 # Xcode 7.2 and above. |
| 140 if xcode_version >= '0720': |
| 141 CheckPlistvalue(plist, 'BuildMachineOSBuild', machine_build) |
| 142 CheckPlistvalue(plist, 'DTCompiler', 'com.apple.compilers.llvm.clang.1_0') |
| 143 CheckPlistvalue(plist, 'DTPlatformVersion', platform_version) |
| 144 CheckPlistvalue(plist, 'DTSDKBuild', sdk_build) |
| 145 CheckPlistvalue(plist, 'DTXcode', xcode_version) |
| 146 CheckPlistvalue(plist, 'DTXcodeBuild', xcode_build) |
| 147 CheckPlistvalue(plist, 'MinimumOSVersion', '8.0') |
| 148 |
| 149 |
| 123 if configuration == 'Default-iphoneos': | 150 if configuration == 'Default-iphoneos': |
| 151 platform_name = 'iphoneos' |
| 124 CheckFileType(result_file, 'armv7') | 152 CheckFileType(result_file, 'armv7') |
| 125 CheckPlistvalue(plist, 'DTPlatformVersion', GetProductVersion()) | |
| 126 CheckPlistvalue(plist, 'CFBundleSupportedPlatforms', ['iPhoneOS']) | 153 CheckPlistvalue(plist, 'CFBundleSupportedPlatforms', ['iPhoneOS']) |
| 127 CheckPlistvalue(plist, 'DTPlatformName', 'iphoneos') | 154 # Apple keeps changing their mind. |
| 155 if xcode_version >= '0720': |
| 156 CheckPlistvalue(plist, 'DTPlatformBuild', sdk_build) |
| 128 else: | 157 else: |
| 158 platform_name = 'iphonesimulator' |
| 129 CheckFileType(result_file, 'i386') | 159 CheckFileType(result_file, 'i386') |
| 130 CheckPlistNotSet(plist, 'DTPlatformVersion') | |
| 131 CheckPlistvalue(plist, 'CFBundleSupportedPlatforms', ['iPhoneSimulator']) | 160 CheckPlistvalue(plist, 'CFBundleSupportedPlatforms', ['iPhoneSimulator']) |
| 132 CheckPlistvalue(plist, 'DTPlatformName', 'iphonesimulator') | 161 if xcode_version >= '0720': |
| 162 CheckPlistvalue(plist, 'DTPlatformBuild', '') |
| 163 |
| 164 CheckPlistvalue(plist, 'DTPlatformName', platform_name) |
| 165 CheckPlistvalue(plist, 'DTSDKName', platform_name + platform_version) |
| 166 |
| 133 | 167 |
| 134 if HasCerts() and configuration == 'Default-iphoneos': | 168 if HasCerts() and configuration == 'Default-iphoneos': |
| 135 test.build('test-device.gyp', 'sig_test', chdir='app-bundle') | 169 test.build('test-device.gyp', 'sig_test', chdir='app-bundle') |
| 136 result_file = test.built_file_path('sig_test.bundle/sig_test', | 170 result_file = test.built_file_path('sigtest.app/sigtest', |
| 137 chdir='app-bundle') | 171 chdir='app-bundle') |
| 138 CheckSignature(result_file) | 172 CheckSignature(result_file) |
| 139 info_plist = test.built_file_path('sig_test.bundle/Info.plist', | 173 info_plist = test.built_file_path('sigtest.app/Info.plist', |
| 140 chdir='app-bundle') | 174 chdir='app-bundle') |
| 141 | 175 |
| 142 plist = plistlib.readPlist(info_plist) | 176 plist = plistlib.readPlist(info_plist) |
| 143 CheckPlistvalue(plist, 'UIDeviceFamily', [1]) | 177 CheckPlistvalue(plist, 'UIDeviceFamily', [1]) |
| 144 | 178 |
| 145 entitlements_file = test.built_file_path('sig_test.xcent', | 179 entitlements_file = test.built_file_path('sig_test.xcent', |
| 146 chdir='app-bundle') | 180 chdir='app-bundle') |
| 147 if os.path.isfile(entitlements_file): | 181 if os.path.isfile(entitlements_file): |
| 148 expected_entitlements = open(entitlements_file).read() | 182 expected_entitlements = open(entitlements_file).read() |
| 149 CheckEntitlements(result_file, expected_entitlements) | 183 CheckEntitlements(result_file, expected_entitlements) |
| 150 | 184 |
| 151 test.pass_test() | 185 test.pass_test() |
| OLD | NEW |