1"Test posix functions" 2 3from test import test_support 4 5# Skip these tests if there is no posix module. 6posix = test_support.import_module('posix') 7 8import errno 9import sys 10import time 11import os 12import platform 13import pwd 14import shutil 15import stat 16import sys 17import tempfile 18import unittest 19import warnings 20 21_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(), 22 test_support.TESTFN + '-dummy-symlink') 23 24warnings.filterwarnings('ignore', '.* potential security risk .*', 25 RuntimeWarning) 26 27class PosixTester(unittest.TestCase): 28 29 def setUp(self): 30 # create empty file 31 fp = open(test_support.TESTFN, 'w+') 32 fp.close() 33 self.teardown_files = [ test_support.TESTFN ] 34 35 def tearDown(self): 36 for teardown_file in self.teardown_files: 37 os.unlink(teardown_file) 38 39 def testNoArgFunctions(self): 40 # test posix functions which take no arguments and have 41 # no side-effects which we need to cleanup (e.g., fork, wait, abort) 42 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdu", "uname", 43 "times", "getloadavg", "tmpnam", 44 "getegid", "geteuid", "getgid", "getgroups", 45 "getpid", "getpgrp", "getppid", "getuid", 46 ] 47 48 with warnings.catch_warnings(): 49 warnings.filterwarnings("ignore", "", DeprecationWarning) 50 for name in NO_ARG_FUNCTIONS: 51 posix_func = getattr(posix, name, None) 52 if posix_func is not None: 53 posix_func() 54 self.assertRaises(TypeError, posix_func, 1) 55 56 @unittest.skipUnless(hasattr(posix, 'getresuid'), 57 'test needs posix.getresuid()') 58 def test_getresuid(self): 59 user_ids = posix.getresuid() 60 self.assertEqual(len(user_ids), 3) 61 for val in user_ids: 62 self.assertGreaterEqual(val, 0) 63 64 @unittest.skipUnless(hasattr(posix, 'getresgid'), 65 'test needs posix.getresgid()') 66 def test_getresgid(self): 67 group_ids = posix.getresgid() 68 self.assertEqual(len(group_ids), 3) 69 for val in group_ids: 70 self.assertGreaterEqual(val, 0) 71 72 @unittest.skipUnless(hasattr(posix, 'setresuid'), 73 'test needs posix.setresuid()') 74 def test_setresuid(self): 75 current_user_ids = posix.getresuid() 76 self.assertIsNone(posix.setresuid(*current_user_ids)) 77 # -1 means don't change that value. 78 self.assertIsNone(posix.setresuid(-1, -1, -1)) 79 80 @unittest.skipUnless(hasattr(posix, 'setresuid'), 81 'test needs posix.setresuid()') 82 def test_setresuid_exception(self): 83 # Don't do this test if someone is silly enough to run us as root. 84 current_user_ids = posix.getresuid() 85 if 0 not in current_user_ids: 86 new_user_ids = (current_user_ids[0]+1, -1, -1) 87 self.assertRaises(OSError, posix.setresuid, *new_user_ids) 88 89 @unittest.skipUnless(hasattr(posix, 'setresgid'), 90 'test needs posix.setresgid()') 91 def test_setresgid(self): 92 current_group_ids = posix.getresgid() 93 self.assertIsNone(posix.setresgid(*current_group_ids)) 94 # -1 means don't change that value. 95 self.assertIsNone(posix.setresgid(-1, -1, -1)) 96 97 @unittest.skipUnless(hasattr(posix, 'setresgid'), 98 'test needs posix.setresgid()') 99 def test_setresgid_exception(self): 100 # Don't do this test if someone is silly enough to run us as root. 101 current_group_ids = posix.getresgid() 102 if 0 not in current_group_ids: 103 new_group_ids = (current_group_ids[0]+1, -1, -1) 104 self.assertRaises(OSError, posix.setresgid, *new_group_ids) 105 106 @unittest.skipUnless(hasattr(posix, 'initgroups'), 107 "test needs os.initgroups()") 108 def test_initgroups(self): 109 # It takes a string and an integer; check that it raises a TypeError 110 # for other argument lists. 111 self.assertRaises(TypeError, posix.initgroups) 112 self.assertRaises(TypeError, posix.initgroups, None) 113 self.assertRaises(TypeError, posix.initgroups, 3, "foo") 114 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object()) 115 116 # If a non-privileged user invokes it, it should fail with OSError 117 # EPERM. 118 if os.getuid() != 0: 119 try: 120 name = pwd.getpwuid(posix.getuid()).pw_name 121 except KeyError: 122 # the current UID may not have a pwd entry 123 raise unittest.SkipTest("need a pwd entry") 124 try: 125 posix.initgroups(name, 13) 126 except OSError as e: 127 self.assertEqual(e.errno, errno.EPERM) 128 else: 129 self.fail("Expected OSError to be raised by initgroups") 130 131 @unittest.skipUnless(hasattr(posix, 'statvfs'), 132 'test needs posix.statvfs()') 133 def test_statvfs(self): 134 self.assertTrue(posix.statvfs(os.curdir)) 135 136 @unittest.skipUnless(hasattr(posix, 'fstatvfs'), 137 'test needs posix.fstatvfs()') 138 def test_fstatvfs(self): 139 fp = open(test_support.TESTFN) 140 try: 141 self.assertTrue(posix.fstatvfs(fp.fileno())) 142 finally: 143 fp.close() 144 145 @unittest.skipUnless(hasattr(posix, 'ftruncate'), 146 'test needs posix.ftruncate()') 147 def test_ftruncate(self): 148 fp = open(test_support.TESTFN, 'w+') 149 try: 150 # we need to have some data to truncate 151 fp.write('test') 152 fp.flush() 153 posix.ftruncate(fp.fileno(), 0) 154 finally: 155 fp.close() 156 157 @unittest.skipUnless(hasattr(posix, 'dup'), 158 'test needs posix.dup()') 159 def test_dup(self): 160 fp = open(test_support.TESTFN) 161 try: 162 fd = posix.dup(fp.fileno()) 163 self.assertIsInstance(fd, int) 164 os.close(fd) 165 finally: 166 fp.close() 167 168 @unittest.skipUnless(hasattr(posix, 'confstr'), 169 'test needs posix.confstr()') 170 def test_confstr(self): 171 self.assertRaises(ValueError, posix.confstr, "CS_garbage") 172 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True) 173 174 @unittest.skipUnless(hasattr(posix, 'dup2'), 175 'test needs posix.dup2()') 176 def test_dup2(self): 177 fp1 = open(test_support.TESTFN) 178 fp2 = open(test_support.TESTFN) 179 try: 180 posix.dup2(fp1.fileno(), fp2.fileno()) 181 finally: 182 fp1.close() 183 fp2.close() 184 185 def fdopen_helper(self, *args): 186 fd = os.open(test_support.TESTFN, os.O_RDONLY) 187 fp2 = posix.fdopen(fd, *args) 188 fp2.close() 189 190 @unittest.skipUnless(hasattr(posix, 'fdopen'), 191 'test needs posix.fdopen()') 192 def test_fdopen(self): 193 self.fdopen_helper() 194 self.fdopen_helper('r') 195 self.fdopen_helper('r', 100) 196 197 @unittest.skipUnless(hasattr(posix, 'fdopen'), 198 'test needs posix.fdopen()') 199 def test_fdopen_directory(self): 200 try: 201 fd = os.open('.', os.O_RDONLY) 202 except OSError as e: 203 self.assertEqual(e.errno, errno.EACCES) 204 self.skipTest("system cannot open directories") 205 with self.assertRaises(IOError) as cm: 206 os.fdopen(fd, 'r') 207 self.assertEqual(cm.exception.errno, errno.EISDIR) 208 209 @unittest.skipUnless(hasattr(posix, 'fdopen') and 210 not sys.platform.startswith("sunos"), 211 'test needs posix.fdopen()') 212 def test_fdopen_keeps_fd_open_on_errors(self): 213 fd = os.open(test_support.TESTFN, os.O_RDONLY) 214 self.assertRaises(OSError, posix.fdopen, fd, 'w') 215 os.close(fd) # fd should not be closed. 216 217 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'), 218 'test needs posix.O_EXLOCK') 219 def test_osexlock(self): 220 fd = os.open(test_support.TESTFN, 221 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT) 222 self.assertRaises(OSError, os.open, test_support.TESTFN, 223 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK) 224 os.close(fd) 225 226 if hasattr(posix, "O_SHLOCK"): 227 fd = os.open(test_support.TESTFN, 228 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT) 229 self.assertRaises(OSError, os.open, test_support.TESTFN, 230 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK) 231 os.close(fd) 232 233 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'), 234 'test needs posix.O_SHLOCK') 235 def test_osshlock(self): 236 fd1 = os.open(test_support.TESTFN, 237 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT) 238 fd2 = os.open(test_support.TESTFN, 239 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT) 240 os.close(fd2) 241 os.close(fd1) 242 243 if hasattr(posix, "O_EXLOCK"): 244 fd = os.open(test_support.TESTFN, 245 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT) 246 self.assertRaises(OSError, os.open, test_support.TESTFN, 247 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK) 248 os.close(fd) 249 250 @unittest.skipUnless(hasattr(posix, 'fstat'), 251 'test needs posix.fstat()') 252 def test_fstat(self): 253 fp = open(test_support.TESTFN) 254 try: 255 self.assertTrue(posix.fstat(fp.fileno())) 256 finally: 257 fp.close() 258 259 @unittest.skipUnless(hasattr(posix, 'stat'), 260 'test needs posix.stat()') 261 def test_stat(self): 262 self.assertTrue(posix.stat(test_support.TESTFN)) 263 264 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()') 265 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()') 266 def test_makedev(self): 267 st = posix.stat(test_support.TESTFN) 268 dev = st.st_dev 269 self.assertIsInstance(dev, (int, long)) 270 self.assertGreaterEqual(dev, 0) 271 272 major = posix.major(dev) 273 self.assertIsInstance(major, (int, long)) 274 self.assertGreaterEqual(major, 0) 275 self.assertEqual(posix.major(int(dev)), major) 276 self.assertEqual(posix.major(long(dev)), major) 277 self.assertRaises(TypeError, posix.major, float(dev)) 278 self.assertRaises(TypeError, posix.major) 279 self.assertRaises((ValueError, OverflowError), posix.major, -1) 280 281 minor = posix.minor(dev) 282 self.assertIsInstance(minor, (int, long)) 283 self.assertGreaterEqual(minor, 0) 284 self.assertEqual(posix.minor(int(dev)), minor) 285 self.assertEqual(posix.minor(long(dev)), minor) 286 self.assertRaises(TypeError, posix.minor, float(dev)) 287 self.assertRaises(TypeError, posix.minor) 288 self.assertRaises((ValueError, OverflowError), posix.minor, -1) 289 290 self.assertEqual(posix.makedev(major, minor), dev) 291 self.assertEqual(posix.makedev(int(major), int(minor)), dev) 292 self.assertEqual(posix.makedev(long(major), long(minor)), dev) 293 self.assertRaises(TypeError, posix.makedev, float(major), minor) 294 self.assertRaises(TypeError, posix.makedev, major, float(minor)) 295 self.assertRaises(TypeError, posix.makedev, major) 296 self.assertRaises(TypeError, posix.makedev) 297 298 def _test_all_chown_common(self, chown_func, first_param, stat_func): 299 """Common code for chown, fchown and lchown tests.""" 300 def check_stat(uid, gid): 301 if stat_func is not None: 302 stat = stat_func(first_param) 303 self.assertEqual(stat.st_uid, uid) 304 self.assertEqual(stat.st_gid, gid) 305 uid = os.getuid() 306 gid = os.getgid() 307 # test a successful chown call 308 chown_func(first_param, uid, gid) 309 check_stat(uid, gid) 310 chown_func(first_param, -1, gid) 311 check_stat(uid, gid) 312 chown_func(first_param, uid, -1) 313 check_stat(uid, gid) 314 315 if uid == 0: 316 # Try an amusingly large uid/gid to make sure we handle 317 # large unsigned values. (chown lets you use any 318 # uid/gid you like, even if they aren't defined.) 319 # 320 # This problem keeps coming up: 321 # http://bugs.python.org/issue1747858 322 # http://bugs.python.org/issue4591 323 # http://bugs.python.org/issue15301 324 # Hopefully the fix in 4591 fixes it for good! 325 # 326 # This part of the test only runs when run as root. 327 # Only scary people run their tests as root. 328 329 big_value = 2**31 330 chown_func(first_param, big_value, big_value) 331 check_stat(big_value, big_value) 332 chown_func(first_param, -1, -1) 333 check_stat(big_value, big_value) 334 chown_func(first_param, uid, gid) 335 check_stat(uid, gid) 336 elif platform.system() in ('HP-UX', 'SunOS'): 337 # HP-UX and Solaris can allow a non-root user to chown() to root 338 # (issue #5113) 339 raise unittest.SkipTest("Skipping because of non-standard chown() " 340 "behavior") 341 else: 342 # non-root cannot chown to root, raises OSError 343 self.assertRaises(OSError, chown_func, first_param, 0, 0) 344 check_stat(uid, gid) 345 self.assertRaises(OSError, chown_func, first_param, 0, -1) 346 check_stat(uid, gid) 347 if 0 not in os.getgroups(): 348 self.assertRaises(OSError, chown_func, first_param, -1, 0) 349 check_stat(uid, gid) 350 # test illegal types 351 for t in str, float: 352 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid) 353 check_stat(uid, gid) 354 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid)) 355 check_stat(uid, gid) 356 357 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()") 358 def test_chown(self): 359 # raise an OSError if the file does not exist 360 os.unlink(test_support.TESTFN) 361 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1) 362 363 # re-create the file 364 open(test_support.TESTFN, 'w').close() 365 self._test_all_chown_common(posix.chown, test_support.TESTFN, 366 getattr(posix, 'stat', None)) 367 368 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()") 369 def test_fchown(self): 370 os.unlink(test_support.TESTFN) 371 372 # re-create the file 373 test_file = open(test_support.TESTFN, 'w') 374 try: 375 fd = test_file.fileno() 376 self._test_all_chown_common(posix.fchown, fd, 377 getattr(posix, 'fstat', None)) 378 finally: 379 test_file.close() 380 381 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()") 382 def test_lchown(self): 383 os.unlink(test_support.TESTFN) 384 # create a symlink 385 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN) 386 self._test_all_chown_common(posix.lchown, test_support.TESTFN, 387 getattr(posix, 'lstat', None)) 388 389 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()') 390 def test_chdir(self): 391 posix.chdir(os.curdir) 392 self.assertRaises(OSError, posix.chdir, test_support.TESTFN) 393 394 @unittest.skipUnless(hasattr(posix, 'lsdir'), 'test needs posix.lsdir()') 395 def test_lsdir(self): 396 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir)) 397 398 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()') 399 def test_access(self): 400 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK)) 401 402 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()') 403 def test_umask(self): 404 old_mask = posix.umask(0) 405 self.assertIsInstance(old_mask, int) 406 posix.umask(old_mask) 407 408 @unittest.skipUnless(hasattr(posix, 'strerror'), 409 'test needs posix.strerror()') 410 def test_strerror(self): 411 self.assertTrue(posix.strerror(0)) 412 413 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()') 414 def test_pipe(self): 415 reader, writer = posix.pipe() 416 os.close(reader) 417 os.close(writer) 418 419 @unittest.skipUnless(hasattr(posix, 'tempnam'), 420 'test needs posix.tempnam()') 421 def test_tempnam(self): 422 with warnings.catch_warnings(): 423 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning) 424 self.assertTrue(posix.tempnam()) 425 self.assertTrue(posix.tempnam(os.curdir)) 426 self.assertTrue(posix.tempnam(os.curdir, 'blah')) 427 428 @unittest.skipUnless(hasattr(posix, 'tmpfile'), 429 'test needs posix.tmpfile()') 430 def test_tmpfile(self): 431 with warnings.catch_warnings(): 432 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning) 433 fp = posix.tmpfile() 434 fp.close() 435 436 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()') 437 def test_utime(self): 438 now = time.time() 439 posix.utime(test_support.TESTFN, None) 440 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None)) 441 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None)) 442 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now)) 443 posix.utime(test_support.TESTFN, (int(now), int(now))) 444 posix.utime(test_support.TESTFN, (now, now)) 445 446 def _test_chflags_regular_file(self, chflags_func, target_file): 447 st = os.stat(target_file) 448 self.assertTrue(hasattr(st, 'st_flags')) 449 450 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE. 451 try: 452 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE) 453 except OSError as err: 454 if err.errno != errno.EOPNOTSUPP: 455 raise 456 msg = 'chflag UF_IMMUTABLE not supported by underlying fs' 457 self.skipTest(msg) 458 459 try: 460 new_st = os.stat(target_file) 461 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags) 462 try: 463 fd = open(target_file, 'w+') 464 except IOError as e: 465 self.assertEqual(e.errno, errno.EPERM) 466 finally: 467 posix.chflags(target_file, st.st_flags) 468 469 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()') 470 def test_chflags(self): 471 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN) 472 473 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()') 474 def test_lchflags_regular_file(self): 475 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN) 476 477 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()') 478 def test_lchflags_symlink(self): 479 testfn_st = os.stat(test_support.TESTFN) 480 481 self.assertTrue(hasattr(testfn_st, 'st_flags')) 482 483 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK) 484 self.teardown_files.append(_DUMMY_SYMLINK) 485 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK) 486 487 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE. 488 try: 489 posix.lchflags(_DUMMY_SYMLINK, 490 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE) 491 except OSError as err: 492 if err.errno != errno.EOPNOTSUPP: 493 raise 494 msg = 'chflag UF_IMMUTABLE not supported by underlying fs' 495 self.skipTest(msg) 496 497 try: 498 new_testfn_st = os.stat(test_support.TESTFN) 499 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK) 500 501 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags) 502 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE, 503 new_dummy_symlink_st.st_flags) 504 finally: 505 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags) 506 507 @unittest.skipUnless(hasattr(posix, 'getcwd'), 508 'test needs posix.getcwd()') 509 def test_getcwd_long_pathnames(self): 510 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef' 511 curdir = os.getcwd() 512 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd' 513 514 try: 515 os.mkdir(base_path) 516 os.chdir(base_path) 517 except: 518 self.skipTest("cannot create directory for testing") 519 520 try: 521 def _create_and_do_getcwd(dirname, current_path_length = 0): 522 try: 523 os.mkdir(dirname) 524 except: 525 self.skipTest("mkdir cannot create directory sufficiently " 526 "deep for getcwd test") 527 528 os.chdir(dirname) 529 try: 530 os.getcwd() 531 if current_path_length < 4099: 532 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1) 533 except OSError as e: 534 expected_errno = errno.ENAMETOOLONG 535 # The following platforms have quirky getcwd() 536 # behaviour -- see issue 9185 and 15765 for 537 # more information. 538 quirky_platform = ( 539 'sunos' in sys.platform or 540 'netbsd' in sys.platform or 541 'openbsd' in sys.platform 542 ) 543 if quirky_platform: 544 expected_errno = errno.ERANGE 545 self.assertEqual(e.errno, expected_errno) 546 finally: 547 os.chdir('..') 548 os.rmdir(dirname) 549 550 _create_and_do_getcwd(dirname) 551 552 finally: 553 os.chdir(curdir) 554 shutil.rmtree(base_path) 555 556 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()") 557 def test_getgroups(self): 558 with os.popen('id -G 2>/dev/null') as idg: 559 groups = idg.read().strip() 560 ret = idg.close() 561 562 if ret != None or not groups: 563 raise unittest.SkipTest("need working 'id -G'") 564 565 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups() 566 if sys.platform == 'darwin': 567 import sysconfig 568 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0' 569 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6): 570 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6") 571 572 # 'id -G' and 'os.getgroups()' should return the same 573 # groups, ignoring order and duplicates. 574 # #10822 - it is implementation defined whether posix.getgroups() 575 # includes the effective gid so we include it anyway, since id -G does 576 self.assertEqual( 577 set([int(x) for x in groups.split()]), 578 set(posix.getgroups() + [posix.getegid()])) 579 580 @test_support.requires_unicode 581 def test_path_with_null_unicode(self): 582 fn = test_support.TESTFN_UNICODE 583 try: 584 fn.encode(test_support.TESTFN_ENCODING) 585 except (UnicodeError, TypeError): 586 self.skipTest("Requires unicode filenames support") 587 fn_with_NUL = fn + u'\0' 588 self.addCleanup(test_support.unlink, fn) 589 test_support.unlink(fn) 590 fd = None 591 try: 592 with self.assertRaises(TypeError): 593 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises 594 finally: 595 if fd is not None: 596 os.close(fd) 597 self.assertFalse(os.path.exists(fn)) 598 self.assertRaises(TypeError, os.mkdir, fn_with_NUL) 599 self.assertFalse(os.path.exists(fn)) 600 open(fn, 'wb').close() 601 self.assertRaises(TypeError, os.stat, fn_with_NUL) 602 603 def test_path_with_null_byte(self): 604 fn = test_support.TESTFN 605 fn_with_NUL = fn + '\0' 606 self.addCleanup(test_support.unlink, fn) 607 test_support.unlink(fn) 608 fd = None 609 try: 610 with self.assertRaises(TypeError): 611 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises 612 finally: 613 if fd is not None: 614 os.close(fd) 615 self.assertFalse(os.path.exists(fn)) 616 self.assertRaises(TypeError, os.mkdir, fn_with_NUL) 617 self.assertFalse(os.path.exists(fn)) 618 open(fn, 'wb').close() 619 self.assertRaises(TypeError, os.stat, fn_with_NUL) 620 621 622class PosixGroupsTester(unittest.TestCase): 623 624 def setUp(self): 625 if posix.getuid() != 0: 626 raise unittest.SkipTest("not enough privileges") 627 if not hasattr(posix, 'getgroups'): 628 raise unittest.SkipTest("need posix.getgroups") 629 if sys.platform == 'darwin': 630 raise unittest.SkipTest("getgroups(2) is broken on OSX") 631 self.saved_groups = posix.getgroups() 632 633 def tearDown(self): 634 if hasattr(posix, 'setgroups'): 635 posix.setgroups(self.saved_groups) 636 elif hasattr(posix, 'initgroups'): 637 name = pwd.getpwuid(posix.getuid()).pw_name 638 posix.initgroups(name, self.saved_groups[0]) 639 640 @unittest.skipUnless(hasattr(posix, 'initgroups'), 641 'test needs posix.initgroups()') 642 def test_initgroups(self): 643 # find missing group 644 645 g = max(self.saved_groups or [0]) + 1 646 name = pwd.getpwuid(posix.getuid()).pw_name 647 posix.initgroups(name, g) 648 self.assertIn(g, posix.getgroups()) 649 650 @unittest.skipUnless(hasattr(posix, 'setgroups'), 651 'test needs posix.setgroups()') 652 def test_setgroups(self): 653 for groups in [[0], range(16)]: 654 posix.setgroups(groups) 655 self.assertListEqual(groups, posix.getgroups()) 656 657 658def test_main(): 659 test_support.run_unittest(PosixTester, PosixGroupsTester) 660 661if __name__ == '__main__': 662 test_main() 663