Home | History | Annotate | Download | only in test
      1 """
      2 Test suite for _osx_support: shared OS X support functions.
      3 """
      4 
      5 import os
      6 import platform
      7 import shutil
      8 import stat
      9 import sys
     10 import unittest
     11 
     12 import test.test_support
     13 
     14 import _osx_support
     15 
     16 @unittest.skipUnless(sys.platform.startswith("darwin"), "requires OS X")
     17 class Test_OSXSupport(unittest.TestCase):
     18 
     19     def setUp(self):
     20         self.maxDiff = None
     21         self.prog_name = 'bogus_program_xxxx'
     22         self.temp_path_dir = os.path.abspath(os.getcwd())
     23         self.env = test.test_support.EnvironmentVarGuard()
     24         self.addCleanup(self.env.__exit__)
     25         for cv in ('CFLAGS', 'LDFLAGS', 'CPPFLAGS',
     26                             'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC',
     27                             'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
     28                             'PY_CORE_CFLAGS'):
     29             if cv in self.env:
     30                 self.env.unset(cv)
     31 
     32     def add_expected_saved_initial_values(self, config_vars, expected_vars):
     33         # Ensure that the initial values for all modified config vars
     34         # are also saved with modified keys.
     35         expected_vars.update(('_OSX_SUPPORT_INITIAL_'+ k,
     36                 config_vars[k]) for k in config_vars
     37                     if config_vars[k] != expected_vars[k])
     38 
     39     def test__find_executable(self):
     40         if self.env['PATH']:
     41             self.env['PATH'] = self.env['PATH'] + ':'
     42         self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
     43         test.test_support.unlink(self.prog_name)
     44         self.assertIsNone(_osx_support._find_executable(self.prog_name))
     45         self.addCleanup(test.test_support.unlink, self.prog_name)
     46         with open(self.prog_name, 'w') as f:
     47             f.write("#!/bin/sh\n/bin/echo OK\n")
     48         os.chmod(self.prog_name, stat.S_IRWXU)
     49         self.assertEqual(self.prog_name,
     50                             _osx_support._find_executable(self.prog_name))
     51 
     52     def test__read_output(self):
     53         if self.env['PATH']:
     54             self.env['PATH'] = self.env['PATH'] + ':'
     55         self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
     56         test.test_support.unlink(self.prog_name)
     57         self.addCleanup(test.test_support.unlink, self.prog_name)
     58         with open(self.prog_name, 'w') as f:
     59             f.write("#!/bin/sh\n/bin/echo ExpectedOutput\n")
     60         os.chmod(self.prog_name, stat.S_IRWXU)
     61         self.assertEqual('ExpectedOutput',
     62                             _osx_support._read_output(self.prog_name))
     63 
     64     def test__find_build_tool(self):
     65         out = _osx_support._find_build_tool('cc')
     66         self.assertTrue(os.path.isfile(out),
     67                             'cc not found - check xcode-select')
     68 
     69     def test__get_system_version(self):
     70         self.assertTrue(platform.mac_ver()[0].startswith(
     71                                     _osx_support._get_system_version()))
     72 
     73     def test__remove_original_values(self):
     74         config_vars = {
     75         'CC': 'gcc-test -pthreads',
     76         }
     77         expected_vars = {
     78         'CC': 'clang -pthreads',
     79         }
     80         cv = 'CC'
     81         newvalue = 'clang -pthreads'
     82         _osx_support._save_modified_value(config_vars, cv, newvalue)
     83         self.assertNotEqual(expected_vars, config_vars)
     84         _osx_support._remove_original_values(config_vars)
     85         self.assertEqual(expected_vars, config_vars)
     86 
     87     def test__save_modified_value(self):
     88         config_vars = {
     89         'CC': 'gcc-test -pthreads',
     90         }
     91         expected_vars = {
     92         'CC': 'clang -pthreads',
     93         }
     94         self.add_expected_saved_initial_values(config_vars, expected_vars)
     95         cv = 'CC'
     96         newvalue = 'clang -pthreads'
     97         _osx_support._save_modified_value(config_vars, cv, newvalue)
     98         self.assertEqual(expected_vars, config_vars)
     99 
    100     def test__save_modified_value_unchanged(self):
    101         config_vars = {
    102         'CC': 'gcc-test -pthreads',
    103         }
    104         expected_vars = config_vars.copy()
    105         cv = 'CC'
    106         newvalue = 'gcc-test -pthreads'
    107         _osx_support._save_modified_value(config_vars, cv, newvalue)
    108         self.assertEqual(expected_vars, config_vars)
    109 
    110     def test__supports_universal_builds(self):
    111         import platform
    112         self.assertEqual(platform.mac_ver()[0].split('.') >= ['10', '4'],
    113                             _osx_support._supports_universal_builds())
    114 
    115     def test__find_appropriate_compiler(self):
    116         compilers = (
    117                         ('gcc-test', 'i686-apple-darwin11-llvm-gcc-4.2'),
    118                         ('clang', 'clang version 3.1'),
    119                     )
    120         config_vars = {
    121         'CC': 'gcc-test -pthreads',
    122         'CXX': 'cc++-test',
    123         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
    124         'LDFLAGS': '-arch ppc -arch i386   -g',
    125         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    126         'BLDSHARED': 'gcc-test -bundle -arch ppc -arch i386 -g',
    127         'LDSHARED': 'gcc-test -bundle -arch ppc -arch i386 '
    128                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    129         }
    130         expected_vars = {
    131         'CC': 'clang -pthreads',
    132         'CXX': 'clang++',
    133         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
    134         'LDFLAGS': '-arch ppc -arch i386   -g',
    135         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    136         'BLDSHARED': 'clang -bundle -arch ppc -arch i386 -g',
    137         'LDSHARED': 'clang -bundle -arch ppc -arch i386 '
    138                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    139         }
    140         self.add_expected_saved_initial_values(config_vars, expected_vars)
    141 
    142         suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
    143         self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
    144         for c_name, c_output in compilers:
    145             test.test_support.unlink(c_name)
    146             self.addCleanup(test.test_support.unlink, c_name)
    147             with open(c_name, 'w') as f:
    148                 f.write("#!/bin/sh\n/bin/echo " + c_output)
    149             os.chmod(c_name, stat.S_IRWXU)
    150         self.assertEqual(expected_vars,
    151                             _osx_support._find_appropriate_compiler(
    152                                     config_vars))
    153 
    154     def test__remove_universal_flags(self):
    155         config_vars = {
    156         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
    157         'LDFLAGS': '-arch ppc -arch i386   -g',
    158         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    159         'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
    160         'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
    161                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    162         }
    163         expected_vars = {
    164         'CFLAGS': '-fno-strict-aliasing  -g -O3    ',
    165         'LDFLAGS': '    -g',
    166         'CPPFLAGS': '-I.  ',
    167         'BLDSHARED': 'gcc-4.0 -bundle    -g',
    168         'LDSHARED': 'gcc-4.0 -bundle      -g',
    169         }
    170         self.add_expected_saved_initial_values(config_vars, expected_vars)
    171 
    172         self.assertEqual(expected_vars,
    173                             _osx_support._remove_universal_flags(
    174                                     config_vars))
    175 
    176     def test__remove_unsupported_archs(self):
    177         config_vars = {
    178         'CC': 'clang',
    179         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
    180         'LDFLAGS': '-arch ppc -arch i386   -g',
    181         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    182         'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
    183         'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
    184                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    185         }
    186         expected_vars = {
    187         'CC': 'clang',
    188         'CFLAGS': '-fno-strict-aliasing  -g -O3  -arch i386  ',
    189         'LDFLAGS': ' -arch i386   -g',
    190         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    191         'BLDSHARED': 'gcc-4.0 -bundle   -arch i386 -g',
    192         'LDSHARED': 'gcc-4.0 -bundle   -arch i386 '
    193                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    194         }
    195         self.add_expected_saved_initial_values(config_vars, expected_vars)
    196 
    197         suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
    198         self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
    199         c_name = 'clang'
    200         test.test_support.unlink(c_name)
    201         self.addCleanup(test.test_support.unlink, c_name)
    202         # exit status 255 means no PPC support in this compiler chain
    203         with open(c_name, 'w') as f:
    204             f.write("#!/bin/sh\nexit 255")
    205         os.chmod(c_name, stat.S_IRWXU)
    206         self.assertEqual(expected_vars,
    207                             _osx_support._remove_unsupported_archs(
    208                                     config_vars))
    209 
    210     def test__override_all_archs(self):
    211         self.env['ARCHFLAGS'] = '-arch x86_64'
    212         config_vars = {
    213         'CC': 'clang',
    214         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
    215         'LDFLAGS': '-arch ppc -arch i386   -g',
    216         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    217         'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
    218         'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
    219                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    220         }
    221         expected_vars = {
    222         'CC': 'clang',
    223         'CFLAGS': '-fno-strict-aliasing  -g -O3     -arch x86_64',
    224         'LDFLAGS': '    -g -arch x86_64',
    225         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    226         'BLDSHARED': 'gcc-4.0 -bundle    -g -arch x86_64',
    227         'LDSHARED': 'gcc-4.0 -bundle   -isysroot '
    228                         '/Developer/SDKs/MacOSX10.4u.sdk -g -arch x86_64',
    229         }
    230         self.add_expected_saved_initial_values(config_vars, expected_vars)
    231 
    232         self.assertEqual(expected_vars,
    233                             _osx_support._override_all_archs(
    234                                     config_vars))
    235 
    236     def test__check_for_unavailable_sdk(self):
    237         config_vars = {
    238         'CC': 'clang',
    239         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  '
    240                         '-isysroot /Developer/SDKs/MacOSX10.1.sdk',
    241         'LDFLAGS': '-arch ppc -arch i386   -g',
    242         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.1.sdk',
    243         'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
    244         'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
    245                         '-isysroot /Developer/SDKs/MacOSX10.1.sdk -g',
    246         }
    247         expected_vars = {
    248         'CC': 'clang',
    249         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  '
    250                         ' ',
    251         'LDFLAGS': '-arch ppc -arch i386   -g',
    252         'CPPFLAGS': '-I.  ',
    253         'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
    254         'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
    255                         ' -g',
    256         }
    257         self.add_expected_saved_initial_values(config_vars, expected_vars)
    258 
    259         self.assertEqual(expected_vars,
    260                             _osx_support._check_for_unavailable_sdk(
    261                                     config_vars))
    262 
    263     def test_get_platform_osx(self):
    264         # Note, get_platform_osx is currently tested more extensively
    265         # indirectly by test_sysconfig and test_distutils
    266         config_vars = {
    267         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  '
    268                         '-isysroot /Developer/SDKs/MacOSX10.1.sdk',
    269         'MACOSX_DEPLOYMENT_TARGET': '10.6',
    270         }
    271         result = _osx_support.get_platform_osx(config_vars, ' ', ' ', ' ')
    272         self.assertEqual(('macosx', '10.6', 'fat'), result)
    273 
    274 def test_main():
    275     if sys.platform == 'darwin':
    276         test.test_support.run_unittest(Test_OSXSupport)
    277 
    278 if __name__ == "__main__":
    279     test_main()
    280