Changeset 391 for python/trunk/Lib/test/test_os.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/test/test_os.py
r2 r391 4 4 5 5 import os 6 import errno 6 7 import unittest 7 8 import warnings 8 9 import sys 10 import signal 11 import subprocess 12 import time 13 try: 14 import resource 15 except ImportError: 16 resource = None 17 9 18 from test import test_support 19 from test.script_helper import assert_python_ok 20 import mmap 21 import uuid 10 22 11 23 warnings.filterwarnings("ignore", "tempnam", RuntimeWarning, __name__) … … 22 34 f = os.open(test_support.TESTFN, os.O_CREAT|os.O_RDWR) 23 35 os.close(f) 24 self.assert _(os.access(test_support.TESTFN, os.W_OK))36 self.assertTrue(os.access(test_support.TESTFN, os.W_OK)) 25 37 26 38 def test_closerange(self): … … 37 49 if retries > 10: 38 50 # XXX test skipped 39 print >> sys.stderr, ( 40 "couldn't allocate two consecutive fds, " 41 "skipping test_closerange") 42 return 51 self.skipTest("couldn't allocate two consecutive fds") 43 52 first, second = second, os.dup(second) 44 53 finally: … … 48 57 self.assertRaises(OSError, os.write, first, "a") 49 58 59 @test_support.cpython_only 50 60 def test_rename(self): 51 61 path = unicode(test_support.TESTFN) … … 68 78 def check_tempfile(self, name): 69 79 # make sure it doesn't already exist: 70 self. failIf(os.path.exists(name),80 self.assertFalse(os.path.exists(name), 71 81 "file already exists for temporary file") 72 82 # make sure we can create the file … … 77 87 if not hasattr(os, "tempnam"): 78 88 return 79 warnings.filterwarnings("ignore", "tempnam", RuntimeWarning, 80 r"test_os$") 81 self.check_tempfile(os.tempnam()) 82 83 name = os.tempnam(test_support.TESTFN) 84 self.check_tempfile(name) 85 86 name = os.tempnam(test_support.TESTFN, "pfx") 87 self.assert_(os.path.basename(name)[:3] == "pfx") 88 self.check_tempfile(name) 89 with warnings.catch_warnings(): 90 warnings.filterwarnings("ignore", "tempnam", RuntimeWarning, 91 r"test_os$") 92 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning) 93 self.check_tempfile(os.tempnam()) 94 95 name = os.tempnam(test_support.TESTFN) 96 self.check_tempfile(name) 97 98 name = os.tempnam(test_support.TESTFN, "pfx") 99 self.assertTrue(os.path.basename(name)[:3] == "pfx") 100 self.check_tempfile(name) 89 101 90 102 def test_tmpfile(self): … … 105 117 # it doesn't, assume we're on XP or below and the user running the test 106 118 # has administrative privileges, and proceed with the test as normal. 107 if sys.platform == 'win32': 108 name = '\\python_test_os_test_tmpfile.txt' 109 if os.path.exists(name): 110 os.remove(name) 111 try: 112 fp = open(name, 'w') 113 except IOError, first: 114 # open() failed, assert tmpfile() fails in the same way. 115 # Although open() raises an IOError and os.tmpfile() raises an 116 # OSError(), 'args' will be (13, 'Permission denied') in both 117 # cases. 119 with warnings.catch_warnings(): 120 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning) 121 122 if sys.platform == 'win32': 123 name = '\\python_test_os_test_tmpfile.txt' 124 if os.path.exists(name): 125 os.remove(name) 118 126 try: 119 fp = os.tmpfile() 120 except OSError, second: 121 self.assertEqual(first.args, second.args) 127 fp = open(name, 'w') 128 except IOError, first: 129 # open() failed, assert tmpfile() fails in the same way. 130 # Although open() raises an IOError and os.tmpfile() raises an 131 # OSError(), 'args' will be (13, 'Permission denied') in both 132 # cases. 133 try: 134 fp = os.tmpfile() 135 except OSError, second: 136 self.assertEqual(first.args, second.args) 137 else: 138 self.fail("expected os.tmpfile() to raise OSError") 139 return 122 140 else: 123 self.fail("expected os.tmpfile() to raise OSError") 124 return 125 else: 126 # open() worked, therefore, tmpfile() should work. Close our 127 # dummy file and proceed with the test as normal. 128 fp.close() 129 os.remove(name) 130 131 fp = os.tmpfile() 132 fp.write("foobar") 133 fp.seek(0,0) 134 s = fp.read() 135 fp.close() 136 self.assert_(s == "foobar") 141 # open() worked, therefore, tmpfile() should work. Close our 142 # dummy file and proceed with the test as normal. 143 fp.close() 144 os.remove(name) 145 146 fp = os.tmpfile() 147 fp.write("foobar") 148 fp.seek(0,0) 149 s = fp.read() 150 fp.close() 151 self.assertTrue(s == "foobar") 137 152 138 153 def test_tmpnam(self): 139 import sys140 154 if not hasattr(os, "tmpnam"): 141 155 return 142 warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning, 143 r"test_os$") 144 name = os.tmpnam() 145 if sys.platform in ("win32",): 146 # The Windows tmpnam() seems useless. From the MS docs: 147 # 148 # The character string that tmpnam creates consists of 149 # the path prefix, defined by the entry P_tmpdir in the 150 # file STDIO.H, followed by a sequence consisting of the 151 # digit characters '0' through '9'; the numerical value 152 # of this string is in the range 1 - 65,535. Changing the 153 # definitions of L_tmpnam or P_tmpdir in STDIO.H does not 154 # change the operation of tmpnam. 155 # 156 # The really bizarre part is that, at least under MSVC6, 157 # P_tmpdir is "\\". That is, the path returned refers to 158 # the root of the current drive. That's a terrible place to 159 # put temp files, and, depending on privileges, the user 160 # may not even be able to open a file in the root directory. 161 self.failIf(os.path.exists(name), 162 "file already exists for temporary file") 163 else: 164 self.check_tempfile(name) 156 with warnings.catch_warnings(): 157 warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning, 158 r"test_os$") 159 warnings.filterwarnings("ignore", "tmpnam", DeprecationWarning) 160 161 name = os.tmpnam() 162 if sys.platform in ("win32",): 163 # The Windows tmpnam() seems useless. From the MS docs: 164 # 165 # The character string that tmpnam creates consists of 166 # the path prefix, defined by the entry P_tmpdir in the 167 # file STDIO.H, followed by a sequence consisting of the 168 # digit characters '0' through '9'; the numerical value 169 # of this string is in the range 1 - 65,535. Changing the 170 # definitions of L_tmpnam or P_tmpdir in STDIO.H does not 171 # change the operation of tmpnam. 172 # 173 # The really bizarre part is that, at least under MSVC6, 174 # P_tmpdir is "\\". That is, the path returned refers to 175 # the root of the current drive. That's a terrible place to 176 # put temp files, and, depending on privileges, the user 177 # may not even be able to open a file in the root directory. 178 self.assertFalse(os.path.exists(name), 179 "file already exists for temporary file") 180 else: 181 self.check_tempfile(name) 165 182 166 183 # Test attributes on return values from os.*stat* family. … … 185 202 186 203 # Make sure direct access works 187 self.assertEquals(result[stat.ST_SIZE], 3) 188 self.assertEquals(result.st_size, 3) 189 190 import sys 204 self.assertEqual(result[stat.ST_SIZE], 3) 205 self.assertEqual(result.st_size, 3) 191 206 192 207 # Make sure all the attributes are there … … 199 214 else: 200 215 def trunc(x): return x 201 self.assertEqual s(trunc(getattr(result, attr)),202 203 self.assert _(attr inmembers)216 self.assertEqual(trunc(getattr(result, attr)), 217 result[getattr(stat, name)]) 218 self.assertIn(attr, members) 204 219 205 220 try: 206 221 result[200] 207 self.fail("No exception thrown")222 self.fail("No exception raised") 208 223 except IndexError: 209 224 pass … … 212 227 try: 213 228 result.st_mode = 1 214 self.fail("No exception thrown") 229 self.fail("No exception raised") 230 except (AttributeError, TypeError): 231 pass 232 233 try: 234 result.st_rdev = 1 235 self.fail("No exception raised") 236 except (AttributeError, TypeError): 237 pass 238 239 try: 240 result.parrot = 1 241 self.fail("No exception raised") 242 except AttributeError: 243 pass 244 245 # Use the stat_result constructor with a too-short tuple. 246 try: 247 result2 = os.stat_result((10,)) 248 self.fail("No exception raised") 215 249 except TypeError: 216 250 pass 217 251 218 try: 219 result.st_rdev = 1 220 self.fail("No exception thrown") 221 except (AttributeError, TypeError): 222 pass 223 224 try: 225 result.parrot = 1 226 self.fail("No exception thrown") 227 except AttributeError: 228 pass 229 230 # Use the stat_result constructor with a too-short tuple. 231 try: 232 result2 = os.stat_result((10,)) 233 self.fail("No exception thrown") 234 except TypeError: 235 pass 236 237 # Use the constructr with a too-long tuple. 252 # Use the constructor with a too-long tuple. 238 253 try: 239 254 result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) … … 250 265 except OSError, e: 251 266 # On AtheOS, glibc always returns ENOSYS 252 import errno253 267 if e.errno == errno.ENOSYS: 254 268 return 255 269 256 270 # Make sure direct access works 257 self.assertEqual s(result.f_bfree, result[3])271 self.assertEqual(result.f_bfree, result[3]) 258 272 259 273 # Make sure all the attributes are there. … … 261 275 'ffree', 'favail', 'flag', 'namemax') 262 276 for value, member in enumerate(members): 263 self.assertEqual s(getattr(result, 'f_' + member), result[value])277 self.assertEqual(getattr(result, 'f_' + member), result[value]) 264 278 265 279 # Make sure that assignment really fails 266 280 try: 267 281 result.f_bfree = 1 268 self.fail("No exception thrown")282 self.fail("No exception raised") 269 283 except TypeError: 270 284 pass … … 272 286 try: 273 287 result.parrot = 1 274 self.fail("No exception thrown")288 self.fail("No exception raised") 275 289 except AttributeError: 276 290 pass … … 279 293 try: 280 294 result2 = os.statvfs_result((10,)) 281 self.fail("No exception thrown")295 self.fail("No exception raised") 282 296 except TypeError: 283 297 pass 284 298 285 # Use the construct r with a too-long tuple.299 # Use the constructor with a too-long tuple. 286 300 try: 287 301 result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) … … 296 310 os.utime(test_support.TESTFN, (st.st_atime, int(st.st_mtime-delta))) 297 311 st2 = os.stat(test_support.TESTFN) 298 self.assertEqual s(st2.st_mtime, int(st.st_mtime-delta))312 self.assertEqual(st2.st_mtime, int(st.st_mtime-delta)) 299 313 300 314 # Restrict test to Win32, since there is no guarantee other … … 313 327 t1 = 1159195039.25 314 328 os.utime(self.fname, (t1, t1)) 315 self.assertEquals(os.stat(self.fname).st_mtime, t1) 329 self.assertEqual(os.stat(self.fname).st_mtime, t1) 330 331 def test_large_time(self): 332 t1 = 5000000000 # some day in 2128 333 os.utime(self.fname, (t1, t1)) 334 self.assertEqual(os.stat(self.fname).st_mtime, t1) 316 335 317 336 def test_1686475(self): … … 345 364 if os.path.exists("/bin/sh"): 346 365 os.environ.update(HELLO="World") 347 value = os.popen("/bin/sh -c 'echo $HELLO'").read().strip() 348 self.assertEquals(value, "World") 366 with os.popen("/bin/sh -c 'echo $HELLO'") as popen: 367 value = popen.read().strip() 368 self.assertEqual(value, "World") 369 370 # On FreeBSD < 7 and OS X < 10.6, unsetenv() doesn't return a value (issue 371 # #13415). 372 @unittest.skipIf(sys.platform.startswith(('freebsd', 'darwin')), 373 "due to known OS bug: see issue #13415") 374 def test_unset_error(self): 375 if sys.platform == "win32": 376 # an environment variable is limited to 32,767 characters 377 key = 'x' * 50000 378 self.assertRaises(ValueError, os.environ.__delitem__, key) 379 else: 380 # "=" is not allowed in a variable name 381 key = 'key=' 382 self.assertRaises(OSError, os.environ.__delitem__, key) 349 383 350 384 class WalkTests(unittest.TestCase): … … 468 502 469 503 # Try paths with a '.' in them 470 self. failUnlessRaises(OSError, os.makedirs, os.curdir)504 self.assertRaises(OSError, os.makedirs, os.curdir) 471 505 path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir) 472 506 os.makedirs(path) … … 499 533 500 534 class URandomTests (unittest.TestCase): 501 def test_urandom(self): 502 try: 503 self.assertEqual(len(os.urandom(1)), 1) 504 self.assertEqual(len(os.urandom(10)), 10) 505 self.assertEqual(len(os.urandom(100)), 100) 506 self.assertEqual(len(os.urandom(1000)), 1000) 507 # see http://bugs.python.org/issue3708 508 self.assertEqual(len(os.urandom(0.9)), 0) 509 self.assertEqual(len(os.urandom(1.1)), 1) 510 self.assertEqual(len(os.urandom(2.0)), 2) 511 except NotImplementedError: 512 pass 535 536 def test_urandom_length(self): 537 self.assertEqual(len(os.urandom(0)), 0) 538 self.assertEqual(len(os.urandom(1)), 1) 539 self.assertEqual(len(os.urandom(10)), 10) 540 self.assertEqual(len(os.urandom(100)), 100) 541 self.assertEqual(len(os.urandom(1000)), 1000) 542 543 def test_urandom_value(self): 544 data1 = os.urandom(16) 545 data2 = os.urandom(16) 546 self.assertNotEqual(data1, data2) 547 548 def get_urandom_subprocess(self, count): 549 # We need to use repr() and eval() to avoid line ending conversions 550 # under Windows. 551 code = '\n'.join(( 552 'import os, sys', 553 'data = os.urandom(%s)' % count, 554 'sys.stdout.write(repr(data))', 555 'sys.stdout.flush()', 556 'print >> sys.stderr, (len(data), data)')) 557 cmd_line = [sys.executable, '-c', code] 558 p = subprocess.Popen(cmd_line, stdin=subprocess.PIPE, 559 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 560 out, err = p.communicate() 561 self.assertEqual(p.wait(), 0, (p.wait(), err)) 562 out = eval(out) 563 self.assertEqual(len(out), count, err) 564 return out 565 566 def test_urandom_subprocess(self): 567 data1 = self.get_urandom_subprocess(16) 568 data2 = self.get_urandom_subprocess(16) 569 self.assertNotEqual(data1, data2) 570 571 @unittest.skipUnless(resource, "test requires the resource module") 572 def test_urandom_failure(self): 573 # Check urandom() failing when it is not able to open /dev/random. 574 # We spawn a new process to make the test more robust (if getrlimit() 575 # failed to restore the file descriptor limit after this, the whole 576 # test suite would crash; this actually happened on the OS X Tiger 577 # buildbot). 578 code = """if 1: 579 import errno 580 import os 581 import resource 582 583 soft_limit, hard_limit = resource.getrlimit(resource.RLIMIT_NOFILE) 584 resource.setrlimit(resource.RLIMIT_NOFILE, (1, hard_limit)) 585 try: 586 os.urandom(16) 587 except OSError as e: 588 assert e.errno == errno.EMFILE, e.errno 589 else: 590 raise AssertionError("OSError not raised") 591 """ 592 assert_python_ok('-c', code) 593 594 595 class ExecvpeTests(unittest.TestCase): 596 597 def test_execvpe_with_bad_arglist(self): 598 self.assertRaises(ValueError, os.execvpe, 'notepad', [], None) 599 513 600 514 601 class Win32ErrorTests(unittest.TestCase): … … 523 610 524 611 def test_mkdir(self): 525 self.assertRaises(WindowsError, os.chdir, test_support.TESTFN) 612 f = open(test_support.TESTFN, "w") 613 try: 614 self.assertRaises(WindowsError, os.mkdir, test_support.TESTFN) 615 finally: 616 f.close() 617 os.unlink(test_support.TESTFN) 526 618 527 619 def test_utime(self): 528 620 self.assertRaises(WindowsError, os.utime, test_support.TESTFN, None) 529 621 530 def test_access(self):531 self.assertRaises(WindowsError, os.utime, test_support.TESTFN, 0)532 533 622 def test_chmod(self): 534 self.assertRaises(WindowsError, os. utime, test_support.TESTFN, 0)623 self.assertRaises(WindowsError, os.chmod, test_support.TESTFN, 0) 535 624 536 625 class TestInvalidFD(unittest.TestCase): … … 548 637 549 638 def check(self, f, *args): 550 self.assertRaises(OSError, f, test_support.make_bad_fd(), *args) 639 try: 640 f(test_support.make_bad_fd(), *args) 641 except OSError as e: 642 self.assertEqual(e.errno, errno.EBADF) 643 else: 644 self.fail("%r didn't raise a OSError with a bad file descriptor" 645 % f) 551 646 552 647 def test_isatty(self): … … 566 661 break 567 662 if i < 2: 568 # Unable to acquire a range of invalid file descriptors, 569 # so skip the test (in 2.6+ this is a unittest.SkipTest). 570 return 663 raise unittest.SkipTest( 664 "Unable to acquire a range of invalid file descriptors") 571 665 self.assertEqual(os.closerange(fd, fd + i-1), None) 572 666 … … 587 681 self.check(os.fpathconf, "PC_NAME_MAX") 588 682 589 #this is a weird one, it raises IOError unlike the others590 683 def test_ftruncate(self): 591 684 if hasattr(os, "ftruncate"): 592 self.assertRaises(IOError, os.ftruncate, test_support.make_bad_fd(), 593 0) 685 self.check(os.ftruncate, 0) 594 686 595 687 def test_lseek(self): … … 648 740 # Needs to accept -1. We run this in a subprocess to avoid 649 741 # altering the test runner's process state (issue8045). 650 import subprocess651 742 subprocess.check_call([ 652 743 sys.executable, '-c', … … 663 754 # Needs to accept -1. We run this in a subprocess to avoid 664 755 # altering the test runner's process state (issue8045). 665 import subprocess666 756 subprocess.check_call([ 667 757 sys.executable, '-c', … … 670 760 class PosixUidGidTests(unittest.TestCase): 671 761 pass 762 763 @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") 764 class Win32KillTests(unittest.TestCase): 765 def _kill(self, sig): 766 # Start sys.executable as a subprocess and communicate from the 767 # subprocess to the parent that the interpreter is ready. When it 768 # becomes ready, send *sig* via os.kill to the subprocess and check 769 # that the return code is equal to *sig*. 770 import ctypes 771 from ctypes import wintypes 772 import msvcrt 773 774 # Since we can't access the contents of the process' stdout until the 775 # process has exited, use PeekNamedPipe to see what's inside stdout 776 # without waiting. This is done so we can tell that the interpreter 777 # is started and running at a point where it could handle a signal. 778 PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe 779 PeekNamedPipe.restype = wintypes.BOOL 780 PeekNamedPipe.argtypes = (wintypes.HANDLE, # Pipe handle 781 ctypes.POINTER(ctypes.c_char), # stdout buf 782 wintypes.DWORD, # Buffer size 783 ctypes.POINTER(wintypes.DWORD), # bytes read 784 ctypes.POINTER(wintypes.DWORD), # bytes avail 785 ctypes.POINTER(wintypes.DWORD)) # bytes left 786 msg = "running" 787 proc = subprocess.Popen([sys.executable, "-c", 788 "import sys;" 789 "sys.stdout.write('{}');" 790 "sys.stdout.flush();" 791 "input()".format(msg)], 792 stdout=subprocess.PIPE, 793 stderr=subprocess.PIPE, 794 stdin=subprocess.PIPE) 795 self.addCleanup(proc.stdout.close) 796 self.addCleanup(proc.stderr.close) 797 self.addCleanup(proc.stdin.close) 798 799 count, max = 0, 100 800 while count < max and proc.poll() is None: 801 # Create a string buffer to store the result of stdout from the pipe 802 buf = ctypes.create_string_buffer(len(msg)) 803 # Obtain the text currently in proc.stdout 804 # Bytes read/avail/left are left as NULL and unused 805 rslt = PeekNamedPipe(msvcrt.get_osfhandle(proc.stdout.fileno()), 806 buf, ctypes.sizeof(buf), None, None, None) 807 self.assertNotEqual(rslt, 0, "PeekNamedPipe failed") 808 if buf.value: 809 self.assertEqual(msg, buf.value) 810 break 811 time.sleep(0.1) 812 count += 1 813 else: 814 self.fail("Did not receive communication from the subprocess") 815 816 os.kill(proc.pid, sig) 817 self.assertEqual(proc.wait(), sig) 818 819 def test_kill_sigterm(self): 820 # SIGTERM doesn't mean anything special, but make sure it works 821 self._kill(signal.SIGTERM) 822 823 def test_kill_int(self): 824 # os.kill on Windows can take an int which gets set as the exit code 825 self._kill(100) 826 827 def _kill_with_event(self, event, name): 828 tagname = "test_os_%s" % uuid.uuid1() 829 m = mmap.mmap(-1, 1, tagname) 830 m[0] = '0' 831 # Run a script which has console control handling enabled. 832 proc = subprocess.Popen([sys.executable, 833 os.path.join(os.path.dirname(__file__), 834 "win_console_handler.py"), tagname], 835 creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) 836 # Let the interpreter startup before we send signals. See #3137. 837 count, max = 0, 20 838 while count < max and proc.poll() is None: 839 if m[0] == '1': 840 break 841 time.sleep(0.5) 842 count += 1 843 else: 844 self.fail("Subprocess didn't finish initialization") 845 os.kill(proc.pid, event) 846 # proc.send_signal(event) could also be done here. 847 # Allow time for the signal to be passed and the process to exit. 848 time.sleep(0.5) 849 if not proc.poll(): 850 # Forcefully kill the process if we weren't able to signal it. 851 os.kill(proc.pid, signal.SIGINT) 852 self.fail("subprocess did not stop on {}".format(name)) 853 854 @unittest.skip("subprocesses aren't inheriting CTRL+C property") 855 def test_CTRL_C_EVENT(self): 856 from ctypes import wintypes 857 import ctypes 858 859 # Make a NULL value by creating a pointer with no argument. 860 NULL = ctypes.POINTER(ctypes.c_int)() 861 SetConsoleCtrlHandler = ctypes.windll.kernel32.SetConsoleCtrlHandler 862 SetConsoleCtrlHandler.argtypes = (ctypes.POINTER(ctypes.c_int), 863 wintypes.BOOL) 864 SetConsoleCtrlHandler.restype = wintypes.BOOL 865 866 # Calling this with NULL and FALSE causes the calling process to 867 # handle CTRL+C, rather than ignore it. This property is inherited 868 # by subprocesses. 869 SetConsoleCtrlHandler(NULL, 0) 870 871 self._kill_with_event(signal.CTRL_C_EVENT, "CTRL_C_EVENT") 872 873 def test_CTRL_BREAK_EVENT(self): 874 self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT") 875 672 876 673 877 def test_main(): … … 681 885 DevNullTests, 682 886 URandomTests, 887 ExecvpeTests, 683 888 Win32ErrorTests, 684 889 TestInvalidFD, 685 PosixUidGidTests 890 PosixUidGidTests, 891 Win32KillTests 686 892 ) 687 893
Note:
See TracChangeset
for help on using the changeset viewer.