blob: e534d62b5162ae67bb32cc0fcb466800ce2b2daa [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
Guido van Rossum0e548712002-08-09 16:14:33 +00003import os
4import sys
5import re
Guido van Rossum0e548712002-08-09 16:14:33 +00006import warnings
Tim Petersc57a2852001-10-29 21:46:08 +00007
Guido van Rossum0e548712002-08-09 16:14:33 +00008import unittest
9from test import test_support
10
Fred Drake7633d232002-10-17 22:09:03 +000011warnings.filterwarnings("ignore",
12 category=RuntimeWarning,
13 message="mktemp", module=__name__)
14
Guido van Rossum0e548712002-08-09 16:14:33 +000015if hasattr(os, 'stat'):
16 import stat
17 has_stat = 1
18else:
19 has_stat = 0
20
21has_textmode = (tempfile._text_openflags != tempfile._bin_openflags)
Guido van Rossum78741062002-08-17 11:41:01 +000022has_spawnl = hasattr(os, 'spawnl')
Guido van Rossum0e548712002-08-09 16:14:33 +000023
Neal Norwitz68ee0122002-08-16 19:28:59 +000024# TEST_FILES may need to be tweaked for systems depending on the maximum
25# number of files that can be opened at one time (see ulimit -n)
Jack Jansence921472003-01-08 16:30:34 +000026if sys.platform == 'mac':
27 TEST_FILES = 32
Neal Norwitz4bc2c092006-09-05 02:57:01 +000028elif sys.platform in ('openbsd3', 'openbsd4'):
Martin v. Löwis99968282004-09-15 06:02:54 +000029 TEST_FILES = 48
Jack Jansence921472003-01-08 16:30:34 +000030else:
31 TEST_FILES = 100
Neal Norwitz68ee0122002-08-16 19:28:59 +000032
Guido van Rossum0e548712002-08-09 16:14:33 +000033# This is organized as one test for each chunk of code in tempfile.py,
34# in order of their appearance in the file. Testing which requires
35# threads is not done here.
36
37# Common functionality.
38class TC(unittest.TestCase):
39
40 str_check = re.compile(r"[a-zA-Z0-9_-]{6}$")
41
42 def failOnException(self, what, ei=None):
43 if ei is None:
44 ei = sys.exc_info()
45 self.fail("%s raised %s: %s" % (what, ei[0], ei[1]))
46
47 def nameCheck(self, name, dir, pre, suf):
48 (ndir, nbase) = os.path.split(name)
49 npre = nbase[:len(pre)]
50 nsuf = nbase[len(nbase)-len(suf):]
51
Martin v. Löwisd6625482003-10-12 17:37:01 +000052 # check for equality of the absolute paths!
53 self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +000054 "file '%s' not in directory '%s'" % (name, dir))
55 self.assertEqual(npre, pre,
56 "file '%s' does not begin with '%s'" % (nbase, pre))
57 self.assertEqual(nsuf, suf,
58 "file '%s' does not end with '%s'" % (nbase, suf))
59
60 nbase = nbase[len(pre):len(nbase)-len(suf)]
Benjamin Peterson5c8da862009-06-30 22:57:08 +000061 self.assertTrue(self.str_check.match(nbase),
Guido van Rossum0e548712002-08-09 16:14:33 +000062 "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/"
63 % nbase)
64
65test_classes = []
66
67class test_exports(TC):
68 def test_exports(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +000069 # There are no surprising symbols in the tempfile module
Guido van Rossum0e548712002-08-09 16:14:33 +000070 dict = tempfile.__dict__
71
72 expected = {
73 "NamedTemporaryFile" : 1,
74 "TemporaryFile" : 1,
75 "mkstemp" : 1,
76 "mkdtemp" : 1,
77 "mktemp" : 1,
78 "TMP_MAX" : 1,
79 "gettempprefix" : 1,
80 "gettempdir" : 1,
81 "tempdir" : 1,
Collin Wintera8785cc2007-03-19 18:52:08 +000082 "template" : 1,
83 "SpooledTemporaryFile" : 1
Guido van Rossum0e548712002-08-09 16:14:33 +000084 }
85
86 unexp = []
87 for key in dict:
88 if key[0] != '_' and key not in expected:
89 unexp.append(key)
Benjamin Peterson5c8da862009-06-30 22:57:08 +000090 self.assertTrue(len(unexp) == 0,
Guido van Rossum0e548712002-08-09 16:14:33 +000091 "unexpected keys: %s" % unexp)
92
93test_classes.append(test_exports)
94
95
Guido van Rossum0e548712002-08-09 16:14:33 +000096class test__RandomNameSequence(TC):
97 """Test the internal iterator object _RandomNameSequence."""
98
99 def setUp(self):
100 self.r = tempfile._RandomNameSequence()
101
102 def test_get_six_char_str(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000103 # _RandomNameSequence returns a six-character string
Guido van Rossum0e548712002-08-09 16:14:33 +0000104 s = self.r.next()
105 self.nameCheck(s, '', '', '')
106
107 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000108 # _RandomNameSequence returns no duplicate strings (stochastic)
Guido van Rossum0e548712002-08-09 16:14:33 +0000109
110 dict = {}
111 r = self.r
Neal Norwitz68ee0122002-08-16 19:28:59 +0000112 for i in xrange(TEST_FILES):
Guido van Rossum0e548712002-08-09 16:14:33 +0000113 s = r.next()
114 self.nameCheck(s, '', '', '')
Ezio Melottiaa980582010-01-23 23:04:36 +0000115 self.assertNotIn(s, dict)
Guido van Rossum0e548712002-08-09 16:14:33 +0000116 dict[s] = 1
117
118 def test_supports_iter(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000119 # _RandomNameSequence supports the iterator protocol
Guido van Rossum0e548712002-08-09 16:14:33 +0000120
121 i = 0
122 r = self.r
123 try:
124 for s in r:
125 i += 1
126 if i == 20:
127 break
128 except:
Georg Brandld10d8ee2010-02-06 23:18:00 +0000129 self.failOnException("iteration")
Guido van Rossum0e548712002-08-09 16:14:33 +0000130
131test_classes.append(test__RandomNameSequence)
132
133
134class test__candidate_tempdir_list(TC):
135 """Test the internal function _candidate_tempdir_list."""
136
137 def test_nonempty_list(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000138 # _candidate_tempdir_list returns a nonempty list of strings
Guido van Rossum0e548712002-08-09 16:14:33 +0000139
140 cand = tempfile._candidate_tempdir_list()
141
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000142 self.assertFalse(len(cand) == 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000143 for c in cand:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000144 self.assertIsInstance(c, basestring)
Guido van Rossum0e548712002-08-09 16:14:33 +0000145
146 def test_wanted_dirs(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000147 # _candidate_tempdir_list contains the expected directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000148
149 # Make sure the interesting environment variables are all set.
Walter Dörwald4b965f62009-04-26 20:51:44 +0000150 with test_support.EnvironmentVarGuard() as env:
Guido van Rossum0e548712002-08-09 16:14:33 +0000151 for envname in 'TMPDIR', 'TEMP', 'TMP':
152 dirname = os.getenv(envname)
153 if not dirname:
Walter Dörwald6733bed2009-05-01 17:35:37 +0000154 env[envname] = os.path.abspath(envname)
Guido van Rossum0e548712002-08-09 16:14:33 +0000155
156 cand = tempfile._candidate_tempdir_list()
157
158 for envname in 'TMPDIR', 'TEMP', 'TMP':
159 dirname = os.getenv(envname)
160 if not dirname: raise ValueError
Ezio Melottiaa980582010-01-23 23:04:36 +0000161 self.assertIn(dirname, cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000162
163 try:
164 dirname = os.getcwd()
165 except (AttributeError, os.error):
166 dirname = os.curdir
167
Ezio Melottiaa980582010-01-23 23:04:36 +0000168 self.assertIn(dirname, cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000169
170 # Not practical to try to verify the presence of OS-specific
171 # paths in this list.
Guido van Rossum0e548712002-08-09 16:14:33 +0000172
173test_classes.append(test__candidate_tempdir_list)
174
175
176# We test _get_default_tempdir by testing gettempdir.
177
178
179class test__get_candidate_names(TC):
180 """Test the internal function _get_candidate_names."""
181
182 def test_retval(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000183 # _get_candidate_names returns a _RandomNameSequence object
Guido van Rossum0e548712002-08-09 16:14:33 +0000184 obj = tempfile._get_candidate_names()
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000185 self.assertIsInstance(obj, tempfile._RandomNameSequence)
Guido van Rossum0e548712002-08-09 16:14:33 +0000186
187 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000188 # _get_candidate_names always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000189 a = tempfile._get_candidate_names()
190 b = tempfile._get_candidate_names()
191
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000192 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000193
194test_classes.append(test__get_candidate_names)
195
196
197class test__mkstemp_inner(TC):
198 """Test the internal function _mkstemp_inner."""
199
200 class mkstemped:
201 _bflags = tempfile._bin_openflags
202 _tflags = tempfile._text_openflags
203 _close = os.close
204 _unlink = os.unlink
205
206 def __init__(self, dir, pre, suf, bin):
207 if bin: flags = self._bflags
208 else: flags = self._tflags
209
210 (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags)
211
212 def write(self, str):
213 os.write(self.fd, str)
214
215 def __del__(self):
216 self._close(self.fd)
217 self._unlink(self.name)
Tim Petersa0d55de2002-08-09 18:01:01 +0000218
Guido van Rossum0e548712002-08-09 16:14:33 +0000219 def do_create(self, dir=None, pre="", suf="", bin=1):
220 if dir is None:
221 dir = tempfile.gettempdir()
222 try:
223 file = self.mkstemped(dir, pre, suf, bin)
224 except:
225 self.failOnException("_mkstemp_inner")
226
227 self.nameCheck(file.name, dir, pre, suf)
228 return file
229
230 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000231 # _mkstemp_inner can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000232 self.do_create().write("blat")
233 self.do_create(pre="a").write("blat")
234 self.do_create(suf="b").write("blat")
235 self.do_create(pre="a", suf="b").write("blat")
236 self.do_create(pre="aa", suf=".txt").write("blat")
237
238 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000239 # _mkstemp_inner can create many files (stochastic)
Neal Norwitz68ee0122002-08-16 19:28:59 +0000240 extant = range(TEST_FILES)
Guido van Rossum0e548712002-08-09 16:14:33 +0000241 for i in extant:
242 extant[i] = self.do_create(pre="aa")
243
244 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000245 # _mkstemp_inner can create files in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000246 dir = tempfile.mkdtemp()
247 try:
248 self.do_create(dir=dir).write("blat")
249 finally:
250 os.rmdir(dir)
251
252 def test_file_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000253 # _mkstemp_inner creates files with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000254 if not has_stat:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000255 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000256
257 file = self.do_create()
258 mode = stat.S_IMODE(os.stat(file.name).st_mode)
Tim Petersca3ac7f2002-08-09 18:13:51 +0000259 expected = 0600
Jack Jansence921472003-01-08 16:30:34 +0000260 if sys.platform in ('win32', 'os2emx', 'mac'):
Tim Petersca3ac7f2002-08-09 18:13:51 +0000261 # There's no distinction among 'user', 'group' and 'world';
262 # replicate the 'user' bits.
263 user = expected >> 6
264 expected = user * (1 + 8 + 64)
265 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000266
267 def test_noinherit(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000268 # _mkstemp_inner file handles are not inherited by child processes
Guido van Rossum78741062002-08-17 11:41:01 +0000269 if not has_spawnl:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000270 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000271
Guido van Rossum78741062002-08-17 11:41:01 +0000272 if test_support.verbose:
273 v="v"
274 else:
275 v="q"
276
Guido van Rossum0e548712002-08-09 16:14:33 +0000277 file = self.do_create()
Guido van Rossum78741062002-08-17 11:41:01 +0000278 fd = "%d" % file.fd
279
280 try:
281 me = __file__
282 except NameError:
283 me = sys.argv[0]
Guido van Rossum0e548712002-08-09 16:14:33 +0000284
285 # We have to exec something, so that FD_CLOEXEC will take
Guido van Rossum78741062002-08-17 11:41:01 +0000286 # effect. The core of this test is therefore in
287 # tf_inherit_check.py, which see.
288 tester = os.path.join(os.path.dirname(os.path.abspath(me)),
289 "tf_inherit_check.py")
Guido van Rossum0e548712002-08-09 16:14:33 +0000290
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000291 # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted,
292 # but an arg with embedded spaces should be decorated with double
293 # quotes on each end
Armin Rigo66d41b22007-12-07 19:19:55 +0000294 if sys.platform in ('win32',):
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000295 decorated = '"%s"' % sys.executable
296 tester = '"%s"' % tester
297 else:
298 decorated = sys.executable
299
300 retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000301 self.assertFalse(retval < 0,
Guido van Rossum78741062002-08-17 11:41:01 +0000302 "child process caught fatal signal %d" % -retval)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000303 self.assertFalse(retval > 0, "child process reports failure %d"%retval)
Guido van Rossum0e548712002-08-09 16:14:33 +0000304
305 def test_textmode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000306 # _mkstemp_inner can create files in text mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000307 if not has_textmode:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000308 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000309
310 self.do_create(bin=0).write("blat\n")
311 # XXX should test that the file really is a text file
312
313test_classes.append(test__mkstemp_inner)
314
315
316class test_gettempprefix(TC):
317 """Test gettempprefix()."""
318
319 def test_sane_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000320 # gettempprefix returns a nonempty prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000321 p = tempfile.gettempprefix()
322
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000323 self.assertIsInstance(p, basestring)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000324 self.assertTrue(len(p) > 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000325
326 def test_usable_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000327 # gettempprefix returns a usable prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000328
329 # Create a temp directory, avoiding use of the prefix.
330 # Then attempt to create a file whose name is
331 # prefix + 'xxxxxx.xxx' in that directory.
332 p = tempfile.gettempprefix() + "xxxxxx.xxx"
333 d = tempfile.mkdtemp(prefix="")
334 try:
335 p = os.path.join(d, p)
336 try:
337 fd = os.open(p, os.O_RDWR | os.O_CREAT)
338 except:
339 self.failOnException("os.open")
340 os.close(fd)
341 os.unlink(p)
342 finally:
343 os.rmdir(d)
344
345test_classes.append(test_gettempprefix)
346
347
348class test_gettempdir(TC):
349 """Test gettempdir()."""
350
351 def test_directory_exists(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000352 # gettempdir returns a directory which exists
Guido van Rossum0e548712002-08-09 16:14:33 +0000353
354 dir = tempfile.gettempdir()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000355 self.assertTrue(os.path.isabs(dir) or dir == os.curdir,
Guido van Rossum0e548712002-08-09 16:14:33 +0000356 "%s is not an absolute path" % dir)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000357 self.assertTrue(os.path.isdir(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +0000358 "%s is not a directory" % dir)
359
360 def test_directory_writable(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000361 # gettempdir returns a directory writable by the user
Guido van Rossum0e548712002-08-09 16:14:33 +0000362
363 # sneaky: just instantiate a NamedTemporaryFile, which
364 # defaults to writing into the directory returned by
365 # gettempdir.
366 try:
367 file = tempfile.NamedTemporaryFile()
368 file.write("blat")
369 file.close()
370 except:
371 self.failOnException("create file in %s" % tempfile.gettempdir())
372
373 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000374 # gettempdir always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000375 a = tempfile.gettempdir()
376 b = tempfile.gettempdir()
377
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000378 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000379
380test_classes.append(test_gettempdir)
381
382
383class test_mkstemp(TC):
384 """Test mkstemp()."""
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000385
Martin Blais215f13d2006-06-06 12:46:55 +0000386 def do_create(self, dir=None, pre="", suf=""):
Guido van Rossum0e548712002-08-09 16:14:33 +0000387 if dir is None:
388 dir = tempfile.gettempdir()
389 try:
390 (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf)
Martin v. Löwisd6625482003-10-12 17:37:01 +0000391 (ndir, nbase) = os.path.split(name)
392 adir = os.path.abspath(dir)
393 self.assertEqual(adir, ndir,
394 "Directory '%s' incorrectly returned as '%s'" % (adir, ndir))
Guido van Rossum0e548712002-08-09 16:14:33 +0000395 except:
396 self.failOnException("mkstemp")
397
398 try:
399 self.nameCheck(name, dir, pre, suf)
400 finally:
401 os.close(fd)
402 os.unlink(name)
403
404 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000405 # mkstemp can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000406 self.do_create()
407 self.do_create(pre="a")
408 self.do_create(suf="b")
409 self.do_create(pre="a", suf="b")
410 self.do_create(pre="aa", suf=".txt")
Martin v. Löwisd6625482003-10-12 17:37:01 +0000411 self.do_create(dir=".")
Guido van Rossum0e548712002-08-09 16:14:33 +0000412
413 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000414 # mkstemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000415 dir = tempfile.mkdtemp()
416 try:
417 self.do_create(dir=dir)
418 finally:
419 os.rmdir(dir)
420
421test_classes.append(test_mkstemp)
422
423
424class test_mkdtemp(TC):
425 """Test mkdtemp()."""
426
427 def do_create(self, dir=None, pre="", suf=""):
428 if dir is None:
429 dir = tempfile.gettempdir()
430 try:
431 name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf)
432 except:
433 self.failOnException("mkdtemp")
434
435 try:
436 self.nameCheck(name, dir, pre, suf)
437 return name
438 except:
439 os.rmdir(name)
440 raise
441
442 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000443 # mkdtemp can create directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000444 os.rmdir(self.do_create())
445 os.rmdir(self.do_create(pre="a"))
446 os.rmdir(self.do_create(suf="b"))
447 os.rmdir(self.do_create(pre="a", suf="b"))
448 os.rmdir(self.do_create(pre="aa", suf=".txt"))
Tim Petersa0d55de2002-08-09 18:01:01 +0000449
Guido van Rossum0e548712002-08-09 16:14:33 +0000450 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000451 # mkdtemp can create many directories (stochastic)
Neal Norwitz68ee0122002-08-16 19:28:59 +0000452 extant = range(TEST_FILES)
Guido van Rossum0e548712002-08-09 16:14:33 +0000453 try:
454 for i in extant:
455 extant[i] = self.do_create(pre="aa")
456 finally:
457 for i in extant:
458 if(isinstance(i, basestring)):
459 os.rmdir(i)
460
461 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000462 # mkdtemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000463 dir = tempfile.mkdtemp()
464 try:
465 os.rmdir(self.do_create(dir=dir))
466 finally:
467 os.rmdir(dir)
468
469 def test_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000470 # mkdtemp creates directories with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000471 if not has_stat:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000472 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000473
474 dir = self.do_create()
475 try:
476 mode = stat.S_IMODE(os.stat(dir).st_mode)
Guido van Rossum59db96f2004-03-31 18:53:29 +0000477 mode &= 0777 # Mask off sticky bits inherited from /tmp
Tim Petersca3ac7f2002-08-09 18:13:51 +0000478 expected = 0700
Jack Jansence921472003-01-08 16:30:34 +0000479 if sys.platform in ('win32', 'os2emx', 'mac'):
Tim Petersca3ac7f2002-08-09 18:13:51 +0000480 # There's no distinction among 'user', 'group' and 'world';
481 # replicate the 'user' bits.
482 user = expected >> 6
483 expected = user * (1 + 8 + 64)
484 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000485 finally:
486 os.rmdir(dir)
487
488test_classes.append(test_mkdtemp)
489
490
491class test_mktemp(TC):
492 """Test mktemp()."""
493
494 # For safety, all use of mktemp must occur in a private directory.
495 # We must also suppress the RuntimeWarning it generates.
496 def setUp(self):
497 self.dir = tempfile.mkdtemp()
Guido van Rossum0e548712002-08-09 16:14:33 +0000498
499 def tearDown(self):
500 if self.dir:
501 os.rmdir(self.dir)
502 self.dir = None
Guido van Rossum0e548712002-08-09 16:14:33 +0000503
504 class mktemped:
505 _unlink = os.unlink
506 _bflags = tempfile._bin_openflags
507
508 def __init__(self, dir, pre, suf):
509 self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf)
510 # Create the file. This will raise an exception if it's
511 # mysteriously appeared in the meanwhile.
512 os.close(os.open(self.name, self._bflags, 0600))
513
514 def __del__(self):
515 self._unlink(self.name)
516
517 def do_create(self, pre="", suf=""):
518 try:
519 file = self.mktemped(self.dir, pre, suf)
520 except:
521 self.failOnException("mktemp")
522
523 self.nameCheck(file.name, self.dir, pre, suf)
524 return file
525
526 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000527 # mktemp can choose usable file names
Guido van Rossum0e548712002-08-09 16:14:33 +0000528 self.do_create()
529 self.do_create(pre="a")
530 self.do_create(suf="b")
531 self.do_create(pre="a", suf="b")
532 self.do_create(pre="aa", suf=".txt")
533
534 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000535 # mktemp can choose many usable file names (stochastic)
Neal Norwitz68ee0122002-08-16 19:28:59 +0000536 extant = range(TEST_FILES)
Guido van Rossum0e548712002-08-09 16:14:33 +0000537 for i in extant:
538 extant[i] = self.do_create(pre="aa")
539
Fred Drake8bec4832002-11-22 20:13:43 +0000540## def test_warning(self):
541## # mktemp issues a warning when used
542## warnings.filterwarnings("error",
543## category=RuntimeWarning,
544## message="mktemp")
545## self.assertRaises(RuntimeWarning,
546## tempfile.mktemp, dir=self.dir)
Guido van Rossum0e548712002-08-09 16:14:33 +0000547
548test_classes.append(test_mktemp)
549
550
551# We test _TemporaryFileWrapper by testing NamedTemporaryFile.
552
553
554class test_NamedTemporaryFile(TC):
555 """Test NamedTemporaryFile()."""
556
Georg Brandl35ef9c12007-03-13 18:31:49 +0000557 def do_create(self, dir=None, pre="", suf="", delete=True):
Guido van Rossum0e548712002-08-09 16:14:33 +0000558 if dir is None:
559 dir = tempfile.gettempdir()
560 try:
Georg Brandl35ef9c12007-03-13 18:31:49 +0000561 file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf,
Georg Brandl4168c042007-03-13 19:18:18 +0000562 delete=delete)
Guido van Rossum0e548712002-08-09 16:14:33 +0000563 except:
564 self.failOnException("NamedTemporaryFile")
565
566 self.nameCheck(file.name, dir, pre, suf)
567 return file
568
569
570 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000571 # NamedTemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000572 self.do_create()
573 self.do_create(pre="a")
574 self.do_create(suf="b")
575 self.do_create(pre="a", suf="b")
576 self.do_create(pre="aa", suf=".txt")
577
578 def test_creates_named(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000579 # NamedTemporaryFile creates files with names
Guido van Rossum0e548712002-08-09 16:14:33 +0000580 f = tempfile.NamedTemporaryFile()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000581 self.assertTrue(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000582 "NamedTemporaryFile %s does not exist" % f.name)
583
584 def test_del_on_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000585 # A NamedTemporaryFile is deleted when closed
Guido van Rossum0e548712002-08-09 16:14:33 +0000586 dir = tempfile.mkdtemp()
587 try:
588 f = tempfile.NamedTemporaryFile(dir=dir)
589 f.write('blat')
590 f.close()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000591 self.assertFalse(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000592 "NamedTemporaryFile %s exists after close" % f.name)
593 finally:
594 os.rmdir(dir)
595
Georg Brandl35ef9c12007-03-13 18:31:49 +0000596 def test_dis_del_on_close(self):
597 # Tests that delete-on-close can be disabled
598 dir = tempfile.mkdtemp()
Georg Brandl4168c042007-03-13 19:18:18 +0000599 tmp = None
Georg Brandl35ef9c12007-03-13 18:31:49 +0000600 try:
601 f = tempfile.NamedTemporaryFile(dir=dir, delete=False)
602 tmp = f.name
603 f.write('blat')
604 f.close()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000605 self.assertTrue(os.path.exists(f.name),
Georg Brandl35ef9c12007-03-13 18:31:49 +0000606 "NamedTemporaryFile %s missing after close" % f.name)
607 finally:
608 if tmp is not None:
609 os.unlink(tmp)
610 os.rmdir(dir)
611
Guido van Rossum0e548712002-08-09 16:14:33 +0000612 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000613 # A NamedTemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000614 f = tempfile.NamedTemporaryFile()
615 f.write('abc\n')
616 f.close()
617 try:
618 f.close()
619 f.close()
620 except:
621 self.failOnException("close")
622
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000623 def test_context_manager(self):
624 # A NamedTemporaryFile can be used as a context manager
625 with tempfile.NamedTemporaryFile() as f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000626 self.assertTrue(os.path.exists(f.name))
627 self.assertFalse(os.path.exists(f.name))
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000628 def use_closed():
629 with f:
630 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000631 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000632
Guido van Rossum0e548712002-08-09 16:14:33 +0000633 # How to test the mode and bufsize parameters?
634
635test_classes.append(test_NamedTemporaryFile)
636
Collin Wintera8785cc2007-03-19 18:52:08 +0000637class test_SpooledTemporaryFile(TC):
638 """Test SpooledTemporaryFile()."""
639
640 def do_create(self, max_size=0, dir=None, pre="", suf=""):
641 if dir is None:
642 dir = tempfile.gettempdir()
643 try:
644 file = tempfile.SpooledTemporaryFile(max_size=max_size, dir=dir, prefix=pre, suffix=suf)
645 except:
646 self.failOnException("SpooledTemporaryFile")
647
648 return file
649
650
651 def test_basic(self):
652 # SpooledTemporaryFile can create files
653 f = self.do_create()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000654 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000655 f = self.do_create(max_size=100, pre="a", suf=".txt")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000656 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000657
658 def test_del_on_close(self):
659 # A SpooledTemporaryFile is deleted when closed
660 dir = tempfile.mkdtemp()
661 try:
662 f = tempfile.SpooledTemporaryFile(max_size=10, dir=dir)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000663 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000664 f.write('blat ' * 5)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000665 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000666 filename = f.name
667 f.close()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000668 self.assertFalse(os.path.exists(filename),
Collin Wintera8785cc2007-03-19 18:52:08 +0000669 "SpooledTemporaryFile %s exists after close" % filename)
670 finally:
671 os.rmdir(dir)
672
673 def test_rewrite_small(self):
674 # A SpooledTemporaryFile can be written to multiple within the max_size
675 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000676 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000677 for i in range(5):
678 f.seek(0, 0)
679 f.write('x' * 20)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000680 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000681
682 def test_write_sequential(self):
683 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
684 # over afterward
685 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000686 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000687 f.write('x' * 20)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000688 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000689 f.write('x' * 10)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000690 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000691 f.write('x')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000692 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000693
694 def test_sparse(self):
695 # A SpooledTemporaryFile that is written late in the file will extend
696 # when that occurs
697 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000698 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000699 f.seek(100, 0)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000700 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000701 f.write('x')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000702 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000703
704 def test_fileno(self):
705 # A SpooledTemporaryFile should roll over to a real file on fileno()
706 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000707 self.assertFalse(f._rolled)
708 self.assertTrue(f.fileno() > 0)
709 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000710
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000711 def test_multiple_close_before_rollover(self):
Collin Wintera8785cc2007-03-19 18:52:08 +0000712 # A SpooledTemporaryFile can be closed many times without error
713 f = tempfile.SpooledTemporaryFile()
714 f.write('abc\n')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000715 self.assertFalse(f._rolled)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000716 f.close()
717 try:
718 f.close()
719 f.close()
720 except:
721 self.failOnException("close")
722
723 def test_multiple_close_after_rollover(self):
724 # A SpooledTemporaryFile can be closed many times without error
725 f = tempfile.SpooledTemporaryFile(max_size=1)
726 f.write('abc\n')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000727 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000728 f.close()
729 try:
730 f.close()
731 f.close()
732 except:
733 self.failOnException("close")
734
735 def test_bound_methods(self):
736 # It should be OK to steal a bound method from a SpooledTemporaryFile
737 # and use it independently; when the file rolls over, those bound
738 # methods should continue to function
739 f = self.do_create(max_size=30)
740 read = f.read
741 write = f.write
742 seek = f.seek
743
744 write("a" * 35)
745 write("b" * 35)
746 seek(0, 0)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000747 self.assertTrue(read(70) == 'a'*35 + 'b'*35)
Collin Wintera8785cc2007-03-19 18:52:08 +0000748
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000749 def test_context_manager_before_rollover(self):
750 # A SpooledTemporaryFile can be used as a context manager
751 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000752 self.assertFalse(f._rolled)
753 self.assertFalse(f.closed)
754 self.assertTrue(f.closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000755 def use_closed():
756 with f:
757 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000758 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000759
760 def test_context_manager_during_rollover(self):
761 # A SpooledTemporaryFile can be used as a context manager
762 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000763 self.assertFalse(f._rolled)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000764 f.write('abc\n')
765 f.flush()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000766 self.assertTrue(f._rolled)
767 self.assertFalse(f.closed)
768 self.assertTrue(f.closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000769 def use_closed():
770 with f:
771 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000772 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000773
774 def test_context_manager_after_rollover(self):
775 # A SpooledTemporaryFile can be used as a context manager
776 f = tempfile.SpooledTemporaryFile(max_size=1)
777 f.write('abc\n')
778 f.flush()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000779 self.assertTrue(f._rolled)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000780 with f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000781 self.assertFalse(f.closed)
782 self.assertTrue(f.closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000783 def use_closed():
784 with f:
785 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000786 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000787
788
Collin Wintera8785cc2007-03-19 18:52:08 +0000789test_classes.append(test_SpooledTemporaryFile)
790
Guido van Rossum0e548712002-08-09 16:14:33 +0000791
792class test_TemporaryFile(TC):
793 """Test TemporaryFile()."""
794
795 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000796 # TemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000797 # No point in testing the name params - the file has no name.
798 try:
799 tempfile.TemporaryFile()
800 except:
801 self.failOnException("TemporaryFile")
802
803 def test_has_no_name(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000804 # TemporaryFile creates files with no names (on this system)
Guido van Rossum0e548712002-08-09 16:14:33 +0000805 dir = tempfile.mkdtemp()
806 f = tempfile.TemporaryFile(dir=dir)
807 f.write('blat')
808
809 # Sneaky: because this file has no name, it should not prevent
810 # us from removing the directory it was created in.
811 try:
812 os.rmdir(dir)
813 except:
814 ei = sys.exc_info()
815 # cleanup
816 f.close()
817 os.rmdir(dir)
818 self.failOnException("rmdir", ei)
819
820 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000821 # A TemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000822 f = tempfile.TemporaryFile()
823 f.write('abc\n')
824 f.close()
825 try:
826 f.close()
827 f.close()
828 except:
829 self.failOnException("close")
830
831 # How to test the mode and bufsize parameters?
832
Guido van Rossum0e548712002-08-09 16:14:33 +0000833
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000834if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
Guido van Rossum0e548712002-08-09 16:14:33 +0000835 test_classes.append(test_TemporaryFile)
836
837def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000838 test_support.run_unittest(*test_classes)
Guido van Rossum0e548712002-08-09 16:14:33 +0000839
840if __name__ == "__main__":
841 test_main()