1"""Tests for distutils.util.""" 2import os 3import sys 4import unittest 5from copy import copy 6from test.support import run_unittest 7from unittest import mock 8 9from distutils.errors import DistutilsPlatformError, DistutilsByteCompileError 10from distutils.util import (get_platform, convert_path, change_root, 11 check_environ, split_quoted, strtobool, 12 rfc822_escape, byte_compile, 13 grok_environment_error) 14from distutils import util # used to patch _environ_checked 15from distutils.sysconfig import get_config_vars 16from distutils import sysconfig 17from distutils.tests import support 18import _osx_support 19 20class UtilTestCase(support.EnvironGuard, unittest.TestCase): 21 22 def setUp(self): 23 super(UtilTestCase, self).setUp() 24 # saving the environment 25 self.name = os.name 26 self.platform = sys.platform 27 self.version = sys.version 28 self.sep = os.sep 29 self.join = os.path.join 30 self.isabs = os.path.isabs 31 self.splitdrive = os.path.splitdrive 32 self._config_vars = copy(sysconfig._config_vars) 33 34 # patching os.uname 35 if hasattr(os, 'uname'): 36 self.uname = os.uname 37 self._uname = os.uname() 38 else: 39 self.uname = None 40 self._uname = None 41 42 os.uname = self._get_uname 43 44 def tearDown(self): 45 # getting back the environment 46 os.name = self.name 47 sys.platform = self.platform 48 sys.version = self.version 49 os.sep = self.sep 50 os.path.join = self.join 51 os.path.isabs = self.isabs 52 os.path.splitdrive = self.splitdrive 53 if self.uname is not None: 54 os.uname = self.uname 55 else: 56 del os.uname 57 sysconfig._config_vars.clear() 58 sysconfig._config_vars.update(self._config_vars) 59 super(UtilTestCase, self).tearDown() 60 61 def _set_uname(self, uname): 62 self._uname = uname 63 64 def _get_uname(self): 65 return self._uname 66 67 def test_get_platform(self): 68 69 # windows XP, 32bits 70 os.name = 'nt' 71 sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' 72 '[MSC v.1310 32 bit (Intel)]') 73 sys.platform = 'win32' 74 self.assertEqual(get_platform(), 'win32') 75 76 # windows XP, amd64 77 os.name = 'nt' 78 sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' 79 '[MSC v.1310 32 bit (Amd64)]') 80 sys.platform = 'win32' 81 self.assertEqual(get_platform(), 'win-amd64') 82 83 # macbook 84 os.name = 'posix' 85 sys.version = ('2.5 (r25:51918, Sep 19 2006, 08:49:13) ' 86 '\n[GCC 4.0.1 (Apple Computer, Inc. build 5341)]') 87 sys.platform = 'darwin' 88 self._set_uname(('Darwin', 'macziade', '8.11.1', 89 ('Darwin Kernel Version 8.11.1: ' 90 'Wed Oct 10 18:23:28 PDT 2007; ' 91 'root:xnu-792.25.20~1/RELEASE_I386'), 'i386')) 92 _osx_support._remove_original_values(get_config_vars()) 93 get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3' 94 95 get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' 96 '-fwrapv -O3 -Wall -Wstrict-prototypes') 97 98 cursize = sys.maxsize 99 sys.maxsize = (2 ** 31)-1 100 try: 101 self.assertEqual(get_platform(), 'macosx-10.3-i386') 102 finally: 103 sys.maxsize = cursize 104 105 # macbook with fat binaries (fat, universal or fat64) 106 _osx_support._remove_original_values(get_config_vars()) 107 get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.4' 108 get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot ' 109 '/Developer/SDKs/MacOSX10.4u.sdk ' 110 '-fno-strict-aliasing -fno-common ' 111 '-dynamic -DNDEBUG -g -O3') 112 113 self.assertEqual(get_platform(), 'macosx-10.4-fat') 114 115 _osx_support._remove_original_values(get_config_vars()) 116 os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.1' 117 self.assertEqual(get_platform(), 'macosx-10.4-fat') 118 119 120 _osx_support._remove_original_values(get_config_vars()) 121 get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot ' 122 '/Developer/SDKs/MacOSX10.4u.sdk ' 123 '-fno-strict-aliasing -fno-common ' 124 '-dynamic -DNDEBUG -g -O3') 125 126 self.assertEqual(get_platform(), 'macosx-10.4-intel') 127 128 _osx_support._remove_original_values(get_config_vars()) 129 get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc -arch i386 -isysroot ' 130 '/Developer/SDKs/MacOSX10.4u.sdk ' 131 '-fno-strict-aliasing -fno-common ' 132 '-dynamic -DNDEBUG -g -O3') 133 self.assertEqual(get_platform(), 'macosx-10.4-fat3') 134 135 _osx_support._remove_original_values(get_config_vars()) 136 get_config_vars()['CFLAGS'] = ('-arch ppc64 -arch x86_64 -arch ppc -arch i386 -isysroot ' 137 '/Developer/SDKs/MacOSX10.4u.sdk ' 138 '-fno-strict-aliasing -fno-common ' 139 '-dynamic -DNDEBUG -g -O3') 140 self.assertEqual(get_platform(), 'macosx-10.4-universal') 141 142 _osx_support._remove_original_values(get_config_vars()) 143 get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc64 -isysroot ' 144 '/Developer/SDKs/MacOSX10.4u.sdk ' 145 '-fno-strict-aliasing -fno-common ' 146 '-dynamic -DNDEBUG -g -O3') 147 148 self.assertEqual(get_platform(), 'macosx-10.4-fat64') 149 150 for arch in ('ppc', 'i386', 'x86_64', 'ppc64'): 151 _osx_support._remove_original_values(get_config_vars()) 152 get_config_vars()['CFLAGS'] = ('-arch %s -isysroot ' 153 '/Developer/SDKs/MacOSX10.4u.sdk ' 154 '-fno-strict-aliasing -fno-common ' 155 '-dynamic -DNDEBUG -g -O3'%(arch,)) 156 157 self.assertEqual(get_platform(), 'macosx-10.4-%s'%(arch,)) 158 159 160 # linux debian sarge 161 os.name = 'posix' 162 sys.version = ('2.3.5 (#1, Jul 4 2007, 17:28:59) ' 163 '\n[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)]') 164 sys.platform = 'linux2' 165 self._set_uname(('Linux', 'aglae', '2.6.21.1dedibox-r7', 166 '#1 Mon Apr 30 17:25:38 CEST 2007', 'i686')) 167 168 self.assertEqual(get_platform(), 'linux-i686') 169 170 # XXX more platforms to tests here 171 172 def test_convert_path(self): 173 # linux/mac 174 os.sep = '/' 175 def _join(path): 176 return '/'.join(path) 177 os.path.join = _join 178 179 self.assertEqual(convert_path('/home/to/my/stuff'), 180 '/home/to/my/stuff') 181 182 # win 183 os.sep = '\\' 184 def _join(*path): 185 return '\\'.join(path) 186 os.path.join = _join 187 188 self.assertRaises(ValueError, convert_path, '/home/to/my/stuff') 189 self.assertRaises(ValueError, convert_path, 'home/to/my/stuff/') 190 191 self.assertEqual(convert_path('home/to/my/stuff'), 192 'home\\to\\my\\stuff') 193 self.assertEqual(convert_path('.'), 194 os.curdir) 195 196 def test_change_root(self): 197 # linux/mac 198 os.name = 'posix' 199 def _isabs(path): 200 return path[0] == '/' 201 os.path.isabs = _isabs 202 def _join(*path): 203 return '/'.join(path) 204 os.path.join = _join 205 206 self.assertEqual(change_root('/root', '/old/its/here'), 207 '/root/old/its/here') 208 self.assertEqual(change_root('/root', 'its/here'), 209 '/root/its/here') 210 211 # windows 212 os.name = 'nt' 213 def _isabs(path): 214 return path.startswith('c:\\') 215 os.path.isabs = _isabs 216 def _splitdrive(path): 217 if path.startswith('c:'): 218 return ('', path.replace('c:', '')) 219 return ('', path) 220 os.path.splitdrive = _splitdrive 221 def _join(*path): 222 return '\\'.join(path) 223 os.path.join = _join 224 225 self.assertEqual(change_root('c:\\root', 'c:\\old\\its\\here'), 226 'c:\\root\\old\\its\\here') 227 self.assertEqual(change_root('c:\\root', 'its\\here'), 228 'c:\\root\\its\\here') 229 230 # BugsBunny os (it's a great os) 231 os.name = 'BugsBunny' 232 self.assertRaises(DistutilsPlatformError, 233 change_root, 'c:\\root', 'its\\here') 234 235 # XXX platforms to be covered: mac 236 237 def test_check_environ(self): 238 util._environ_checked = 0 239 os.environ.pop('HOME', None) 240 241 check_environ() 242 243 self.assertEqual(os.environ['PLAT'], get_platform()) 244 self.assertEqual(util._environ_checked, 1) 245 246 @unittest.skipUnless(os.name == 'posix', 'specific to posix') 247 def test_check_environ_getpwuid(self): 248 util._environ_checked = 0 249 os.environ.pop('HOME', None) 250 251 import pwd 252 253 # only set pw_dir field, other fields are not used 254 result = pwd.struct_passwd((None, None, None, None, None, 255 '/home/distutils', None)) 256 with mock.patch.object(pwd, 'getpwuid', return_value=result): 257 check_environ() 258 self.assertEqual(os.environ['HOME'], '/home/distutils') 259 260 util._environ_checked = 0 261 os.environ.pop('HOME', None) 262 263 # bpo-10496: Catch pwd.getpwuid() error 264 with mock.patch.object(pwd, 'getpwuid', side_effect=KeyError): 265 check_environ() 266 self.assertNotIn('HOME', os.environ) 267 268 def test_split_quoted(self): 269 self.assertEqual(split_quoted('""one"" "two" \'three\' \\four'), 270 ['one', 'two', 'three', 'four']) 271 272 def test_strtobool(self): 273 yes = ('y', 'Y', 'yes', 'True', 't', 'true', 'True', 'On', 'on', '1') 274 no = ('n', 'no', 'f', 'false', 'off', '0', 'Off', 'No', 'N') 275 276 for y in yes: 277 self.assertTrue(strtobool(y)) 278 279 for n in no: 280 self.assertFalse(strtobool(n)) 281 282 def test_rfc822_escape(self): 283 header = 'I am a\npoor\nlonesome\nheader\n' 284 res = rfc822_escape(header) 285 wanted = ('I am a%(8s)spoor%(8s)slonesome%(8s)s' 286 'header%(8s)s') % {'8s': '\n'+8*' '} 287 self.assertEqual(res, wanted) 288 289 def test_dont_write_bytecode(self): 290 # makes sure byte_compile raise a DistutilsError 291 # if sys.dont_write_bytecode is True 292 old_dont_write_bytecode = sys.dont_write_bytecode 293 sys.dont_write_bytecode = True 294 try: 295 self.assertRaises(DistutilsByteCompileError, byte_compile, []) 296 finally: 297 sys.dont_write_bytecode = old_dont_write_bytecode 298 299 def test_grok_environment_error(self): 300 # test obsolete function to ensure backward compat (#4931) 301 exc = IOError("Unable to find batch file") 302 msg = grok_environment_error(exc) 303 self.assertEqual(msg, "error: Unable to find batch file") 304 305 306def test_suite(): 307 return unittest.makeSuite(UtilTestCase) 308 309if __name__ == "__main__": 310 run_unittest(test_suite()) 311