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