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