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 self.addCleanup(os.close, fd) 203 except OSError as e: 204 self.assertEqual(e.errno, errno.EACCES) 205 self.skipTest("system cannot open directories") 206 with self.assertRaises(IOError) as cm: 207 os.fdopen(fd, 'r') 208 self.assertEqual(cm.exception.errno, errno.EISDIR) 209 210 @unittest.skipUnless(hasattr(posix, 'fdopen') and 211 not sys.platform.startswith("sunos"), 212 'test needs posix.fdopen()') 213 def test_fdopen_keeps_fd_open_on_errors(self): 214 fd = os.open(test_support.TESTFN, os.O_RDONLY) 215 self.assertRaises(OSError, posix.fdopen, fd, 'w') 216 os.close(fd) # fd should not be closed. 217 218 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'), 219 'test needs posix.O_EXLOCK') 220 def test_osexlock(self): 221 fd = os.open(test_support.TESTFN, 222 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT) 223 self.assertRaises(OSError, os.open, test_support.TESTFN, 224 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK) 225 os.close(fd) 226 227 if hasattr(posix, "O_SHLOCK"): 228 fd = os.open(test_support.TESTFN, 229 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT) 230 self.assertRaises(OSError, os.open, test_support.TESTFN, 231 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK) 232 os.close(fd) 233 234 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'), 235 'test needs posix.O_SHLOCK') 236 def test_osshlock(self): 237 fd1 = os.open(test_support.TESTFN, 238 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT) 239 fd2 = os.open(test_support.TESTFN, 240 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT) 241 os.close(fd2) 242 os.close(fd1) 243 244 if hasattr(posix, "O_EXLOCK"): 245 fd = os.open(test_support.TESTFN, 246 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT) 247 self.assertRaises(OSError, os.open, test_support.TESTFN, 248 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK) 249 os.close(fd) 250 251 @unittest.skipUnless(hasattr(posix, 'fstat'), 252 'test needs posix.fstat()') 253 def test_fstat(self): 254 fp = open(test_support.TESTFN) 255 try: 256 self.assertTrue(posix.fstat(fp.fileno())) 257 finally: 258 fp.close() 259 260 @unittest.skipUnless(hasattr(posix, 'stat'), 261 'test needs posix.stat()') 262 def test_stat(self): 263 self.assertTrue(posix.stat(test_support.TESTFN)) 264 265 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()') 266 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()') 267 def test_makedev(self): 268 st = posix.stat(test_support.TESTFN) 269 dev = st.st_dev 270 self.assertIsInstance(dev, (int, long)) 271 self.assertGreaterEqual(dev, 0) 272 273 major = posix.major(dev) 274 self.assertIsInstance(major, (int, long)) 275 self.assertGreaterEqual(major, 0) 276 self.assertEqual(posix.major(int(dev)), major) 277 self.assertEqual(posix.major(long(dev)), major) 278 self.assertRaises(TypeError, posix.major, float(dev)) 279 self.assertRaises(TypeError, posix.major) 280 self.assertRaises((ValueError, OverflowError), posix.major, -1) 281 282 minor = posix.minor(dev) 283 self.assertIsInstance(minor, (int, long)) 284 self.assertGreaterEqual(minor, 0) 285 self.assertEqual(posix.minor(int(dev)), minor) 286 self.assertEqual(posix.minor(long(dev)), minor) 287 self.assertRaises(TypeError, posix.minor, float(dev)) 288 self.assertRaises(TypeError, posix.minor) 289 self.assertRaises((ValueError, OverflowError), posix.minor, -1) 290 291 if sys.platform.startswith('freebsd') and dev >= 0x100000000: 292 self.skipTest("bpo-31044: on FreeBSD CURRENT, minor() truncates " 293 "64-bit dev to 32-bit") 294 295 self.assertEqual(posix.makedev(major, minor), dev) 296 self.assertEqual(posix.makedev(int(major), int(minor)), dev) 297 self.assertEqual(posix.makedev(long(major), long(minor)), dev) 298 self.assertRaises(TypeError, posix.makedev, float(major), minor) 299 self.assertRaises(TypeError, posix.makedev, major, float(minor)) 300 self.assertRaises(TypeError, posix.makedev, major) 301 self.assertRaises(TypeError, posix.makedev) 302 303 def _test_all_chown_common(self, chown_func, first_param, stat_func): 304 """Common code for chown, fchown and lchown tests.""" 305 def check_stat(uid, gid): 306 if stat_func is not None: 307 stat = stat_func(first_param) 308 self.assertEqual(stat.st_uid, uid) 309 self.assertEqual(stat.st_gid, gid) 310 uid = os.getuid() 311 gid = os.getgid() 312 # test a successful chown call 313 chown_func(first_param, uid, gid) 314 check_stat(uid, gid) 315 chown_func(first_param, -1, gid) 316 check_stat(uid, gid) 317 chown_func(first_param, uid, -1) 318 check_stat(uid, gid) 319 320 if uid == 0: 321 # Try an amusingly large uid/gid to make sure we handle 322 # large unsigned values. (chown lets you use any 323 # uid/gid you like, even if they aren't defined.) 324 # 325 # This problem keeps coming up: 326 # http://bugs.python.org/issue1747858 327 # http://bugs.python.org/issue4591 328 # http://bugs.python.org/issue15301 329 # Hopefully the fix in 4591 fixes it for good! 330 # 331 # This part of the test only runs when run as root. 332 # Only scary people run their tests as root. 333 334 big_value = 2**31 335 chown_func(first_param, big_value, big_value) 336 check_stat(big_value, big_value) 337 chown_func(first_param, -1, -1) 338 check_stat(big_value, big_value) 339 chown_func(first_param, uid, gid) 340 check_stat(uid, gid) 341 elif platform.system() in ('HP-UX', 'SunOS'): 342 # HP-UX and Solaris can allow a non-root user to chown() to root 343 # (issue #5113) 344 raise unittest.SkipTest("Skipping because of non-standard chown() " 345 "behavior") 346 else: 347 # non-root cannot chown to root, raises OSError 348 self.assertRaises(OSError, chown_func, first_param, 0, 0) 349 check_stat(uid, gid) 350 self.assertRaises(OSError, chown_func, first_param, 0, -1) 351 check_stat(uid, gid) 352 if 0 not in os.getgroups(): 353 self.assertRaises(OSError, chown_func, first_param, -1, 0) 354 check_stat(uid, gid) 355 # test illegal types 356 for t in str, float: 357 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid) 358 check_stat(uid, gid) 359 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid)) 360 check_stat(uid, gid) 361 362 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()") 363 def test_chown(self): 364 # raise an OSError if the file does not exist 365 os.unlink(test_support.TESTFN) 366 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1) 367 368 # re-create the file 369 open(test_support.TESTFN, 'w').close() 370 self._test_all_chown_common(posix.chown, test_support.TESTFN, 371 getattr(posix, 'stat', None)) 372 373 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()") 374 def test_fchown(self): 375 os.unlink(test_support.TESTFN) 376 377 # re-create the file 378 test_file = open(test_support.TESTFN, 'w') 379 try: 380 fd = test_file.fileno() 381 self._test_all_chown_common(posix.fchown, fd, 382 getattr(posix, 'fstat', None)) 383 finally: 384 test_file.close() 385 386 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()") 387 def test_lchown(self): 388 os.unlink(test_support.TESTFN) 389 # create a symlink 390 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN) 391 self._test_all_chown_common(posix.lchown, test_support.TESTFN, 392 getattr(posix, 'lstat', None)) 393 394 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()') 395 def test_chdir(self): 396 posix.chdir(os.curdir) 397 self.assertRaises(OSError, posix.chdir, test_support.TESTFN) 398 399 @unittest.skipUnless(hasattr(posix, 'lsdir'), 'test needs posix.lsdir()') 400 def test_lsdir(self): 401 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir)) 402 403 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()') 404 def test_access(self): 405 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK)) 406 407 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()') 408 def test_umask(self): 409 old_mask = posix.umask(0) 410 self.assertIsInstance(old_mask, int) 411 posix.umask(old_mask) 412 413 @unittest.skipUnless(hasattr(posix, 'strerror'), 414 'test needs posix.strerror()') 415 def test_strerror(self): 416 self.assertTrue(posix.strerror(0)) 417 418 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()') 419 def test_pipe(self): 420 reader, writer = posix.pipe() 421 os.close(reader) 422 os.close(writer) 423 424 @unittest.skipUnless(hasattr(posix, 'tempnam'), 425 'test needs posix.tempnam()') 426 def test_tempnam(self): 427 with warnings.catch_warnings(): 428 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning) 429 self.assertTrue(posix.tempnam()) 430 self.assertTrue(posix.tempnam(os.curdir)) 431 self.assertTrue(posix.tempnam(os.curdir, 'blah')) 432 433 @unittest.skipUnless(hasattr(posix, 'tmpfile'), 434 'test needs posix.tmpfile()') 435 def test_tmpfile(self): 436 with warnings.catch_warnings(): 437 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning) 438 fp = posix.tmpfile() 439 fp.close() 440 441 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()') 442 def test_utime(self): 443 now = time.time() 444 posix.utime(test_support.TESTFN, None) 445 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None)) 446 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None)) 447 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now)) 448 posix.utime(test_support.TESTFN, (int(now), int(now))) 449 posix.utime(test_support.TESTFN, (now, now)) 450 451 def _test_chflags_regular_file(self, chflags_func, target_file): 452 st = os.stat(target_file) 453 self.assertTrue(hasattr(st, 'st_flags')) 454 455 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE. 456 try: 457 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE) 458 except OSError as err: 459 if err.errno != errno.EOPNOTSUPP: 460 raise 461 msg = 'chflag UF_IMMUTABLE not supported by underlying fs' 462 self.skipTest(msg) 463 464 try: 465 new_st = os.stat(target_file) 466 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags) 467 try: 468 fd = open(target_file, 'w+') 469 except IOError as e: 470 self.assertEqual(e.errno, errno.EPERM) 471 finally: 472 posix.chflags(target_file, st.st_flags) 473 474 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()') 475 def test_chflags(self): 476 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN) 477 478 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()') 479 def test_lchflags_regular_file(self): 480 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN) 481 482 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()') 483 def test_lchflags_symlink(self): 484 testfn_st = os.stat(test_support.TESTFN) 485 486 self.assertTrue(hasattr(testfn_st, 'st_flags')) 487 488 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK) 489 self.teardown_files.append(_DUMMY_SYMLINK) 490 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK) 491 492 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE. 493 try: 494 posix.lchflags(_DUMMY_SYMLINK, 495 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE) 496 except OSError as err: 497 if err.errno != errno.EOPNOTSUPP: 498 raise 499 msg = 'chflag UF_IMMUTABLE not supported by underlying fs' 500 self.skipTest(msg) 501 502 try: 503 new_testfn_st = os.stat(test_support.TESTFN) 504 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK) 505 506 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags) 507 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE, 508 new_dummy_symlink_st.st_flags) 509 finally: 510 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags) 511 512 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()") 513 def test_putenv(self): 514 with self.assertRaises(TypeError): 515 os.putenv('FRUIT\0VEGETABLE', 'cabbage') 516 with self.assertRaises(TypeError): 517 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage') 518 with self.assertRaises(ValueError): 519 os.putenv('FRUIT=ORANGE', 'lemon') 520 521 @unittest.skipUnless(hasattr(posix, 'getcwd'), 522 'test needs posix.getcwd()') 523 def test_getcwd_long_pathnames(self): 524 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef' 525 curdir = os.getcwd() 526 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd' 527 528 try: 529 os.mkdir(base_path) 530 os.chdir(base_path) 531 except: 532 self.skipTest("cannot create directory for testing") 533 534 try: 535 def _create_and_do_getcwd(dirname, current_path_length = 0): 536 try: 537 os.mkdir(dirname) 538 except: 539 self.skipTest("mkdir cannot create directory sufficiently " 540 "deep for getcwd test") 541 542 os.chdir(dirname) 543 try: 544 os.getcwd() 545 if current_path_length < 4099: 546 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1) 547 except OSError as e: 548 expected_errno = errno.ENAMETOOLONG 549 # The following platforms have quirky getcwd() 550 # behaviour -- see issue 9185 and 15765 for 551 # more information. 552 quirky_platform = ( 553 'sunos' in sys.platform or 554 'netbsd' in sys.platform or 555 'openbsd' in sys.platform 556 ) 557 if quirky_platform: 558 expected_errno = errno.ERANGE 559 self.assertEqual(e.errno, expected_errno) 560 finally: 561 os.chdir('..') 562 os.rmdir(dirname) 563 564 _create_and_do_getcwd(dirname) 565 566 finally: 567 os.chdir(curdir) 568 shutil.rmtree(base_path) 569 570 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()") 571 def test_getgroups(self): 572 with os.popen('id -G 2>/dev/null') as idg: 573 groups = idg.read().strip() 574 ret = idg.close() 575 576 if ret != None or not groups: 577 raise unittest.SkipTest("need working 'id -G'") 578 579 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups() 580 if sys.platform == 'darwin': 581 import sysconfig 582 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0' 583 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6): 584 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6") 585 586 # 'id -G' and 'os.getgroups()' should return the same 587 # groups, ignoring order and duplicates. 588 # #10822 - it is implementation defined whether posix.getgroups() 589 # includes the effective gid so we include it anyway, since id -G does 590 self.assertEqual( 591 set([int(x) for x in groups.split()]), 592 set(posix.getgroups() + [posix.getegid()])) 593 594 @test_support.requires_unicode 595 def test_path_with_null_unicode(self): 596 fn = test_support.TESTFN_UNICODE 597 try: 598 fn.encode(test_support.TESTFN_ENCODING) 599 except (UnicodeError, TypeError): 600 self.skipTest("Requires unicode filenames support") 601 fn_with_NUL = fn + u'\0' 602 self.addCleanup(test_support.unlink, fn) 603 test_support.unlink(fn) 604 fd = None 605 try: 606 with self.assertRaises(TypeError): 607 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises 608 finally: 609 if fd is not None: 610 os.close(fd) 611 self.assertFalse(os.path.exists(fn)) 612 self.assertRaises(TypeError, os.mkdir, fn_with_NUL) 613 self.assertFalse(os.path.exists(fn)) 614 open(fn, 'wb').close() 615 self.assertRaises(TypeError, os.stat, fn_with_NUL) 616 617 def test_path_with_null_byte(self): 618 fn = test_support.TESTFN 619 fn_with_NUL = fn + '\0' 620 self.addCleanup(test_support.unlink, fn) 621 test_support.unlink(fn) 622 fd = None 623 try: 624 with self.assertRaises(TypeError): 625 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises 626 finally: 627 if fd is not None: 628 os.close(fd) 629 self.assertFalse(os.path.exists(fn)) 630 self.assertRaises(TypeError, os.mkdir, fn_with_NUL) 631 self.assertFalse(os.path.exists(fn)) 632 open(fn, 'wb').close() 633 self.assertRaises(TypeError, os.stat, fn_with_NUL) 634 635 636class PosixGroupsTester(unittest.TestCase): 637 638 def setUp(self): 639 if posix.getuid() != 0: 640 raise unittest.SkipTest("not enough privileges") 641 if not hasattr(posix, 'getgroups'): 642 raise unittest.SkipTest("need posix.getgroups") 643 if sys.platform == 'darwin': 644 raise unittest.SkipTest("getgroups(2) is broken on OSX") 645 self.saved_groups = posix.getgroups() 646 647 def tearDown(self): 648 if hasattr(posix, 'setgroups'): 649 posix.setgroups(self.saved_groups) 650 elif hasattr(posix, 'initgroups'): 651 name = pwd.getpwuid(posix.getuid()).pw_name 652 posix.initgroups(name, self.saved_groups[0]) 653 654 @unittest.skipUnless(hasattr(posix, 'initgroups'), 655 'test needs posix.initgroups()') 656 def test_initgroups(self): 657 # find missing group 658 659 g = max(self.saved_groups or [0]) + 1 660 name = pwd.getpwuid(posix.getuid()).pw_name 661 posix.initgroups(name, g) 662 self.assertIn(g, posix.getgroups()) 663 664 @unittest.skipUnless(hasattr(posix, 'setgroups'), 665 'test needs posix.setgroups()') 666 def test_setgroups(self): 667 for groups in [[0], range(16)]: 668 posix.setgroups(groups) 669 self.assertListEqual(groups, posix.getgroups()) 670 671 672def test_main(): 673 test_support.run_unittest(PosixTester, PosixGroupsTester) 674 675if __name__ == '__main__': 676 test_main() 677