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         mac_ver_tuple = tuple(int(i) for i in
    113                             platform.mac_ver()[0].split('.')[0:2])
    114         self.assertEqual(mac_ver_tuple >= (10, 4),
    115                             _osx_support._supports_universal_builds())
    116 
    117     def test__find_appropriate_compiler(self):
    118         compilers = (
    119                         ('gcc-test', 'i686-apple-darwin11-llvm-gcc-4.2'),
    120                         ('clang', 'clang version 3.1'),
    121                     )
    122         config_vars = {
    123         'CC': 'gcc-test -pthreads',
    124         'CXX': 'cc++-test',
    125         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
    126         'LDFLAGS': '-arch ppc -arch i386   -g',
    127         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    128         'BLDSHARED': 'gcc-test -bundle -arch ppc -arch i386 -g',
    129         'LDSHARED': 'gcc-test -bundle -arch ppc -arch i386 '
    130                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    131         }
    132         expected_vars = {
    133         'CC': 'clang -pthreads',
    134         'CXX': 'clang++',
    135         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
    136         'LDFLAGS': '-arch ppc -arch i386   -g',
    137         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    138         'BLDSHARED': 'clang -bundle -arch ppc -arch i386 -g',
    139         'LDSHARED': 'clang -bundle -arch ppc -arch i386 '
    140                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    141         }
    142         self.add_expected_saved_initial_values(config_vars, expected_vars)
    143 
    144         suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
    145         self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
    146         for c_name, c_output in compilers:
    147             test.test_support.unlink(c_name)
    148             self.addCleanup(test.test_support.unlink, c_name)
    149             with open(c_name, 'w') as f:
    150                 f.write("#!/bin/sh\n/bin/echo " + c_output)
    151             os.chmod(c_name, stat.S_IRWXU)
    152         self.assertEqual(expected_vars,
    153                             _osx_support._find_appropriate_compiler(
    154                                     config_vars))
    155 
    156     def test__remove_universal_flags(self):
    157         config_vars = {
    158         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
    159         'LDFLAGS': '-arch ppc -arch i386   -g',
    160         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    161         'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
    162         'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
    163                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    164         }
    165         expected_vars = {
    166         'CFLAGS': '-fno-strict-aliasing  -g -O3    ',
    167         'LDFLAGS': '    -g',
    168         'CPPFLAGS': '-I.  ',
    169         'BLDSHARED': 'gcc-4.0 -bundle    -g',
    170         'LDSHARED': 'gcc-4.0 -bundle      -g',
    171         }
    172         self.add_expected_saved_initial_values(config_vars, expected_vars)
    173 
    174         self.assertEqual(expected_vars,
    175                             _osx_support._remove_universal_flags(
    176                                     config_vars))
    177 
    178     def test__remove_unsupported_archs(self):
    179         config_vars = {
    180         'CC': 'clang',
    181         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
    182         'LDFLAGS': '-arch ppc -arch i386   -g',
    183         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    184         'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
    185         'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
    186                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    187         }
    188         expected_vars = {
    189         'CC': 'clang',
    190         'CFLAGS': '-fno-strict-aliasing  -g -O3  -arch i386  ',
    191         'LDFLAGS': ' -arch i386   -g',
    192         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    193         'BLDSHARED': 'gcc-4.0 -bundle   -arch i386 -g',
    194         'LDSHARED': 'gcc-4.0 -bundle   -arch i386 '
    195                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    196         }
    197         self.add_expected_saved_initial_values(config_vars, expected_vars)
    198 
    199         suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
    200         self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
    201         c_name = 'clang'
    202         test.test_support.unlink(c_name)
    203         self.addCleanup(test.test_support.unlink, c_name)
    204         # exit status 255 means no PPC support in this compiler chain
    205         with open(c_name, 'w') as f:
    206             f.write("#!/bin/sh\nexit 255")
    207         os.chmod(c_name, stat.S_IRWXU)
    208         self.assertEqual(expected_vars,
    209                             _osx_support._remove_unsupported_archs(
    210                                     config_vars))
    211 
    212     def test__override_all_archs(self):
    213         self.env['ARCHFLAGS'] = '-arch x86_64'
    214         config_vars = {
    215         'CC': 'clang',
    216         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  ',
    217         'LDFLAGS': '-arch ppc -arch i386   -g',
    218         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    219         'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
    220         'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
    221                         '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
    222         }
    223         expected_vars = {
    224         'CC': 'clang',
    225         'CFLAGS': '-fno-strict-aliasing  -g -O3     -arch x86_64',
    226         'LDFLAGS': '    -g -arch x86_64',
    227         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
    228         'BLDSHARED': 'gcc-4.0 -bundle    -g -arch x86_64',
    229         'LDSHARED': 'gcc-4.0 -bundle   -isysroot '
    230                         '/Developer/SDKs/MacOSX10.4u.sdk -g -arch x86_64',
    231         }
    232         self.add_expected_saved_initial_values(config_vars, expected_vars)
    233 
    234         self.assertEqual(expected_vars,
    235                             _osx_support._override_all_archs(
    236                                     config_vars))
    237 
    238     def test__check_for_unavailable_sdk(self):
    239         config_vars = {
    240         'CC': 'clang',
    241         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  '
    242                         '-isysroot /Developer/SDKs/MacOSX10.1.sdk',
    243         'LDFLAGS': '-arch ppc -arch i386   -g',
    244         'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.1.sdk',
    245         'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
    246         'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
    247                         '-isysroot /Developer/SDKs/MacOSX10.1.sdk -g',
    248         }
    249         expected_vars = {
    250         'CC': 'clang',
    251         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  '
    252                         ' ',
    253         'LDFLAGS': '-arch ppc -arch i386   -g',
    254         'CPPFLAGS': '-I.  ',
    255         'BLDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 -g',
    256         'LDSHARED': 'gcc-4.0 -bundle  -arch ppc -arch i386 '
    257                         ' -g',
    258         }
    259         self.add_expected_saved_initial_values(config_vars, expected_vars)
    260 
    261         self.assertEqual(expected_vars,
    262                             _osx_support._check_for_unavailable_sdk(
    263                                     config_vars))
    264 
    265     def test_get_platform_osx(self):
    266         # Note, get_platform_osx is currently tested more extensively
    267         # indirectly by test_sysconfig and test_distutils
    268         config_vars = {
    269         'CFLAGS': '-fno-strict-aliasing  -g -O3 -arch ppc -arch i386  '
    270                         '-isysroot /Developer/SDKs/MacOSX10.1.sdk',
    271         'MACOSX_DEPLOYMENT_TARGET': '10.6',
    272         }
    273         result = _osx_support.get_platform_osx(config_vars, ' ', ' ', ' ')
    274         self.assertEqual(('macosx', '10.6', 'fat'), result)
    275 
    276 def test_main():
    277     if sys.platform == 'darwin':
    278         test.test_support.run_unittest(Test_OSXSupport)
    279 
    280 if __name__ == "__main__":
    281     test_main()
    282