0001 # tempfile.py unit tests. 0002 0003 import tempfile 0004 import os 0005 import sys 0006 import re 0007 import errno 0008 import warnings 0009 0010 import unittest 0011 from test import test_support 0012 0013 warnings.filterwarnings("ignore", 0014 category=RuntimeWarning, 0015 message="mktemp", module=__name__) 0016 0017 if hasattr(os, 'stat'): 0018 import stat 0019 has_stat = 1 0020 else: 0021 has_stat = 0 0022 0023 has_textmode = (tempfile._text_openflags != tempfile._bin_openflags) 0024 has_spawnl = hasattr(os, 'spawnl') 0025 0026 # TEST_FILES may need to be tweaked for systems depending on the maximum 0027 # number of files that can be opened at one time (see ulimit -n) 0028 if sys.platform == 'mac': 0029 TEST_FILES = 32 0030 elif sys.platform == 'openbsd3': 0031 TEST_FILES = 48 0032 else: 0033 TEST_FILES = 100 0034 0035 # This is organized as one test for each chunk of code in tempfile.py, 0036 # in order of their appearance in the file. Testing which requires 0037 # threads is not done here. 0038 0039 # Common functionality. 0040 class TC(unittest.TestCase): 0041 0042 str_check = re.compile(r"[a-zA-Z0-9_-]{6}$") 0043 0044 def failOnException(self, what, ei=None): 0045 if ei is None: 0046 ei = sys.exc_info() 0047 self.fail("%s raised %s: %s" % (what, ei[0], ei[1])) 0048 0049 def nameCheck(self, name, dir, pre, suf): 0050 (ndir, nbase) = os.path.split(name) 0051 npre = nbase[:len(pre)] 0052 nsuf = nbase[len(nbase)-len(suf):] 0053 0054 # check for equality of the absolute paths! 0055 self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir), 0056 "file '%s' not in directory '%s'" % (name, dir)) 0057 self.assertEqual(npre, pre, 0058 "file '%s' does not begin with '%s'" % (nbase, pre)) 0059 self.assertEqual(nsuf, suf, 0060 "file '%s' does not end with '%s'" % (nbase, suf)) 0061 0062 nbase = nbase[len(pre):len(nbase)-len(suf)] 0063 self.assert_(self.str_check.match(nbase), 0064 "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/" 0065 % nbase) 0066 0067 test_classes = [] 0068 0069 class test_exports(TC): 0070 def test_exports(self): 0071 # There are no surprising symbols in the tempfile module 0072 dict = tempfile.__dict__ 0073 0074 expected = { 0075 "NamedTemporaryFile" : 1, 0076 "TemporaryFile" : 1, 0077 "mkstemp" : 1, 0078 "mkdtemp" : 1, 0079 "mktemp" : 1, 0080 "TMP_MAX" : 1, 0081 "gettempprefix" : 1, 0082 "gettempdir" : 1, 0083 "tempdir" : 1, 0084 "template" : 1 0085 } 0086 0087 unexp = [] 0088 for key in dict: 0089 if key[0] != '_' and key not in expected: 0090 unexp.append(key) 0091 self.failUnless(len(unexp) == 0, 0092 "unexpected keys: %s" % unexp) 0093 0094 test_classes.append(test_exports) 0095 0096 0097 class test__RandomNameSequence(TC): 0098 """Test the internal iterator object _RandomNameSequence.""" 0099 0100 def setUp(self): 0101 self.r = tempfile._RandomNameSequence() 0102 0103 def test_get_six_char_str(self): 0104 # _RandomNameSequence returns a six-character string 0105 s = self.r.next() 0106 self.nameCheck(s, '', '', '') 0107 0108 def test_many(self): 0109 # _RandomNameSequence returns no duplicate strings (stochastic) 0110 0111 dict = {} 0112 r = self.r 0113 for i in xrange(TEST_FILES): 0114 s = r.next() 0115 self.nameCheck(s, '', '', '') 0116 self.failIf(s in dict) 0117 dict[s] = 1 0118 0119 def test_supports_iter(self): 0120 # _RandomNameSequence supports the iterator protocol 0121 0122 i = 0 0123 r = self.r 0124 try: 0125 for s in r: 0126 i += 1 0127 if i == 20: 0128 break 0129 except: 0130 failOnException("iteration") 0131 0132 test_classes.append(test__RandomNameSequence) 0133 0134 0135 class test__candidate_tempdir_list(TC): 0136 """Test the internal function _candidate_tempdir_list.""" 0137 0138 def test_nonempty_list(self): 0139 # _candidate_tempdir_list returns a nonempty list of strings 0140 0141 cand = tempfile._candidate_tempdir_list() 0142 0143 self.failIf(len(cand) == 0) 0144 for c in cand: 0145 self.assert_(isinstance(c, basestring), 0146 "%s is not a string" % c) 0147 0148 def test_wanted_dirs(self): 0149 # _candidate_tempdir_list contains the expected directories 0150 0151 # Make sure the interesting environment variables are all set. 0152 added = [] 0153 try: 0154 for envname in 'TMPDIR', 'TEMP', 'TMP': 0155 dirname = os.getenv(envname) 0156 if not dirname: 0157 os.environ[envname] = os.path.abspath(envname) 0158 added.append(envname) 0159 0160 cand = tempfile._candidate_tempdir_list() 0161 0162 for envname in 'TMPDIR', 'TEMP', 'TMP': 0163 dirname = os.getenv(envname) 0164 if not dirname: raise ValueError 0165 self.assert_(dirname in cand) 0166 0167 try: 0168 dirname = os.getcwd() 0169 except (AttributeError, os.error): 0170 dirname = os.curdir 0171 0172 self.assert_(dirname in cand) 0173 0174 # Not practical to try to verify the presence of OS-specific 0175 # paths in this list. 0176 finally: 0177 for p in added: 0178 del os.environ[p] 0179 0180 test_classes.append(test__candidate_tempdir_list) 0181 0182 0183 # We test _get_default_tempdir by testing gettempdir. 0184 0185 0186 class test__get_candidate_names(TC): 0187 """Test the internal function _get_candidate_names.""" 0188 0189 def test_retval(self): 0190 # _get_candidate_names returns a _RandomNameSequence object 0191 obj = tempfile._get_candidate_names() 0192 self.assert_(isinstance(obj, tempfile._RandomNameSequence)) 0193 0194 def test_same_thing(self): 0195 # _get_candidate_names always returns the same object 0196 a = tempfile._get_candidate_names() 0197 b = tempfile._get_candidate_names() 0198 0199 self.assert_(a is b) 0200 0201 test_classes.append(test__get_candidate_names) 0202 0203 0204 class test__mkstemp_inner(TC): 0205 """Test the internal function _mkstemp_inner.""" 0206 0207 class mkstemped: 0208 _bflags = tempfile._bin_openflags 0209 _tflags = tempfile._text_openflags 0210 _close = os.close 0211 _unlink = os.unlink 0212 0213 def __init__(self, dir, pre, suf, bin): 0214 if bin: flags = self._bflags 0215 else: flags = self._tflags 0216 0217 (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags) 0218 0219 def write(self, str): 0220 os.write(self.fd, str) 0221 0222 def __del__(self): 0223 self._close(self.fd) 0224 self._unlink(self.name) 0225 0226 def do_create(self, dir=None, pre="", suf="", bin=1): 0227 if dir is None: 0228 dir = tempfile.gettempdir() 0229 try: 0230 file = self.mkstemped(dir, pre, suf, bin) 0231 except: 0232 self.failOnException("_mkstemp_inner") 0233 0234 self.nameCheck(file.name, dir, pre, suf) 0235 return file 0236 0237 def test_basic(self): 0238 # _mkstemp_inner can create files 0239 self.do_create().write("blat") 0240 self.do_create(pre="a").write("blat") 0241 self.do_create(suf="b").write("blat") 0242 self.do_create(pre="a", suf="b").write("blat") 0243 self.do_create(pre="aa", suf=".txt").write("blat") 0244 0245 def test_basic_many(self): 0246 # _mkstemp_inner can create many files (stochastic) 0247 extant = range(TEST_FILES) 0248 for i in extant: 0249 extant[i] = self.do_create(pre="aa") 0250 0251 def test_choose_directory(self): 0252 # _mkstemp_inner can create files in a user-selected directory 0253 dir = tempfile.mkdtemp() 0254 try: 0255 self.do_create(dir=dir).write("blat") 0256 finally: 0257 os.rmdir(dir) 0258 0259 def test_file_mode(self): 0260 # _mkstemp_inner creates files with the proper mode 0261 if not has_stat: 0262 return # ugh, can't use TestSkipped. 0263 0264 file = self.do_create() 0265 mode = stat.S_IMODE(os.stat(file.name).st_mode) 0266 expected = 0600 0267 if sys.platform in ('win32', 'os2emx', 'mac'): 0268 # There's no distinction among 'user', 'group' and 'world'; 0269 # replicate the 'user' bits. 0270 user = expected >> 6 0271 expected = user * (1 + 8 + 64) 0272 self.assertEqual(mode, expected) 0273 0274 def test_noinherit(self): 0275 # _mkstemp_inner file handles are not inherited by child processes 0276 if not has_spawnl: 0277 return # ugh, can't use TestSkipped. 0278 0279 if test_support.verbose: 0280 v="v" 0281 else: 0282 v="q" 0283 0284 file = self.do_create() 0285 fd = "%d" % file.fd 0286 0287 try: 0288 me = __file__ 0289 except NameError: 0290 me = sys.argv[0] 0291 0292 # We have to exec something, so that FD_CLOEXEC will take 0293 # effect. The core of this test is therefore in 0294 # tf_inherit_check.py, which see. 0295 tester = os.path.join(os.path.dirname(os.path.abspath(me)), 0296 "tf_inherit_check.py") 0297 0298 # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted, 0299 # but an arg with embedded spaces should be decorated with double 0300 # quotes on each end 0301 if sys.platform in ('win32'): 0302 decorated = '"%s"' % sys.executable 0303 tester = '"%s"' % tester 0304 else: 0305 decorated = sys.executable 0306 0307 retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd) 0308 self.failIf(retval < 0, 0309 "child process caught fatal signal %d" % -retval) 0310 self.failIf(retval > 0, "child process reports failure") 0311 0312 def test_textmode(self): 0313 # _mkstemp_inner can create files in text mode 0314 if not has_textmode: 0315 return # ugh, can't use TestSkipped. 0316 0317 self.do_create(bin=0).write("blat\n") 0318 # XXX should test that the file really is a text file 0319 0320 test_classes.append(test__mkstemp_inner) 0321 0322 0323 class test_gettempprefix(TC): 0324 """Test gettempprefix().""" 0325 0326 def test_sane_template(self): 0327 # gettempprefix returns a nonempty prefix string 0328 p = tempfile.gettempprefix() 0329 0330 self.assert_(isinstance(p, basestring)) 0331 self.assert_(len(p) > 0) 0332 0333 def test_usable_template(self): 0334 # gettempprefix returns a usable prefix string 0335 0336 # Create a temp directory, avoiding use of the prefix. 0337 # Then attempt to create a file whose name is 0338 # prefix + 'xxxxxx.xxx' in that directory. 0339 p = tempfile.gettempprefix() + "xxxxxx.xxx" 0340 d = tempfile.mkdtemp(prefix="") 0341 try: 0342 p = os.path.join(d, p) 0343 try: 0344 fd = os.open(p, os.O_RDWR | os.O_CREAT) 0345 except: 0346 self.failOnException("os.open") 0347 os.close(fd) 0348 os.unlink(p) 0349 finally: 0350 os.rmdir(d) 0351 0352 test_classes.append(test_gettempprefix) 0353 0354 0355 class test_gettempdir(TC): 0356 """Test gettempdir().""" 0357 0358 def test_directory_exists(self): 0359 # gettempdir returns a directory which exists 0360 0361 dir = tempfile.gettempdir() 0362 self.assert_(os.path.isabs(dir) or dir == os.curdir, 0363 "%s is not an absolute path" % dir) 0364 self.assert_(os.path.isdir(dir), 0365 "%s is not a directory" % dir) 0366 0367 def test_directory_writable(self): 0368 # gettempdir returns a directory writable by the user 0369 0370 # sneaky: just instantiate a NamedTemporaryFile, which 0371 # defaults to writing into the directory returned by 0372 # gettempdir. 0373 try: 0374 file = tempfile.NamedTemporaryFile() 0375 file.write("blat") 0376 file.close() 0377 except: 0378 self.failOnException("create file in %s" % tempfile.gettempdir()) 0379 0380 def test_same_thing(self): 0381 # gettempdir always returns the same object 0382 a = tempfile.gettempdir() 0383 b = tempfile.gettempdir() 0384 0385 self.assert_(a is b) 0386 0387 test_classes.append(test_gettempdir) 0388 0389 0390 class test_mkstemp(TC): 0391 """Test mkstemp().""" 0392 0393 def do_create(self, dir=None, pre="", suf="", ): 0394 if dir is None: 0395 dir = tempfile.gettempdir() 0396 try: 0397 (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf) 0398 (ndir, nbase) = os.path.split(name) 0399 adir = os.path.abspath(dir) 0400 self.assertEqual(adir, ndir, 0401 "Directory '%s' incorrectly returned as '%s'" % (adir, ndir)) 0402 except: 0403 self.failOnException("mkstemp") 0404 0405 try: 0406 self.nameCheck(name, dir, pre, suf) 0407 finally: 0408 os.close(fd) 0409 os.unlink(name) 0410 0411 def test_basic(self): 0412 # mkstemp can create files 0413 self.do_create() 0414 self.do_create(pre="a") 0415 self.do_create(suf="b") 0416 self.do_create(pre="a", suf="b") 0417 self.do_create(pre="aa", suf=".txt") 0418 self.do_create(dir=".") 0419 0420 def test_choose_directory(self): 0421 # mkstemp can create directories in a user-selected directory 0422 dir = tempfile.mkdtemp() 0423 try: 0424 self.do_create(dir=dir) 0425 finally: 0426 os.rmdir(dir) 0427 0428 test_classes.append(test_mkstemp) 0429 0430 0431 class test_mkdtemp(TC): 0432 """Test mkdtemp().""" 0433 0434 def do_create(self, dir=None, pre="", suf=""): 0435 if dir is None: 0436 dir = tempfile.gettempdir() 0437 try: 0438 name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf) 0439 except: 0440 self.failOnException("mkdtemp") 0441 0442 try: 0443 self.nameCheck(name, dir, pre, suf) 0444 return name 0445 except: 0446 os.rmdir(name) 0447 raise 0448 0449 def test_basic(self): 0450 # mkdtemp can create directories 0451 os.rmdir(self.do_create()) 0452 os.rmdir(self.do_create(pre="a")) 0453 os.rmdir(self.do_create(suf="b")) 0454 os.rmdir(self.do_create(pre="a", suf="b")) 0455 os.rmdir(self.do_create(pre="aa", suf=".txt")) 0456 0457 def test_basic_many(self): 0458 # mkdtemp can create many directories (stochastic) 0459 extant = range(TEST_FILES) 0460 try: 0461 for i in extant: 0462 extant[i] = self.do_create(pre="aa") 0463 finally: 0464 for i in extant: 0465 if(isinstance(i, basestring)): 0466 os.rmdir(i) 0467 0468 def test_choose_directory(self): 0469 # mkdtemp can create directories in a user-selected directory 0470 dir = tempfile.mkdtemp() 0471 try: 0472 os.rmdir(self.do_create(dir=dir)) 0473 finally: 0474 os.rmdir(dir) 0475 0476 def test_mode(self): 0477 # mkdtemp creates directories with the proper mode 0478 if not has_stat: 0479 return # ugh, can't use TestSkipped. 0480 0481 dir = self.do_create() 0482 try: 0483 mode = stat.S_IMODE(os.stat(dir).st_mode) 0484 mode &= 0777 # Mask off sticky bits inherited from /tmp 0485 expected = 0700 0486 if sys.platform in ('win32', 'os2emx', 'mac'): 0487 # There's no distinction among 'user', 'group' and 'world'; 0488 # replicate the 'user' bits. 0489 user = expected >> 6 0490 expected = user * (1 + 8 + 64) 0491 self.assertEqual(mode, expected) 0492 finally: 0493 os.rmdir(dir) 0494 0495 test_classes.append(test_mkdtemp) 0496 0497 0498 class test_mktemp(TC): 0499 """Test mktemp().""" 0500 0501 # For safety, all use of mktemp must occur in a private directory. 0502 # We must also suppress the RuntimeWarning it generates. 0503 def setUp(self): 0504 self.dir = tempfile.mkdtemp() 0505 0506 def tearDown(self): 0507 if self.dir: 0508 os.rmdir(self.dir) 0509 self.dir = None 0510 0511 class mktemped: 0512 _unlink = os.unlink 0513 _bflags = tempfile._bin_openflags 0514 0515 def __init__(self, dir, pre, suf): 0516 self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf) 0517 # Create the file. This will raise an exception if it's 0518 # mysteriously appeared in the meanwhile. 0519 os.close(os.open(self.name, self._bflags, 0600)) 0520 0521 def __del__(self): 0522 self._unlink(self.name) 0523 0524 def do_create(self, pre="", suf=""): 0525 try: 0526 file = self.mktemped(self.dir, pre, suf) 0527 except: 0528 self.failOnException("mktemp") 0529 0530 self.nameCheck(file.name, self.dir, pre, suf) 0531 return file 0532 0533 def test_basic(self): 0534 # mktemp can choose usable file names 0535 self.do_create() 0536 self.do_create(pre="a") 0537 self.do_create(suf="b") 0538 self.do_create(pre="a", suf="b") 0539 self.do_create(pre="aa", suf=".txt") 0540 0541 def test_many(self): 0542 # mktemp can choose many usable file names (stochastic) 0543 extant = range(TEST_FILES) 0544 for i in extant: 0545 extant[i] = self.do_create(pre="aa") 0546 0547 ## def test_warning(self): 0548 ## # mktemp issues a warning when used 0549 ## warnings.filterwarnings("error", 0550 ## category=RuntimeWarning, 0551 ## message="mktemp") 0552 ## self.assertRaises(RuntimeWarning, 0553 ## tempfile.mktemp, dir=self.dir) 0554 0555 test_classes.append(test_mktemp) 0556 0557 0558 # We test _TemporaryFileWrapper by testing NamedTemporaryFile. 0559 0560 0561 class test_NamedTemporaryFile(TC): 0562 """Test NamedTemporaryFile().""" 0563 0564 def do_create(self, dir=None, pre="", suf=""): 0565 if dir is None: 0566 dir = tempfile.gettempdir() 0567 try: 0568 file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf) 0569 except: 0570 self.failOnException("NamedTemporaryFile") 0571 0572 self.nameCheck(file.name, dir, pre, suf) 0573 return file 0574 0575 0576 def test_basic(self): 0577 # NamedTemporaryFile can create files 0578 self.do_create() 0579 self.do_create(pre="a") 0580 self.do_create(suf="b") 0581 self.do_create(pre="a", suf="b") 0582 self.do_create(pre="aa", suf=".txt") 0583 0584 def test_creates_named(self): 0585 # NamedTemporaryFile creates files with names 0586 f = tempfile.NamedTemporaryFile() 0587 self.failUnless(os.path.exists(f.name), 0588 "NamedTemporaryFile %s does not exist" % f.name) 0589 0590 def test_del_on_close(self): 0591 # A NamedTemporaryFile is deleted when closed 0592 dir = tempfile.mkdtemp() 0593 try: 0594 f = tempfile.NamedTemporaryFile(dir=dir) 0595 f.write('blat') 0596 f.close() 0597 self.failIf(os.path.exists(f.name), 0598 "NamedTemporaryFile %s exists after close" % f.name) 0599 finally: 0600 os.rmdir(dir) 0601 0602 def test_multiple_close(self): 0603 # A NamedTemporaryFile can be closed many times without error 0604 0605 f = tempfile.NamedTemporaryFile() 0606 f.write('abc\n') 0607 f.close() 0608 try: 0609 f.close() 0610 f.close() 0611 except: 0612 self.failOnException("close") 0613 0614 # How to test the mode and bufsize parameters? 0615 0616 test_classes.append(test_NamedTemporaryFile) 0617 0618 0619 class test_TemporaryFile(TC): 0620 """Test TemporaryFile().""" 0621 0622 def test_basic(self): 0623 # TemporaryFile can create files 0624 # No point in testing the name params - the file has no name. 0625 try: 0626 tempfile.TemporaryFile() 0627 except: 0628 self.failOnException("TemporaryFile") 0629 0630 def test_has_no_name(self): 0631 # TemporaryFile creates files with no names (on this system) 0632 dir = tempfile.mkdtemp() 0633 f = tempfile.TemporaryFile(dir=dir) 0634 f.write('blat') 0635 0636 # Sneaky: because this file has no name, it should not prevent 0637 # us from removing the directory it was created in. 0638 try: 0639 os.rmdir(dir) 0640 except: 0641 ei = sys.exc_info() 0642 # cleanup 0643 f.close() 0644 os.rmdir(dir) 0645 self.failOnException("rmdir", ei) 0646 0647 def test_multiple_close(self): 0648 # A TemporaryFile can be closed many times without error 0649 f = tempfile.TemporaryFile() 0650 f.write('abc\n') 0651 f.close() 0652 try: 0653 f.close() 0654 f.close() 0655 except: 0656 self.failOnException("close") 0657 0658 # How to test the mode and bufsize parameters? 0659 0660 0661 if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile: 0662 test_classes.append(test_TemporaryFile) 0663 0664 def test_main(): 0665 test_support.run_unittest(*test_classes) 0666 0667 if __name__ == "__main__": 0668 test_main() 0669
Generated by PyXR 0.9.4