blob: b4d23addf2bb39db86bbe8e130efb0ed11445fd8 [file] [log] [blame]
Guido van Rossum0e548712002-08-09 16:14:33 +00001# tempfile.py unit tests.
Tim Petersc57a2852001-10-29 21:46:08 +00002import tempfile
Serhiy Storchaka0127de02013-02-13 00:34:46 +02003import errno
4import io
Guido van Rossum0e548712002-08-09 16:14:33 +00005import os
Antoine Pitroua5d5bb92011-11-25 21:28:15 +01006import signal
Serhiy Storchaka0127de02013-02-13 00:34:46 +02007import shutil
Guido van Rossum0e548712002-08-09 16:14:33 +00008import sys
9import re
Guido van Rossum0e548712002-08-09 16:14:33 +000010import warnings
Tim Petersc57a2852001-10-29 21:46:08 +000011
Guido van Rossum0e548712002-08-09 16:14:33 +000012import unittest
Serhiy Storchaka0127de02013-02-13 00:34:46 +020013from test import test_support as support
Guido van Rossum0e548712002-08-09 16:14:33 +000014
Fred Drake7633d232002-10-17 22:09:03 +000015warnings.filterwarnings("ignore",
16 category=RuntimeWarning,
17 message="mktemp", module=__name__)
18
Guido van Rossum0e548712002-08-09 16:14:33 +000019if hasattr(os, 'stat'):
20 import stat
21 has_stat = 1
22else:
23 has_stat = 0
24
25has_textmode = (tempfile._text_openflags != tempfile._bin_openflags)
Guido van Rossum78741062002-08-17 11:41:01 +000026has_spawnl = hasattr(os, 'spawnl')
Guido van Rossum0e548712002-08-09 16:14:33 +000027
Neal Norwitz68ee0122002-08-16 19:28:59 +000028# TEST_FILES may need to be tweaked for systems depending on the maximum
29# number of files that can be opened at one time (see ulimit -n)
Ronald Oussoren9545a232010-05-05 19:09:31 +000030if sys.platform in ('openbsd3', 'openbsd4'):
Martin v. Löwis99968282004-09-15 06:02:54 +000031 TEST_FILES = 48
Jack Jansence921472003-01-08 16:30:34 +000032else:
33 TEST_FILES = 100
Neal Norwitz68ee0122002-08-16 19:28:59 +000034
Guido van Rossum0e548712002-08-09 16:14:33 +000035# 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.
38
39# Common functionality.
40class TC(unittest.TestCase):
41
42 str_check = re.compile(r"[a-zA-Z0-9_-]{6}$")
43
44 def failOnException(self, what, ei=None):
45 if ei is None:
46 ei = sys.exc_info()
47 self.fail("%s raised %s: %s" % (what, ei[0], ei[1]))
48
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):]
53
Martin v. Löwisd6625482003-10-12 17:37:01 +000054 # check for equality of the absolute paths!
55 self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +000056 "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))
61
62 nbase = nbase[len(pre):len(nbase)-len(suf)]
Benjamin Peterson5c8da862009-06-30 22:57:08 +000063 self.assertTrue(self.str_check.match(nbase),
Guido van Rossum0e548712002-08-09 16:14:33 +000064 "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/"
65 % nbase)
66
67test_classes = []
68
69class test_exports(TC):
70 def test_exports(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +000071 # There are no surprising symbols in the tempfile module
Guido van Rossum0e548712002-08-09 16:14:33 +000072 dict = tempfile.__dict__
73
74 expected = {
75 "NamedTemporaryFile" : 1,
76 "TemporaryFile" : 1,
77 "mkstemp" : 1,
78 "mkdtemp" : 1,
79 "mktemp" : 1,
80 "TMP_MAX" : 1,
81 "gettempprefix" : 1,
82 "gettempdir" : 1,
83 "tempdir" : 1,
Collin Wintera8785cc2007-03-19 18:52:08 +000084 "template" : 1,
85 "SpooledTemporaryFile" : 1
Guido van Rossum0e548712002-08-09 16:14:33 +000086 }
87
88 unexp = []
89 for key in dict:
90 if key[0] != '_' and key not in expected:
91 unexp.append(key)
Benjamin Peterson5c8da862009-06-30 22:57:08 +000092 self.assertTrue(len(unexp) == 0,
Guido van Rossum0e548712002-08-09 16:14:33 +000093 "unexpected keys: %s" % unexp)
94
95test_classes.append(test_exports)
96
97
Guido van Rossum0e548712002-08-09 16:14:33 +000098class test__RandomNameSequence(TC):
99 """Test the internal iterator object _RandomNameSequence."""
100
101 def setUp(self):
102 self.r = tempfile._RandomNameSequence()
103
104 def test_get_six_char_str(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000105 # _RandomNameSequence returns a six-character string
Guido van Rossum0e548712002-08-09 16:14:33 +0000106 s = self.r.next()
107 self.nameCheck(s, '', '', '')
108
109 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000110 # _RandomNameSequence returns no duplicate strings (stochastic)
Guido van Rossum0e548712002-08-09 16:14:33 +0000111
112 dict = {}
113 r = self.r
Neal Norwitz68ee0122002-08-16 19:28:59 +0000114 for i in xrange(TEST_FILES):
Guido van Rossum0e548712002-08-09 16:14:33 +0000115 s = r.next()
116 self.nameCheck(s, '', '', '')
Ezio Melottiaa980582010-01-23 23:04:36 +0000117 self.assertNotIn(s, dict)
Guido van Rossum0e548712002-08-09 16:14:33 +0000118 dict[s] = 1
119
120 def test_supports_iter(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000121 # _RandomNameSequence supports the iterator protocol
Guido van Rossum0e548712002-08-09 16:14:33 +0000122
123 i = 0
124 r = self.r
125 try:
126 for s in r:
127 i += 1
128 if i == 20:
129 break
130 except:
Georg Brandld10d8ee2010-02-06 23:18:00 +0000131 self.failOnException("iteration")
Guido van Rossum0e548712002-08-09 16:14:33 +0000132
Antoine Pitroua5d5bb92011-11-25 21:28:15 +0100133 @unittest.skipUnless(hasattr(os, 'fork'),
134 "os.fork is required for this test")
135 def test_process_awareness(self):
136 # ensure that the random source differs between
137 # child and parent.
138 read_fd, write_fd = os.pipe()
139 pid = None
140 try:
141 pid = os.fork()
142 if not pid:
143 os.close(read_fd)
144 os.write(write_fd, next(self.r).encode("ascii"))
145 os.close(write_fd)
146 # bypass the normal exit handlers- leave those to
147 # the parent.
148 os._exit(0)
149 parent_value = next(self.r)
150 child_value = os.read(read_fd, len(parent_value)).decode("ascii")
151 finally:
152 if pid:
153 # best effort to ensure the process can't bleed out
154 # via any bugs above
155 try:
156 os.kill(pid, signal.SIGKILL)
157 except EnvironmentError:
158 pass
159 os.close(read_fd)
160 os.close(write_fd)
161 self.assertNotEqual(child_value, parent_value)
162
163
Guido van Rossum0e548712002-08-09 16:14:33 +0000164test_classes.append(test__RandomNameSequence)
165
166
167class test__candidate_tempdir_list(TC):
168 """Test the internal function _candidate_tempdir_list."""
169
170 def test_nonempty_list(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000171 # _candidate_tempdir_list returns a nonempty list of strings
Guido van Rossum0e548712002-08-09 16:14:33 +0000172
173 cand = tempfile._candidate_tempdir_list()
174
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000175 self.assertFalse(len(cand) == 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000176 for c in cand:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000177 self.assertIsInstance(c, basestring)
Guido van Rossum0e548712002-08-09 16:14:33 +0000178
179 def test_wanted_dirs(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000180 # _candidate_tempdir_list contains the expected directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000181
182 # Make sure the interesting environment variables are all set.
Serhiy Storchaka0127de02013-02-13 00:34:46 +0200183 with support.EnvironmentVarGuard() as env:
Guido van Rossum0e548712002-08-09 16:14:33 +0000184 for envname in 'TMPDIR', 'TEMP', 'TMP':
185 dirname = os.getenv(envname)
186 if not dirname:
Walter Dörwald6733bed2009-05-01 17:35:37 +0000187 env[envname] = os.path.abspath(envname)
Guido van Rossum0e548712002-08-09 16:14:33 +0000188
189 cand = tempfile._candidate_tempdir_list()
190
191 for envname in 'TMPDIR', 'TEMP', 'TMP':
192 dirname = os.getenv(envname)
193 if not dirname: raise ValueError
Ezio Melottiaa980582010-01-23 23:04:36 +0000194 self.assertIn(dirname, cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000195
196 try:
197 dirname = os.getcwd()
198 except (AttributeError, os.error):
199 dirname = os.curdir
200
Ezio Melottiaa980582010-01-23 23:04:36 +0000201 self.assertIn(dirname, cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000202
203 # Not practical to try to verify the presence of OS-specific
204 # paths in this list.
Guido van Rossum0e548712002-08-09 16:14:33 +0000205
206test_classes.append(test__candidate_tempdir_list)
207
Serhiy Storchaka0127de02013-02-13 00:34:46 +0200208# We test _get_default_tempdir some more by testing gettempdir.
Guido van Rossum0e548712002-08-09 16:14:33 +0000209
Serhiy Storchaka0127de02013-02-13 00:34:46 +0200210class TestGetDefaultTempdir(TC):
211 """Test _get_default_tempdir()."""
212
213 def test_no_files_left_behind(self):
214 # use a private empty directory
215 our_temp_directory = tempfile.mkdtemp()
216 try:
217 # force _get_default_tempdir() to consider our empty directory
218 def our_candidate_list():
219 return [our_temp_directory]
220
221 with support.swap_attr(tempfile, "_candidate_tempdir_list",
222 our_candidate_list):
223 # verify our directory is empty after _get_default_tempdir()
224 tempfile._get_default_tempdir()
225 self.assertEqual(os.listdir(our_temp_directory), [])
226
227 def raise_OSError(*args, **kwargs):
228 raise OSError(-1)
229
230 with support.swap_attr(io, "open", raise_OSError):
231 # test again with failing io.open()
232 with self.assertRaises(IOError) as cm:
233 tempfile._get_default_tempdir()
234 self.assertEqual(cm.exception.errno, errno.ENOENT)
235 self.assertEqual(os.listdir(our_temp_directory), [])
236
237 open = io.open
238 def bad_writer(*args, **kwargs):
239 fp = open(*args, **kwargs)
240 fp.write = raise_OSError
241 return fp
242
243 with support.swap_attr(io, "open", bad_writer):
244 # test again with failing write()
245 with self.assertRaises(IOError) as cm:
246 tempfile._get_default_tempdir()
247 self.assertEqual(cm.exception.errno, errno.ENOENT)
248 self.assertEqual(os.listdir(our_temp_directory), [])
249 finally:
250 shutil.rmtree(our_temp_directory)
251
252test_classes.append(TestGetDefaultTempdir)
Guido van Rossum0e548712002-08-09 16:14:33 +0000253
254
255class test__get_candidate_names(TC):
256 """Test the internal function _get_candidate_names."""
257
258 def test_retval(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000259 # _get_candidate_names returns a _RandomNameSequence object
Guido van Rossum0e548712002-08-09 16:14:33 +0000260 obj = tempfile._get_candidate_names()
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000261 self.assertIsInstance(obj, tempfile._RandomNameSequence)
Guido van Rossum0e548712002-08-09 16:14:33 +0000262
263 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000264 # _get_candidate_names always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000265 a = tempfile._get_candidate_names()
266 b = tempfile._get_candidate_names()
267
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000268 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000269
270test_classes.append(test__get_candidate_names)
271
272
273class test__mkstemp_inner(TC):
274 """Test the internal function _mkstemp_inner."""
275
276 class mkstemped:
277 _bflags = tempfile._bin_openflags
278 _tflags = tempfile._text_openflags
279 _close = os.close
280 _unlink = os.unlink
281
282 def __init__(self, dir, pre, suf, bin):
283 if bin: flags = self._bflags
284 else: flags = self._tflags
285
286 (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags)
287
288 def write(self, str):
289 os.write(self.fd, str)
290
291 def __del__(self):
292 self._close(self.fd)
293 self._unlink(self.name)
Tim Petersa0d55de2002-08-09 18:01:01 +0000294
Guido van Rossum0e548712002-08-09 16:14:33 +0000295 def do_create(self, dir=None, pre="", suf="", bin=1):
296 if dir is None:
297 dir = tempfile.gettempdir()
298 try:
299 file = self.mkstemped(dir, pre, suf, bin)
300 except:
301 self.failOnException("_mkstemp_inner")
302
303 self.nameCheck(file.name, dir, pre, suf)
304 return file
305
306 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000307 # _mkstemp_inner can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000308 self.do_create().write("blat")
309 self.do_create(pre="a").write("blat")
310 self.do_create(suf="b").write("blat")
311 self.do_create(pre="a", suf="b").write("blat")
312 self.do_create(pre="aa", suf=".txt").write("blat")
313
314 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000315 # _mkstemp_inner can create many files (stochastic)
Neal Norwitz68ee0122002-08-16 19:28:59 +0000316 extant = range(TEST_FILES)
Guido van Rossum0e548712002-08-09 16:14:33 +0000317 for i in extant:
318 extant[i] = self.do_create(pre="aa")
319
320 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000321 # _mkstemp_inner can create files in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000322 dir = tempfile.mkdtemp()
323 try:
324 self.do_create(dir=dir).write("blat")
325 finally:
326 os.rmdir(dir)
327
328 def test_file_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000329 # _mkstemp_inner creates files with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000330 if not has_stat:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000331 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000332
333 file = self.do_create()
334 mode = stat.S_IMODE(os.stat(file.name).st_mode)
Tim Petersca3ac7f2002-08-09 18:13:51 +0000335 expected = 0600
Ronald Oussoren9545a232010-05-05 19:09:31 +0000336 if sys.platform in ('win32', 'os2emx'):
Tim Petersca3ac7f2002-08-09 18:13:51 +0000337 # There's no distinction among 'user', 'group' and 'world';
338 # replicate the 'user' bits.
339 user = expected >> 6
340 expected = user * (1 + 8 + 64)
341 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000342
343 def test_noinherit(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000344 # _mkstemp_inner file handles are not inherited by child processes
Guido van Rossum78741062002-08-17 11:41:01 +0000345 if not has_spawnl:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000346 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000347
Serhiy Storchaka0127de02013-02-13 00:34:46 +0200348 if support.verbose:
Guido van Rossum78741062002-08-17 11:41:01 +0000349 v="v"
350 else:
351 v="q"
352
Guido van Rossum0e548712002-08-09 16:14:33 +0000353 file = self.do_create()
Guido van Rossum78741062002-08-17 11:41:01 +0000354 fd = "%d" % file.fd
355
356 try:
357 me = __file__
358 except NameError:
359 me = sys.argv[0]
Guido van Rossum0e548712002-08-09 16:14:33 +0000360
361 # We have to exec something, so that FD_CLOEXEC will take
Guido van Rossum78741062002-08-17 11:41:01 +0000362 # effect. The core of this test is therefore in
363 # tf_inherit_check.py, which see.
364 tester = os.path.join(os.path.dirname(os.path.abspath(me)),
365 "tf_inherit_check.py")
Guido van Rossum0e548712002-08-09 16:14:33 +0000366
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000367 # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted,
368 # but an arg with embedded spaces should be decorated with double
369 # quotes on each end
Armin Rigo66d41b22007-12-07 19:19:55 +0000370 if sys.platform in ('win32',):
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000371 decorated = '"%s"' % sys.executable
372 tester = '"%s"' % tester
373 else:
374 decorated = sys.executable
375
376 retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000377 self.assertFalse(retval < 0,
Guido van Rossum78741062002-08-17 11:41:01 +0000378 "child process caught fatal signal %d" % -retval)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000379 self.assertFalse(retval > 0, "child process reports failure %d"%retval)
Guido van Rossum0e548712002-08-09 16:14:33 +0000380
381 def test_textmode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000382 # _mkstemp_inner can create files in text mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000383 if not has_textmode:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000384 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000385
386 self.do_create(bin=0).write("blat\n")
387 # XXX should test that the file really is a text file
388
389test_classes.append(test__mkstemp_inner)
390
391
392class test_gettempprefix(TC):
393 """Test gettempprefix()."""
394
395 def test_sane_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000396 # gettempprefix returns a nonempty prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000397 p = tempfile.gettempprefix()
398
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000399 self.assertIsInstance(p, basestring)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000400 self.assertTrue(len(p) > 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000401
402 def test_usable_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000403 # gettempprefix returns a usable prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000404
405 # Create a temp directory, avoiding use of the prefix.
406 # Then attempt to create a file whose name is
407 # prefix + 'xxxxxx.xxx' in that directory.
408 p = tempfile.gettempprefix() + "xxxxxx.xxx"
409 d = tempfile.mkdtemp(prefix="")
410 try:
411 p = os.path.join(d, p)
412 try:
413 fd = os.open(p, os.O_RDWR | os.O_CREAT)
414 except:
415 self.failOnException("os.open")
416 os.close(fd)
417 os.unlink(p)
418 finally:
419 os.rmdir(d)
420
421test_classes.append(test_gettempprefix)
422
423
424class test_gettempdir(TC):
425 """Test gettempdir()."""
426
427 def test_directory_exists(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000428 # gettempdir returns a directory which exists
Guido van Rossum0e548712002-08-09 16:14:33 +0000429
430 dir = tempfile.gettempdir()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000431 self.assertTrue(os.path.isabs(dir) or dir == os.curdir,
Guido van Rossum0e548712002-08-09 16:14:33 +0000432 "%s is not an absolute path" % dir)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000433 self.assertTrue(os.path.isdir(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +0000434 "%s is not a directory" % dir)
435
436 def test_directory_writable(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000437 # gettempdir returns a directory writable by the user
Guido van Rossum0e548712002-08-09 16:14:33 +0000438
439 # sneaky: just instantiate a NamedTemporaryFile, which
440 # defaults to writing into the directory returned by
441 # gettempdir.
442 try:
443 file = tempfile.NamedTemporaryFile()
444 file.write("blat")
445 file.close()
446 except:
447 self.failOnException("create file in %s" % tempfile.gettempdir())
448
449 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000450 # gettempdir always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000451 a = tempfile.gettempdir()
452 b = tempfile.gettempdir()
453
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000454 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000455
456test_classes.append(test_gettempdir)
457
458
459class test_mkstemp(TC):
460 """Test mkstemp()."""
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000461
Martin Blais215f13d2006-06-06 12:46:55 +0000462 def do_create(self, dir=None, pre="", suf=""):
Guido van Rossum0e548712002-08-09 16:14:33 +0000463 if dir is None:
464 dir = tempfile.gettempdir()
465 try:
466 (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf)
Martin v. Löwisd6625482003-10-12 17:37:01 +0000467 (ndir, nbase) = os.path.split(name)
468 adir = os.path.abspath(dir)
469 self.assertEqual(adir, ndir,
470 "Directory '%s' incorrectly returned as '%s'" % (adir, ndir))
Guido van Rossum0e548712002-08-09 16:14:33 +0000471 except:
472 self.failOnException("mkstemp")
473
474 try:
475 self.nameCheck(name, dir, pre, suf)
476 finally:
477 os.close(fd)
478 os.unlink(name)
479
480 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000481 # mkstemp can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000482 self.do_create()
483 self.do_create(pre="a")
484 self.do_create(suf="b")
485 self.do_create(pre="a", suf="b")
486 self.do_create(pre="aa", suf=".txt")
Martin v. Löwisd6625482003-10-12 17:37:01 +0000487 self.do_create(dir=".")
Guido van Rossum0e548712002-08-09 16:14:33 +0000488
489 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000490 # mkstemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000491 dir = tempfile.mkdtemp()
492 try:
493 self.do_create(dir=dir)
494 finally:
495 os.rmdir(dir)
496
497test_classes.append(test_mkstemp)
498
499
500class test_mkdtemp(TC):
501 """Test mkdtemp()."""
502
503 def do_create(self, dir=None, pre="", suf=""):
504 if dir is None:
505 dir = tempfile.gettempdir()
506 try:
507 name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf)
508 except:
509 self.failOnException("mkdtemp")
510
511 try:
512 self.nameCheck(name, dir, pre, suf)
513 return name
514 except:
515 os.rmdir(name)
516 raise
517
518 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000519 # mkdtemp can create directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000520 os.rmdir(self.do_create())
521 os.rmdir(self.do_create(pre="a"))
522 os.rmdir(self.do_create(suf="b"))
523 os.rmdir(self.do_create(pre="a", suf="b"))
524 os.rmdir(self.do_create(pre="aa", suf=".txt"))
Tim Petersa0d55de2002-08-09 18:01:01 +0000525
Guido van Rossum0e548712002-08-09 16:14:33 +0000526 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000527 # mkdtemp can create many directories (stochastic)
Neal Norwitz68ee0122002-08-16 19:28:59 +0000528 extant = range(TEST_FILES)
Guido van Rossum0e548712002-08-09 16:14:33 +0000529 try:
530 for i in extant:
531 extant[i] = self.do_create(pre="aa")
532 finally:
533 for i in extant:
534 if(isinstance(i, basestring)):
535 os.rmdir(i)
536
537 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000538 # mkdtemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000539 dir = tempfile.mkdtemp()
540 try:
541 os.rmdir(self.do_create(dir=dir))
542 finally:
543 os.rmdir(dir)
544
545 def test_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000546 # mkdtemp creates directories with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000547 if not has_stat:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000548 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000549
550 dir = self.do_create()
551 try:
552 mode = stat.S_IMODE(os.stat(dir).st_mode)
Guido van Rossum59db96f2004-03-31 18:53:29 +0000553 mode &= 0777 # Mask off sticky bits inherited from /tmp
Tim Petersca3ac7f2002-08-09 18:13:51 +0000554 expected = 0700
Ronald Oussoren9545a232010-05-05 19:09:31 +0000555 if sys.platform in ('win32', 'os2emx'):
Tim Petersca3ac7f2002-08-09 18:13:51 +0000556 # There's no distinction among 'user', 'group' and 'world';
557 # replicate the 'user' bits.
558 user = expected >> 6
559 expected = user * (1 + 8 + 64)
560 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000561 finally:
562 os.rmdir(dir)
563
564test_classes.append(test_mkdtemp)
565
566
567class test_mktemp(TC):
568 """Test mktemp()."""
569
570 # For safety, all use of mktemp must occur in a private directory.
571 # We must also suppress the RuntimeWarning it generates.
572 def setUp(self):
573 self.dir = tempfile.mkdtemp()
Guido van Rossum0e548712002-08-09 16:14:33 +0000574
575 def tearDown(self):
576 if self.dir:
577 os.rmdir(self.dir)
578 self.dir = None
Guido van Rossum0e548712002-08-09 16:14:33 +0000579
580 class mktemped:
581 _unlink = os.unlink
582 _bflags = tempfile._bin_openflags
583
584 def __init__(self, dir, pre, suf):
585 self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf)
586 # Create the file. This will raise an exception if it's
587 # mysteriously appeared in the meanwhile.
588 os.close(os.open(self.name, self._bflags, 0600))
589
590 def __del__(self):
591 self._unlink(self.name)
592
593 def do_create(self, pre="", suf=""):
594 try:
595 file = self.mktemped(self.dir, pre, suf)
596 except:
597 self.failOnException("mktemp")
598
599 self.nameCheck(file.name, self.dir, pre, suf)
600 return file
601
602 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000603 # mktemp can choose usable file names
Guido van Rossum0e548712002-08-09 16:14:33 +0000604 self.do_create()
605 self.do_create(pre="a")
606 self.do_create(suf="b")
607 self.do_create(pre="a", suf="b")
608 self.do_create(pre="aa", suf=".txt")
609
610 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000611 # mktemp can choose many usable file names (stochastic)
Neal Norwitz68ee0122002-08-16 19:28:59 +0000612 extant = range(TEST_FILES)
Guido van Rossum0e548712002-08-09 16:14:33 +0000613 for i in extant:
614 extant[i] = self.do_create(pre="aa")
615
Fred Drake8bec4832002-11-22 20:13:43 +0000616## def test_warning(self):
617## # mktemp issues a warning when used
618## warnings.filterwarnings("error",
619## category=RuntimeWarning,
620## message="mktemp")
621## self.assertRaises(RuntimeWarning,
622## tempfile.mktemp, dir=self.dir)
Guido van Rossum0e548712002-08-09 16:14:33 +0000623
624test_classes.append(test_mktemp)
625
626
627# We test _TemporaryFileWrapper by testing NamedTemporaryFile.
628
629
630class test_NamedTemporaryFile(TC):
631 """Test NamedTemporaryFile()."""
632
Georg Brandl35ef9c12007-03-13 18:31:49 +0000633 def do_create(self, dir=None, pre="", suf="", delete=True):
Guido van Rossum0e548712002-08-09 16:14:33 +0000634 if dir is None:
635 dir = tempfile.gettempdir()
636 try:
Georg Brandl35ef9c12007-03-13 18:31:49 +0000637 file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf,
Georg Brandl4168c042007-03-13 19:18:18 +0000638 delete=delete)
Guido van Rossum0e548712002-08-09 16:14:33 +0000639 except:
640 self.failOnException("NamedTemporaryFile")
641
642 self.nameCheck(file.name, dir, pre, suf)
643 return file
644
645
646 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000647 # NamedTemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000648 self.do_create()
649 self.do_create(pre="a")
650 self.do_create(suf="b")
651 self.do_create(pre="a", suf="b")
652 self.do_create(pre="aa", suf=".txt")
653
654 def test_creates_named(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000655 # NamedTemporaryFile creates files with names
Guido van Rossum0e548712002-08-09 16:14:33 +0000656 f = tempfile.NamedTemporaryFile()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000657 self.assertTrue(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000658 "NamedTemporaryFile %s does not exist" % f.name)
659
660 def test_del_on_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000661 # A NamedTemporaryFile is deleted when closed
Guido van Rossum0e548712002-08-09 16:14:33 +0000662 dir = tempfile.mkdtemp()
663 try:
664 f = tempfile.NamedTemporaryFile(dir=dir)
665 f.write('blat')
666 f.close()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000667 self.assertFalse(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000668 "NamedTemporaryFile %s exists after close" % f.name)
669 finally:
670 os.rmdir(dir)
671
Georg Brandl35ef9c12007-03-13 18:31:49 +0000672 def test_dis_del_on_close(self):
673 # Tests that delete-on-close can be disabled
674 dir = tempfile.mkdtemp()
Georg Brandl4168c042007-03-13 19:18:18 +0000675 tmp = None
Georg Brandl35ef9c12007-03-13 18:31:49 +0000676 try:
677 f = tempfile.NamedTemporaryFile(dir=dir, delete=False)
678 tmp = f.name
679 f.write('blat')
680 f.close()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000681 self.assertTrue(os.path.exists(f.name),
Georg Brandl35ef9c12007-03-13 18:31:49 +0000682 "NamedTemporaryFile %s missing after close" % f.name)
683 finally:
684 if tmp is not None:
685 os.unlink(tmp)
686 os.rmdir(dir)
687
Guido van Rossum0e548712002-08-09 16:14:33 +0000688 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000689 # A NamedTemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000690 f = tempfile.NamedTemporaryFile()
691 f.write('abc\n')
692 f.close()
693 try:
694 f.close()
695 f.close()
696 except:
697 self.failOnException("close")
698
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000699 def test_context_manager(self):
700 # A NamedTemporaryFile can be used as a context manager
701 with tempfile.NamedTemporaryFile() as f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000702 self.assertTrue(os.path.exists(f.name))
703 self.assertFalse(os.path.exists(f.name))
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000704 def use_closed():
705 with f:
706 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000707 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000708
Guido van Rossum0e548712002-08-09 16:14:33 +0000709 # How to test the mode and bufsize parameters?
710
711test_classes.append(test_NamedTemporaryFile)
712
Collin Wintera8785cc2007-03-19 18:52:08 +0000713class test_SpooledTemporaryFile(TC):
714 """Test SpooledTemporaryFile()."""
715
716 def do_create(self, max_size=0, dir=None, pre="", suf=""):
717 if dir is None:
718 dir = tempfile.gettempdir()
719 try:
720 file = tempfile.SpooledTemporaryFile(max_size=max_size, dir=dir, prefix=pre, suffix=suf)
721 except:
722 self.failOnException("SpooledTemporaryFile")
723
724 return file
725
726
727 def test_basic(self):
728 # SpooledTemporaryFile can create files
729 f = self.do_create()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000730 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000731 f = self.do_create(max_size=100, pre="a", suf=".txt")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000732 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000733
734 def test_del_on_close(self):
735 # A SpooledTemporaryFile is deleted when closed
736 dir = tempfile.mkdtemp()
737 try:
738 f = tempfile.SpooledTemporaryFile(max_size=10, dir=dir)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000739 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000740 f.write('blat ' * 5)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000741 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000742 filename = f.name
743 f.close()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000744 self.assertFalse(os.path.exists(filename),
Collin Wintera8785cc2007-03-19 18:52:08 +0000745 "SpooledTemporaryFile %s exists after close" % filename)
746 finally:
747 os.rmdir(dir)
748
749 def test_rewrite_small(self):
750 # A SpooledTemporaryFile can be written to multiple within the max_size
751 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000752 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000753 for i in range(5):
754 f.seek(0, 0)
755 f.write('x' * 20)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000756 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000757
758 def test_write_sequential(self):
759 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
760 # over afterward
761 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000762 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000763 f.write('x' * 20)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000764 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000765 f.write('x' * 10)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000766 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000767 f.write('x')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000768 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000769
R David Murrayb44e1842011-03-14 10:01:12 -0400770 def test_writelines(self):
771 # Verify writelines with a SpooledTemporaryFile
772 f = self.do_create()
773 f.writelines((b'x', b'y', b'z'))
774 f.seek(0)
775 buf = f.read()
776 self.assertEqual(buf, b'xyz')
777
778 def test_writelines_sequential(self):
779 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
780 # over afterward
781 f = self.do_create(max_size=35)
782 f.writelines((b'x' * 20, b'x' * 10, b'x' * 5))
783 self.assertFalse(f._rolled)
784 f.write(b'x')
785 self.assertTrue(f._rolled)
786
Serhiy Storchakabeaa3ad2013-02-09 12:20:18 +0200787 def test_xreadlines(self):
788 f = self.do_create(max_size=20)
789 f.write(b'abc\n' * 5)
790 f.seek(0)
791 self.assertFalse(f._rolled)
792 self.assertEqual(list(f.xreadlines()), [b'abc\n'] * 5)
793 f.write(b'x\ny')
794 self.assertTrue(f._rolled)
795 f.seek(0)
796 self.assertEqual(list(f.xreadlines()), [b'abc\n'] * 5 + [b'x\n', b'y'])
797
Collin Wintera8785cc2007-03-19 18:52:08 +0000798 def test_sparse(self):
799 # A SpooledTemporaryFile that is written late in the file will extend
800 # when that occurs
801 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000802 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000803 f.seek(100, 0)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000804 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000805 f.write('x')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000806 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000807
808 def test_fileno(self):
809 # A SpooledTemporaryFile should roll over to a real file on fileno()
810 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000811 self.assertFalse(f._rolled)
812 self.assertTrue(f.fileno() > 0)
813 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000814
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000815 def test_multiple_close_before_rollover(self):
Collin Wintera8785cc2007-03-19 18:52:08 +0000816 # A SpooledTemporaryFile can be closed many times without error
817 f = tempfile.SpooledTemporaryFile()
818 f.write('abc\n')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000819 self.assertFalse(f._rolled)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000820 f.close()
821 try:
822 f.close()
823 f.close()
824 except:
825 self.failOnException("close")
826
827 def test_multiple_close_after_rollover(self):
828 # A SpooledTemporaryFile can be closed many times without error
829 f = tempfile.SpooledTemporaryFile(max_size=1)
830 f.write('abc\n')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000831 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000832 f.close()
833 try:
834 f.close()
835 f.close()
836 except:
837 self.failOnException("close")
838
839 def test_bound_methods(self):
840 # It should be OK to steal a bound method from a SpooledTemporaryFile
841 # and use it independently; when the file rolls over, those bound
842 # methods should continue to function
843 f = self.do_create(max_size=30)
844 read = f.read
845 write = f.write
846 seek = f.seek
847
848 write("a" * 35)
849 write("b" * 35)
850 seek(0, 0)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000851 self.assertTrue(read(70) == 'a'*35 + 'b'*35)
Collin Wintera8785cc2007-03-19 18:52:08 +0000852
Serhiy Storchakabeaa3ad2013-02-09 12:20:18 +0200853 def test_properties(self):
854 f = tempfile.SpooledTemporaryFile(max_size=10)
855 f.write(b'x' * 10)
856 self.assertFalse(f._rolled)
857 self.assertEqual(f.mode, 'w+b')
858 self.assertIsNone(f.name)
859 with self.assertRaises(AttributeError):
860 f.newlines
861 with self.assertRaises(AttributeError):
862 f.encoding
863
864 f.write(b'x')
865 self.assertTrue(f._rolled)
866 self.assertEqual(f.mode, 'w+b')
867 self.assertIsNotNone(f.name)
868 with self.assertRaises(AttributeError):
869 f.newlines
870 with self.assertRaises(AttributeError):
871 f.encoding
872
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000873 def test_context_manager_before_rollover(self):
874 # A SpooledTemporaryFile can be used as a context manager
875 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000876 self.assertFalse(f._rolled)
877 self.assertFalse(f.closed)
878 self.assertTrue(f.closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000879 def use_closed():
880 with f:
881 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000882 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000883
884 def test_context_manager_during_rollover(self):
885 # A SpooledTemporaryFile can be used as a context manager
886 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000887 self.assertFalse(f._rolled)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000888 f.write('abc\n')
889 f.flush()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000890 self.assertTrue(f._rolled)
891 self.assertFalse(f.closed)
892 self.assertTrue(f.closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000893 def use_closed():
894 with f:
895 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000896 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000897
898 def test_context_manager_after_rollover(self):
899 # A SpooledTemporaryFile can be used as a context manager
900 f = tempfile.SpooledTemporaryFile(max_size=1)
901 f.write('abc\n')
902 f.flush()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000903 self.assertTrue(f._rolled)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000904 with f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000905 self.assertFalse(f.closed)
906 self.assertTrue(f.closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000907 def use_closed():
908 with f:
909 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000910 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000911
912
Collin Wintera8785cc2007-03-19 18:52:08 +0000913test_classes.append(test_SpooledTemporaryFile)
914
Guido van Rossum0e548712002-08-09 16:14:33 +0000915
916class test_TemporaryFile(TC):
917 """Test TemporaryFile()."""
918
919 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000920 # TemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000921 # No point in testing the name params - the file has no name.
922 try:
923 tempfile.TemporaryFile()
924 except:
925 self.failOnException("TemporaryFile")
926
927 def test_has_no_name(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000928 # TemporaryFile creates files with no names (on this system)
Guido van Rossum0e548712002-08-09 16:14:33 +0000929 dir = tempfile.mkdtemp()
930 f = tempfile.TemporaryFile(dir=dir)
931 f.write('blat')
932
933 # Sneaky: because this file has no name, it should not prevent
934 # us from removing the directory it was created in.
935 try:
936 os.rmdir(dir)
937 except:
938 ei = sys.exc_info()
939 # cleanup
940 f.close()
941 os.rmdir(dir)
942 self.failOnException("rmdir", ei)
943
944 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000945 # A TemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000946 f = tempfile.TemporaryFile()
947 f.write('abc\n')
948 f.close()
949 try:
950 f.close()
951 f.close()
952 except:
953 self.failOnException("close")
954
955 # How to test the mode and bufsize parameters?
956
Guido van Rossum0e548712002-08-09 16:14:33 +0000957
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000958if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
Guido van Rossum0e548712002-08-09 16:14:33 +0000959 test_classes.append(test_TemporaryFile)
960
961def test_main():
Serhiy Storchaka0127de02013-02-13 00:34:46 +0200962 support.run_unittest(*test_classes)
Guido van Rossum0e548712002-08-09 16:14:33 +0000963
964if __name__ == "__main__":
965 test_main()