1 # tempfile.py unit tests.
11 from test
import test_support
13 warnings
.filterwarnings("ignore",
14 category
=RuntimeWarning,
15 message
="mktemp", module
=__name__
)
17 if hasattr(os
, 'stat'):
23 has_textmode
= (tempfile
._text
_openflags
!= tempfile
._bin
_openflags
)
24 has_spawnl
= hasattr(os
, 'spawnl')
26 # TEST_FILES may need to be tweaked for systems depending on the maximum
27 # number of files that can be opened at one time (see ulimit -n)
28 if sys
.platform
== 'mac':
30 elif sys
.platform
== 'openbsd3':
35 # This is organized as one test for each chunk of code in tempfile.py,
36 # in order of their appearance in the file. Testing which requires
37 # threads is not done here.
39 # Common functionality.
40 class TC(unittest
.TestCase
):
42 str_check
= re
.compile(r
"[a-zA-Z0-9_-]{6}$")
44 def failOnException(self
, what
, ei
=None):
47 self
.fail("%s raised %s: %s" % (what
, ei
[0], ei
[1]))
49 def nameCheck(self
, name
, dir, pre
, suf
):
50 (ndir
, nbase
) = os
.path
.split(name
)
51 npre
= nbase
[:len(pre
)]
52 nsuf
= nbase
[len(nbase
)-len(suf
):]
54 # check for equality of the absolute paths!
55 self
.assertEqual(os
.path
.abspath(ndir
), os
.path
.abspath(dir),
56 "file '%s' not in directory '%s'" % (name
, dir))
57 self
.assertEqual(npre
, pre
,
58 "file '%s' does not begin with '%s'" % (nbase
, pre
))
59 self
.assertEqual(nsuf
, suf
,
60 "file '%s' does not end with '%s'" % (nbase
, suf
))
62 nbase
= nbase
[len(pre
):len(nbase
)-len(suf
)]
63 self
.assert_(self
.str_check
.match(nbase
),
64 "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/"
69 class test_exports(TC
):
70 def test_exports(self
):
71 # There are no surprising symbols in the tempfile module
72 dict = tempfile
.__dict
__
75 "NamedTemporaryFile" : 1,
89 if key
[0] != '_' and key
not in expected
:
91 self
.failUnless(len(unexp
) == 0,
92 "unexpected keys: %s" % unexp
)
94 test_classes
.append(test_exports
)
97 class test__RandomNameSequence(TC
):
98 """Test the internal iterator object _RandomNameSequence."""
101 self
.r
= tempfile
._RandomNameSequence
()
103 def test_get_six_char_str(self
):
104 # _RandomNameSequence returns a six-character string
106 self
.nameCheck(s
, '', '', '')
109 # _RandomNameSequence returns no duplicate strings (stochastic)
113 for i
in xrange(TEST_FILES
):
115 self
.nameCheck(s
, '', '', '')
116 self
.failIf(s
in dict)
119 def test_supports_iter(self
):
120 # _RandomNameSequence supports the iterator protocol
130 failOnException("iteration")
132 test_classes
.append(test__RandomNameSequence
)
135 class test__candidate_tempdir_list(TC
):
136 """Test the internal function _candidate_tempdir_list."""
138 def test_nonempty_list(self
):
139 # _candidate_tempdir_list returns a nonempty list of strings
141 cand
= tempfile
._candidate
_tempdir
_list
()
143 self
.failIf(len(cand
) == 0)
145 self
.assert_(isinstance(c
, basestring
),
146 "%s is not a string" % c
)
148 def test_wanted_dirs(self
):
149 # _candidate_tempdir_list contains the expected directories
151 # Make sure the interesting environment variables are all set.
154 for envname
in 'TMPDIR', 'TEMP', 'TMP':
155 dirname
= os
.getenv(envname
)
157 os
.environ
[envname
] = os
.path
.abspath(envname
)
158 added
.append(envname
)
160 cand
= tempfile
._candidate
_tempdir
_list
()
162 for envname
in 'TMPDIR', 'TEMP', 'TMP':
163 dirname
= os
.getenv(envname
)
164 if not dirname
: raise ValueError
165 self
.assert_(dirname
in cand
)
168 dirname
= os
.getcwd()
169 except (AttributeError, os
.error
):
172 self
.assert_(dirname
in cand
)
174 # Not practical to try to verify the presence of OS-specific
175 # paths in this list.
180 test_classes
.append(test__candidate_tempdir_list
)
183 # We test _get_default_tempdir by testing gettempdir.
186 class test__get_candidate_names(TC
):
187 """Test the internal function _get_candidate_names."""
189 def test_retval(self
):
190 # _get_candidate_names returns a _RandomNameSequence object
191 obj
= tempfile
._get
_candidate
_names
()
192 self
.assert_(isinstance(obj
, tempfile
._RandomNameSequence
))
194 def test_same_thing(self
):
195 # _get_candidate_names always returns the same object
196 a
= tempfile
._get
_candidate
_names
()
197 b
= tempfile
._get
_candidate
_names
()
201 test_classes
.append(test__get_candidate_names
)
204 class test__mkstemp_inner(TC
):
205 """Test the internal function _mkstemp_inner."""
208 _bflags
= tempfile
._bin
_openflags
209 _tflags
= tempfile
._text
_openflags
213 def __init__(self
, dir, pre
, suf
, bin
):
214 if bin
: flags
= self
._bflags
215 else: flags
= self
._tflags
217 (self
.fd
, self
.name
) = tempfile
._mkstemp
_inner
(dir, pre
, suf
, flags
)
219 def write(self
, str):
220 os
.write(self
.fd
, str)
224 self
._unlink
(self
.name
)
226 def do_create(self
, dir=None, pre
="", suf
="", bin
=1):
228 dir = tempfile
.gettempdir()
230 file = self
.mkstemped(dir, pre
, suf
, bin
)
232 self
.failOnException("_mkstemp_inner")
234 self
.nameCheck(file.name
, dir, pre
, suf
)
237 def test_basic(self
):
238 # _mkstemp_inner can create files
239 self
.do_create().write("blat")
240 self
.do_create(pre
="a").write("blat")
241 self
.do_create(suf
="b").write("blat")
242 self
.do_create(pre
="a", suf
="b").write("blat")
243 self
.do_create(pre
="aa", suf
=".txt").write("blat")
245 def test_basic_many(self
):
246 # _mkstemp_inner can create many files (stochastic)
247 extant
= range(TEST_FILES
)
249 extant
[i
] = self
.do_create(pre
="aa")
251 def test_choose_directory(self
):
252 # _mkstemp_inner can create files in a user-selected directory
253 dir = tempfile
.mkdtemp()
255 self
.do_create(dir=dir).write("blat")
259 def test_file_mode(self
):
260 # _mkstemp_inner creates files with the proper mode
262 return # ugh, can't use TestSkipped.
264 file = self
.do_create()
265 mode
= stat
.S_IMODE(os
.stat(file.name
).st_mode
)
267 if sys
.platform
in ('win32', 'os2emx', 'mac'):
268 # There's no distinction among 'user', 'group' and 'world';
269 # replicate the 'user' bits.
271 expected
= user
* (1 + 8 + 64)
272 self
.assertEqual(mode
, expected
)
274 def test_noinherit(self
):
275 # _mkstemp_inner file handles are not inherited by child processes
277 return # ugh, can't use TestSkipped.
279 if test_support
.verbose
:
284 file = self
.do_create()
292 # We have to exec something, so that FD_CLOEXEC will take
293 # effect. The core of this test is therefore in
294 # tf_inherit_check.py, which see.
295 tester
= os
.path
.join(os
.path
.dirname(os
.path
.abspath(me
)),
296 "tf_inherit_check.py")
298 # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted,
299 # but an arg with embedded spaces should be decorated with double
301 if sys
.platform
in ('win32'):
302 decorated
= '"%s"' % sys
.executable
303 tester
= '"%s"' % tester
305 decorated
= sys
.executable
307 retval
= os
.spawnl(os
.P_WAIT
, sys
.executable
, decorated
, tester
, v
, fd
)
308 self
.failIf(retval
< 0,
309 "child process caught fatal signal %d" % -retval
)
310 self
.failIf(retval
> 0, "child process reports failure %d"%retval
)
312 def test_textmode(self
):
313 # _mkstemp_inner can create files in text mode
315 return # ugh, can't use TestSkipped.
317 self
.do_create(bin
=0).write("blat\n")
318 # XXX should test that the file really is a text file
320 test_classes
.append(test__mkstemp_inner
)
323 class test_gettempprefix(TC
):
324 """Test gettempprefix()."""
326 def test_sane_template(self
):
327 # gettempprefix returns a nonempty prefix string
328 p
= tempfile
.gettempprefix()
330 self
.assert_(isinstance(p
, basestring
))
331 self
.assert_(len(p
) > 0)
333 def test_usable_template(self
):
334 # gettempprefix returns a usable prefix string
336 # Create a temp directory, avoiding use of the prefix.
337 # Then attempt to create a file whose name is
338 # prefix + 'xxxxxx.xxx' in that directory.
339 p
= tempfile
.gettempprefix() + "xxxxxx.xxx"
340 d
= tempfile
.mkdtemp(prefix
="")
342 p
= os
.path
.join(d
, p
)
344 fd
= os
.open(p
, os
.O_RDWR | os
.O_CREAT
)
346 self
.failOnException("os.open")
352 test_classes
.append(test_gettempprefix
)
355 class test_gettempdir(TC
):
356 """Test gettempdir()."""
358 def test_directory_exists(self
):
359 # gettempdir returns a directory which exists
361 dir = tempfile
.gettempdir()
362 self
.assert_(os
.path
.isabs(dir) or dir == os
.curdir
,
363 "%s is not an absolute path" % dir)
364 self
.assert_(os
.path
.isdir(dir),
365 "%s is not a directory" % dir)
367 def test_directory_writable(self
):
368 # gettempdir returns a directory writable by the user
370 # sneaky: just instantiate a NamedTemporaryFile, which
371 # defaults to writing into the directory returned by
374 file = tempfile
.NamedTemporaryFile()
378 self
.failOnException("create file in %s" % tempfile
.gettempdir())
380 def test_same_thing(self
):
381 # gettempdir always returns the same object
382 a
= tempfile
.gettempdir()
383 b
= tempfile
.gettempdir()
387 test_classes
.append(test_gettempdir
)
390 class test_mkstemp(TC
):
391 """Test mkstemp()."""
393 def do_create(self
, dir=None, pre
="", suf
="", ):
395 dir = tempfile
.gettempdir()
397 (fd
, name
) = tempfile
.mkstemp(dir=dir, prefix
=pre
, suffix
=suf
)
398 (ndir
, nbase
) = os
.path
.split(name
)
399 adir
= os
.path
.abspath(dir)
400 self
.assertEqual(adir
, ndir
,
401 "Directory '%s' incorrectly returned as '%s'" % (adir
, ndir
))
403 self
.failOnException("mkstemp")
406 self
.nameCheck(name
, dir, pre
, suf
)
411 def test_basic(self
):
412 # mkstemp can create files
414 self
.do_create(pre
="a")
415 self
.do_create(suf
="b")
416 self
.do_create(pre
="a", suf
="b")
417 self
.do_create(pre
="aa", suf
=".txt")
418 self
.do_create(dir=".")
420 def test_choose_directory(self
):
421 # mkstemp can create directories in a user-selected directory
422 dir = tempfile
.mkdtemp()
424 self
.do_create(dir=dir)
428 test_classes
.append(test_mkstemp
)
431 class test_mkdtemp(TC
):
432 """Test mkdtemp()."""
434 def do_create(self
, dir=None, pre
="", suf
=""):
436 dir = tempfile
.gettempdir()
438 name
= tempfile
.mkdtemp(dir=dir, prefix
=pre
, suffix
=suf
)
440 self
.failOnException("mkdtemp")
443 self
.nameCheck(name
, dir, pre
, suf
)
449 def test_basic(self
):
450 # mkdtemp can create directories
451 os
.rmdir(self
.do_create())
452 os
.rmdir(self
.do_create(pre
="a"))
453 os
.rmdir(self
.do_create(suf
="b"))
454 os
.rmdir(self
.do_create(pre
="a", suf
="b"))
455 os
.rmdir(self
.do_create(pre
="aa", suf
=".txt"))
457 def test_basic_many(self
):
458 # mkdtemp can create many directories (stochastic)
459 extant
= range(TEST_FILES
)
462 extant
[i
] = self
.do_create(pre
="aa")
465 if(isinstance(i
, basestring
)):
468 def test_choose_directory(self
):
469 # mkdtemp can create directories in a user-selected directory
470 dir = tempfile
.mkdtemp()
472 os
.rmdir(self
.do_create(dir=dir))
477 # mkdtemp creates directories with the proper mode
479 return # ugh, can't use TestSkipped.
481 dir = self
.do_create()
483 mode
= stat
.S_IMODE(os
.stat(dir).st_mode
)
484 mode
&= 0777 # Mask off sticky bits inherited from /tmp
486 if sys
.platform
in ('win32', 'os2emx', 'mac'):
487 # There's no distinction among 'user', 'group' and 'world';
488 # replicate the 'user' bits.
490 expected
= user
* (1 + 8 + 64)
491 self
.assertEqual(mode
, expected
)
495 test_classes
.append(test_mkdtemp
)
498 class test_mktemp(TC
):
501 # For safety, all use of mktemp must occur in a private directory.
502 # We must also suppress the RuntimeWarning it generates.
504 self
.dir = tempfile
.mkdtemp()
513 _bflags
= tempfile
._bin
_openflags
515 def __init__(self
, dir, pre
, suf
):
516 self
.name
= tempfile
.mktemp(dir=dir, prefix
=pre
, suffix
=suf
)
517 # Create the file. This will raise an exception if it's
518 # mysteriously appeared in the meanwhile.
519 os
.close(os
.open(self
.name
, self
._bflags
, 0600))
522 self
._unlink
(self
.name
)
524 def do_create(self
, pre
="", suf
=""):
526 file = self
.mktemped(self
.dir, pre
, suf
)
528 self
.failOnException("mktemp")
530 self
.nameCheck(file.name
, self
.dir, pre
, suf
)
533 def test_basic(self
):
534 # mktemp can choose usable file names
536 self
.do_create(pre
="a")
537 self
.do_create(suf
="b")
538 self
.do_create(pre
="a", suf
="b")
539 self
.do_create(pre
="aa", suf
=".txt")
542 # mktemp can choose many usable file names (stochastic)
543 extant
= range(TEST_FILES
)
545 extant
[i
] = self
.do_create(pre
="aa")
547 ## def test_warning(self):
548 ## # mktemp issues a warning when used
549 ## warnings.filterwarnings("error",
550 ## category=RuntimeWarning,
552 ## self.assertRaises(RuntimeWarning,
553 ## tempfile.mktemp, dir=self.dir)
555 test_classes
.append(test_mktemp
)
558 # We test _TemporaryFileWrapper by testing NamedTemporaryFile.
561 class test_NamedTemporaryFile(TC
):
562 """Test NamedTemporaryFile()."""
564 def do_create(self
, dir=None, pre
="", suf
=""):
566 dir = tempfile
.gettempdir()
568 file = tempfile
.NamedTemporaryFile(dir=dir, prefix
=pre
, suffix
=suf
)
570 self
.failOnException("NamedTemporaryFile")
572 self
.nameCheck(file.name
, dir, pre
, suf
)
576 def test_basic(self
):
577 # NamedTemporaryFile can create files
579 self
.do_create(pre
="a")
580 self
.do_create(suf
="b")
581 self
.do_create(pre
="a", suf
="b")
582 self
.do_create(pre
="aa", suf
=".txt")
584 def test_creates_named(self
):
585 # NamedTemporaryFile creates files with names
586 f
= tempfile
.NamedTemporaryFile()
587 self
.failUnless(os
.path
.exists(f
.name
),
588 "NamedTemporaryFile %s does not exist" % f
.name
)
590 def test_del_on_close(self
):
591 # A NamedTemporaryFile is deleted when closed
592 dir = tempfile
.mkdtemp()
594 f
= tempfile
.NamedTemporaryFile(dir=dir)
597 self
.failIf(os
.path
.exists(f
.name
),
598 "NamedTemporaryFile %s exists after close" % f
.name
)
602 def test_multiple_close(self
):
603 # A NamedTemporaryFile can be closed many times without error
605 f
= tempfile
.NamedTemporaryFile()
612 self
.failOnException("close")
614 # How to test the mode and bufsize parameters?
616 test_classes
.append(test_NamedTemporaryFile
)
619 class test_TemporaryFile(TC
):
620 """Test TemporaryFile()."""
622 def test_basic(self
):
623 # TemporaryFile can create files
624 # No point in testing the name params - the file has no name.
626 tempfile
.TemporaryFile()
628 self
.failOnException("TemporaryFile")
630 def test_has_no_name(self
):
631 # TemporaryFile creates files with no names (on this system)
632 dir = tempfile
.mkdtemp()
633 f
= tempfile
.TemporaryFile(dir=dir)
636 # Sneaky: because this file has no name, it should not prevent
637 # us from removing the directory it was created in.
645 self
.failOnException("rmdir", ei
)
647 def test_multiple_close(self
):
648 # A TemporaryFile can be closed many times without error
649 f
= tempfile
.TemporaryFile()
656 self
.failOnException("close")
658 # How to test the mode and bufsize parameters?
661 if tempfile
.NamedTemporaryFile
is not tempfile
.TemporaryFile
:
662 test_classes
.append(test_TemporaryFile
)
665 test_support
.run_unittest(*test_classes
)
667 if __name__
== "__main__":