blob: 27068e3295a0d23874d121d6657b3e5905a0d7d6 [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)
Ronald Oussoren9545a232010-05-05 19:09:31 +000026if sys.platform in ('openbsd3', 'openbsd4'):
Martin v. Löwis99968282004-09-15 06:02:54 +000027 TEST_FILES = 48
Jack Jansence921472003-01-08 16:30:34 +000028else:
29 TEST_FILES = 100
Neal Norwitz68ee0122002-08-16 19:28:59 +000030
Guido van Rossum0e548712002-08-09 16:14:33 +000031# This is organized as one test for each chunk of code in tempfile.py,
32# in order of their appearance in the file. Testing which requires
33# threads is not done here.
34
35# Common functionality.
36class TC(unittest.TestCase):
37
38 str_check = re.compile(r"[a-zA-Z0-9_-]{6}$")
39
40 def failOnException(self, what, ei=None):
41 if ei is None:
42 ei = sys.exc_info()
43 self.fail("%s raised %s: %s" % (what, ei[0], ei[1]))
44
45 def nameCheck(self, name, dir, pre, suf):
46 (ndir, nbase) = os.path.split(name)
47 npre = nbase[:len(pre)]
48 nsuf = nbase[len(nbase)-len(suf):]
49
Martin v. Löwisd6625482003-10-12 17:37:01 +000050 # check for equality of the absolute paths!
51 self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +000052 "file '%s' not in directory '%s'" % (name, dir))
53 self.assertEqual(npre, pre,
54 "file '%s' does not begin with '%s'" % (nbase, pre))
55 self.assertEqual(nsuf, suf,
56 "file '%s' does not end with '%s'" % (nbase, suf))
57
58 nbase = nbase[len(pre):len(nbase)-len(suf)]
Benjamin Peterson5c8da862009-06-30 22:57:08 +000059 self.assertTrue(self.str_check.match(nbase),
Guido van Rossum0e548712002-08-09 16:14:33 +000060 "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/"
61 % nbase)
62
63test_classes = []
64
65class test_exports(TC):
66 def test_exports(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +000067 # There are no surprising symbols in the tempfile module
Guido van Rossum0e548712002-08-09 16:14:33 +000068 dict = tempfile.__dict__
69
70 expected = {
71 "NamedTemporaryFile" : 1,
72 "TemporaryFile" : 1,
73 "mkstemp" : 1,
74 "mkdtemp" : 1,
75 "mktemp" : 1,
76 "TMP_MAX" : 1,
77 "gettempprefix" : 1,
78 "gettempdir" : 1,
79 "tempdir" : 1,
Collin Wintera8785cc2007-03-19 18:52:08 +000080 "template" : 1,
81 "SpooledTemporaryFile" : 1
Guido van Rossum0e548712002-08-09 16:14:33 +000082 }
83
84 unexp = []
85 for key in dict:
86 if key[0] != '_' and key not in expected:
87 unexp.append(key)
Benjamin Peterson5c8da862009-06-30 22:57:08 +000088 self.assertTrue(len(unexp) == 0,
Guido van Rossum0e548712002-08-09 16:14:33 +000089 "unexpected keys: %s" % unexp)
90
91test_classes.append(test_exports)
92
93
Guido van Rossum0e548712002-08-09 16:14:33 +000094class test__RandomNameSequence(TC):
95 """Test the internal iterator object _RandomNameSequence."""
96
97 def setUp(self):
98 self.r = tempfile._RandomNameSequence()
99
100 def test_get_six_char_str(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000101 # _RandomNameSequence returns a six-character string
Guido van Rossum0e548712002-08-09 16:14:33 +0000102 s = self.r.next()
103 self.nameCheck(s, '', '', '')
104
105 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000106 # _RandomNameSequence returns no duplicate strings (stochastic)
Guido van Rossum0e548712002-08-09 16:14:33 +0000107
108 dict = {}
109 r = self.r
Neal Norwitz68ee0122002-08-16 19:28:59 +0000110 for i in xrange(TEST_FILES):
Guido van Rossum0e548712002-08-09 16:14:33 +0000111 s = r.next()
112 self.nameCheck(s, '', '', '')
Ezio Melottiaa980582010-01-23 23:04:36 +0000113 self.assertNotIn(s, dict)
Guido van Rossum0e548712002-08-09 16:14:33 +0000114 dict[s] = 1
115
116 def test_supports_iter(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000117 # _RandomNameSequence supports the iterator protocol
Guido van Rossum0e548712002-08-09 16:14:33 +0000118
119 i = 0
120 r = self.r
121 try:
122 for s in r:
123 i += 1
124 if i == 20:
125 break
126 except:
Georg Brandld10d8ee2010-02-06 23:18:00 +0000127 self.failOnException("iteration")
Guido van Rossum0e548712002-08-09 16:14:33 +0000128
129test_classes.append(test__RandomNameSequence)
130
131
132class test__candidate_tempdir_list(TC):
133 """Test the internal function _candidate_tempdir_list."""
134
135 def test_nonempty_list(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000136 # _candidate_tempdir_list returns a nonempty list of strings
Guido van Rossum0e548712002-08-09 16:14:33 +0000137
138 cand = tempfile._candidate_tempdir_list()
139
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000140 self.assertFalse(len(cand) == 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000141 for c in cand:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000142 self.assertIsInstance(c, basestring)
Guido van Rossum0e548712002-08-09 16:14:33 +0000143
144 def test_wanted_dirs(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000145 # _candidate_tempdir_list contains the expected directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000146
147 # Make sure the interesting environment variables are all set.
Walter Dörwald4b965f62009-04-26 20:51:44 +0000148 with test_support.EnvironmentVarGuard() as env:
Guido van Rossum0e548712002-08-09 16:14:33 +0000149 for envname in 'TMPDIR', 'TEMP', 'TMP':
150 dirname = os.getenv(envname)
151 if not dirname:
Walter Dörwald6733bed2009-05-01 17:35:37 +0000152 env[envname] = os.path.abspath(envname)
Guido van Rossum0e548712002-08-09 16:14:33 +0000153
154 cand = tempfile._candidate_tempdir_list()
155
156 for envname in 'TMPDIR', 'TEMP', 'TMP':
157 dirname = os.getenv(envname)
158 if not dirname: raise ValueError
Ezio Melottiaa980582010-01-23 23:04:36 +0000159 self.assertIn(dirname, cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000160
161 try:
162 dirname = os.getcwd()
163 except (AttributeError, os.error):
164 dirname = os.curdir
165
Ezio Melottiaa980582010-01-23 23:04:36 +0000166 self.assertIn(dirname, cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000167
168 # Not practical to try to verify the presence of OS-specific
169 # paths in this list.
Guido van Rossum0e548712002-08-09 16:14:33 +0000170
171test_classes.append(test__candidate_tempdir_list)
172
173
174# We test _get_default_tempdir by testing gettempdir.
175
176
177class test__get_candidate_names(TC):
178 """Test the internal function _get_candidate_names."""
179
180 def test_retval(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000181 # _get_candidate_names returns a _RandomNameSequence object
Guido van Rossum0e548712002-08-09 16:14:33 +0000182 obj = tempfile._get_candidate_names()
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000183 self.assertIsInstance(obj, tempfile._RandomNameSequence)
Guido van Rossum0e548712002-08-09 16:14:33 +0000184
185 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000186 # _get_candidate_names always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000187 a = tempfile._get_candidate_names()
188 b = tempfile._get_candidate_names()
189
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000190 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000191
192test_classes.append(test__get_candidate_names)
193
194
195class test__mkstemp_inner(TC):
196 """Test the internal function _mkstemp_inner."""
197
198 class mkstemped:
199 _bflags = tempfile._bin_openflags
200 _tflags = tempfile._text_openflags
201 _close = os.close
202 _unlink = os.unlink
203
204 def __init__(self, dir, pre, suf, bin):
205 if bin: flags = self._bflags
206 else: flags = self._tflags
207
208 (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags)
209
210 def write(self, str):
211 os.write(self.fd, str)
212
213 def __del__(self):
214 self._close(self.fd)
215 self._unlink(self.name)
Tim Petersa0d55de2002-08-09 18:01:01 +0000216
Guido van Rossum0e548712002-08-09 16:14:33 +0000217 def do_create(self, dir=None, pre="", suf="", bin=1):
218 if dir is None:
219 dir = tempfile.gettempdir()
220 try:
221 file = self.mkstemped(dir, pre, suf, bin)
222 except:
223 self.failOnException("_mkstemp_inner")
224
225 self.nameCheck(file.name, dir, pre, suf)
226 return file
227
228 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000229 # _mkstemp_inner can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000230 self.do_create().write("blat")
231 self.do_create(pre="a").write("blat")
232 self.do_create(suf="b").write("blat")
233 self.do_create(pre="a", suf="b").write("blat")
234 self.do_create(pre="aa", suf=".txt").write("blat")
235
236 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000237 # _mkstemp_inner can create many files (stochastic)
Neal Norwitz68ee0122002-08-16 19:28:59 +0000238 extant = range(TEST_FILES)
Guido van Rossum0e548712002-08-09 16:14:33 +0000239 for i in extant:
240 extant[i] = self.do_create(pre="aa")
241
242 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000243 # _mkstemp_inner can create files in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000244 dir = tempfile.mkdtemp()
245 try:
246 self.do_create(dir=dir).write("blat")
247 finally:
248 os.rmdir(dir)
249
250 def test_file_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000251 # _mkstemp_inner creates files with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000252 if not has_stat:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000253 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000254
255 file = self.do_create()
256 mode = stat.S_IMODE(os.stat(file.name).st_mode)
Tim Petersca3ac7f2002-08-09 18:13:51 +0000257 expected = 0600
Ronald Oussoren9545a232010-05-05 19:09:31 +0000258 if sys.platform in ('win32', 'os2emx'):
Tim Petersca3ac7f2002-08-09 18:13:51 +0000259 # There's no distinction among 'user', 'group' and 'world';
260 # replicate the 'user' bits.
261 user = expected >> 6
262 expected = user * (1 + 8 + 64)
263 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000264
265 def test_noinherit(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000266 # _mkstemp_inner file handles are not inherited by child processes
Guido van Rossum78741062002-08-17 11:41:01 +0000267 if not has_spawnl:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000268 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000269
Guido van Rossum78741062002-08-17 11:41:01 +0000270 if test_support.verbose:
271 v="v"
272 else:
273 v="q"
274
Guido van Rossum0e548712002-08-09 16:14:33 +0000275 file = self.do_create()
Guido van Rossum78741062002-08-17 11:41:01 +0000276 fd = "%d" % file.fd
277
278 try:
279 me = __file__
280 except NameError:
281 me = sys.argv[0]
Guido van Rossum0e548712002-08-09 16:14:33 +0000282
283 # We have to exec something, so that FD_CLOEXEC will take
Guido van Rossum78741062002-08-17 11:41:01 +0000284 # effect. The core of this test is therefore in
285 # tf_inherit_check.py, which see.
286 tester = os.path.join(os.path.dirname(os.path.abspath(me)),
287 "tf_inherit_check.py")
Guido van Rossum0e548712002-08-09 16:14:33 +0000288
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000289 # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted,
290 # but an arg with embedded spaces should be decorated with double
291 # quotes on each end
Armin Rigo66d41b22007-12-07 19:19:55 +0000292 if sys.platform in ('win32',):
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000293 decorated = '"%s"' % sys.executable
294 tester = '"%s"' % tester
295 else:
296 decorated = sys.executable
297
298 retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000299 self.assertFalse(retval < 0,
Guido van Rossum78741062002-08-17 11:41:01 +0000300 "child process caught fatal signal %d" % -retval)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000301 self.assertFalse(retval > 0, "child process reports failure %d"%retval)
Guido van Rossum0e548712002-08-09 16:14:33 +0000302
303 def test_textmode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000304 # _mkstemp_inner can create files in text mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000305 if not has_textmode:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000306 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000307
308 self.do_create(bin=0).write("blat\n")
309 # XXX should test that the file really is a text file
310
311test_classes.append(test__mkstemp_inner)
312
313
314class test_gettempprefix(TC):
315 """Test gettempprefix()."""
316
317 def test_sane_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000318 # gettempprefix returns a nonempty prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000319 p = tempfile.gettempprefix()
320
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000321 self.assertIsInstance(p, basestring)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000322 self.assertTrue(len(p) > 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000323
324 def test_usable_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000325 # gettempprefix returns a usable prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000326
327 # Create a temp directory, avoiding use of the prefix.
328 # Then attempt to create a file whose name is
329 # prefix + 'xxxxxx.xxx' in that directory.
330 p = tempfile.gettempprefix() + "xxxxxx.xxx"
331 d = tempfile.mkdtemp(prefix="")
332 try:
333 p = os.path.join(d, p)
334 try:
335 fd = os.open(p, os.O_RDWR | os.O_CREAT)
336 except:
337 self.failOnException("os.open")
338 os.close(fd)
339 os.unlink(p)
340 finally:
341 os.rmdir(d)
342
343test_classes.append(test_gettempprefix)
344
345
346class test_gettempdir(TC):
347 """Test gettempdir()."""
348
349 def test_directory_exists(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000350 # gettempdir returns a directory which exists
Guido van Rossum0e548712002-08-09 16:14:33 +0000351
352 dir = tempfile.gettempdir()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000353 self.assertTrue(os.path.isabs(dir) or dir == os.curdir,
Guido van Rossum0e548712002-08-09 16:14:33 +0000354 "%s is not an absolute path" % dir)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000355 self.assertTrue(os.path.isdir(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +0000356 "%s is not a directory" % dir)
357
358 def test_directory_writable(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000359 # gettempdir returns a directory writable by the user
Guido van Rossum0e548712002-08-09 16:14:33 +0000360
361 # sneaky: just instantiate a NamedTemporaryFile, which
362 # defaults to writing into the directory returned by
363 # gettempdir.
364 try:
365 file = tempfile.NamedTemporaryFile()
366 file.write("blat")
367 file.close()
368 except:
369 self.failOnException("create file in %s" % tempfile.gettempdir())
370
371 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000372 # gettempdir always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000373 a = tempfile.gettempdir()
374 b = tempfile.gettempdir()
375
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000376 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000377
378test_classes.append(test_gettempdir)
379
380
381class test_mkstemp(TC):
382 """Test mkstemp()."""
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000383
Martin Blais215f13d2006-06-06 12:46:55 +0000384 def do_create(self, dir=None, pre="", suf=""):
Guido van Rossum0e548712002-08-09 16:14:33 +0000385 if dir is None:
386 dir = tempfile.gettempdir()
387 try:
388 (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf)
Martin v. Löwisd6625482003-10-12 17:37:01 +0000389 (ndir, nbase) = os.path.split(name)
390 adir = os.path.abspath(dir)
391 self.assertEqual(adir, ndir,
392 "Directory '%s' incorrectly returned as '%s'" % (adir, ndir))
Guido van Rossum0e548712002-08-09 16:14:33 +0000393 except:
394 self.failOnException("mkstemp")
395
396 try:
397 self.nameCheck(name, dir, pre, suf)
398 finally:
399 os.close(fd)
400 os.unlink(name)
401
402 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000403 # mkstemp can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000404 self.do_create()
405 self.do_create(pre="a")
406 self.do_create(suf="b")
407 self.do_create(pre="a", suf="b")
408 self.do_create(pre="aa", suf=".txt")
Martin v. Löwisd6625482003-10-12 17:37:01 +0000409 self.do_create(dir=".")
Guido van Rossum0e548712002-08-09 16:14:33 +0000410
411 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000412 # mkstemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000413 dir = tempfile.mkdtemp()
414 try:
415 self.do_create(dir=dir)
416 finally:
417 os.rmdir(dir)
418
419test_classes.append(test_mkstemp)
420
421
422class test_mkdtemp(TC):
423 """Test mkdtemp()."""
424
425 def do_create(self, dir=None, pre="", suf=""):
426 if dir is None:
427 dir = tempfile.gettempdir()
428 try:
429 name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf)
430 except:
431 self.failOnException("mkdtemp")
432
433 try:
434 self.nameCheck(name, dir, pre, suf)
435 return name
436 except:
437 os.rmdir(name)
438 raise
439
440 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000441 # mkdtemp can create directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000442 os.rmdir(self.do_create())
443 os.rmdir(self.do_create(pre="a"))
444 os.rmdir(self.do_create(suf="b"))
445 os.rmdir(self.do_create(pre="a", suf="b"))
446 os.rmdir(self.do_create(pre="aa", suf=".txt"))
Tim Petersa0d55de2002-08-09 18:01:01 +0000447
Guido van Rossum0e548712002-08-09 16:14:33 +0000448 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000449 # mkdtemp can create many directories (stochastic)
Neal Norwitz68ee0122002-08-16 19:28:59 +0000450 extant = range(TEST_FILES)
Guido van Rossum0e548712002-08-09 16:14:33 +0000451 try:
452 for i in extant:
453 extant[i] = self.do_create(pre="aa")
454 finally:
455 for i in extant:
456 if(isinstance(i, basestring)):
457 os.rmdir(i)
458
459 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000460 # mkdtemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000461 dir = tempfile.mkdtemp()
462 try:
463 os.rmdir(self.do_create(dir=dir))
464 finally:
465 os.rmdir(dir)
466
467 def test_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000468 # mkdtemp creates directories with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000469 if not has_stat:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000470 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000471
472 dir = self.do_create()
473 try:
474 mode = stat.S_IMODE(os.stat(dir).st_mode)
Guido van Rossum59db96f2004-03-31 18:53:29 +0000475 mode &= 0777 # Mask off sticky bits inherited from /tmp
Tim Petersca3ac7f2002-08-09 18:13:51 +0000476 expected = 0700
Ronald Oussoren9545a232010-05-05 19:09:31 +0000477 if sys.platform in ('win32', 'os2emx'):
Tim Petersca3ac7f2002-08-09 18:13:51 +0000478 # There's no distinction among 'user', 'group' and 'world';
479 # replicate the 'user' bits.
480 user = expected >> 6
481 expected = user * (1 + 8 + 64)
482 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000483 finally:
484 os.rmdir(dir)
485
486test_classes.append(test_mkdtemp)
487
488
489class test_mktemp(TC):
490 """Test mktemp()."""
491
492 # For safety, all use of mktemp must occur in a private directory.
493 # We must also suppress the RuntimeWarning it generates.
494 def setUp(self):
495 self.dir = tempfile.mkdtemp()
Guido van Rossum0e548712002-08-09 16:14:33 +0000496
497 def tearDown(self):
498 if self.dir:
499 os.rmdir(self.dir)
500 self.dir = None
Guido van Rossum0e548712002-08-09 16:14:33 +0000501
502 class mktemped:
503 _unlink = os.unlink
504 _bflags = tempfile._bin_openflags
505
506 def __init__(self, dir, pre, suf):
507 self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf)
508 # Create the file. This will raise an exception if it's
509 # mysteriously appeared in the meanwhile.
510 os.close(os.open(self.name, self._bflags, 0600))
511
512 def __del__(self):
513 self._unlink(self.name)
514
515 def do_create(self, pre="", suf=""):
516 try:
517 file = self.mktemped(self.dir, pre, suf)
518 except:
519 self.failOnException("mktemp")
520
521 self.nameCheck(file.name, self.dir, pre, suf)
522 return file
523
524 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000525 # mktemp can choose usable file names
Guido van Rossum0e548712002-08-09 16:14:33 +0000526 self.do_create()
527 self.do_create(pre="a")
528 self.do_create(suf="b")
529 self.do_create(pre="a", suf="b")
530 self.do_create(pre="aa", suf=".txt")
531
532 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000533 # mktemp can choose many usable file names (stochastic)
Neal Norwitz68ee0122002-08-16 19:28:59 +0000534 extant = range(TEST_FILES)
Guido van Rossum0e548712002-08-09 16:14:33 +0000535 for i in extant:
536 extant[i] = self.do_create(pre="aa")
537
Fred Drake8bec4832002-11-22 20:13:43 +0000538## def test_warning(self):
539## # mktemp issues a warning when used
540## warnings.filterwarnings("error",
541## category=RuntimeWarning,
542## message="mktemp")
543## self.assertRaises(RuntimeWarning,
544## tempfile.mktemp, dir=self.dir)
Guido van Rossum0e548712002-08-09 16:14:33 +0000545
546test_classes.append(test_mktemp)
547
548
549# We test _TemporaryFileWrapper by testing NamedTemporaryFile.
550
551
552class test_NamedTemporaryFile(TC):
553 """Test NamedTemporaryFile()."""
554
Georg Brandl35ef9c12007-03-13 18:31:49 +0000555 def do_create(self, dir=None, pre="", suf="", delete=True):
Guido van Rossum0e548712002-08-09 16:14:33 +0000556 if dir is None:
557 dir = tempfile.gettempdir()
558 try:
Georg Brandl35ef9c12007-03-13 18:31:49 +0000559 file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf,
Georg Brandl4168c042007-03-13 19:18:18 +0000560 delete=delete)
Guido van Rossum0e548712002-08-09 16:14:33 +0000561 except:
562 self.failOnException("NamedTemporaryFile")
563
564 self.nameCheck(file.name, dir, pre, suf)
565 return file
566
567
568 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000569 # NamedTemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000570 self.do_create()
571 self.do_create(pre="a")
572 self.do_create(suf="b")
573 self.do_create(pre="a", suf="b")
574 self.do_create(pre="aa", suf=".txt")
575
576 def test_creates_named(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000577 # NamedTemporaryFile creates files with names
Guido van Rossum0e548712002-08-09 16:14:33 +0000578 f = tempfile.NamedTemporaryFile()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000579 self.assertTrue(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000580 "NamedTemporaryFile %s does not exist" % f.name)
581
582 def test_del_on_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000583 # A NamedTemporaryFile is deleted when closed
Guido van Rossum0e548712002-08-09 16:14:33 +0000584 dir = tempfile.mkdtemp()
585 try:
586 f = tempfile.NamedTemporaryFile(dir=dir)
587 f.write('blat')
588 f.close()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000589 self.assertFalse(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000590 "NamedTemporaryFile %s exists after close" % f.name)
591 finally:
592 os.rmdir(dir)
593
Georg Brandl35ef9c12007-03-13 18:31:49 +0000594 def test_dis_del_on_close(self):
595 # Tests that delete-on-close can be disabled
596 dir = tempfile.mkdtemp()
Georg Brandl4168c042007-03-13 19:18:18 +0000597 tmp = None
Georg Brandl35ef9c12007-03-13 18:31:49 +0000598 try:
599 f = tempfile.NamedTemporaryFile(dir=dir, delete=False)
600 tmp = f.name
601 f.write('blat')
602 f.close()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000603 self.assertTrue(os.path.exists(f.name),
Georg Brandl35ef9c12007-03-13 18:31:49 +0000604 "NamedTemporaryFile %s missing after close" % f.name)
605 finally:
606 if tmp is not None:
607 os.unlink(tmp)
608 os.rmdir(dir)
609
Guido van Rossum0e548712002-08-09 16:14:33 +0000610 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000611 # A NamedTemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000612 f = tempfile.NamedTemporaryFile()
613 f.write('abc\n')
614 f.close()
615 try:
616 f.close()
617 f.close()
618 except:
619 self.failOnException("close")
620
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000621 def test_context_manager(self):
622 # A NamedTemporaryFile can be used as a context manager
623 with tempfile.NamedTemporaryFile() as f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000624 self.assertTrue(os.path.exists(f.name))
625 self.assertFalse(os.path.exists(f.name))
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000626 def use_closed():
627 with f:
628 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000629 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000630
Guido van Rossum0e548712002-08-09 16:14:33 +0000631 # How to test the mode and bufsize parameters?
632
633test_classes.append(test_NamedTemporaryFile)
634
Collin Wintera8785cc2007-03-19 18:52:08 +0000635class test_SpooledTemporaryFile(TC):
636 """Test SpooledTemporaryFile()."""
637
638 def do_create(self, max_size=0, dir=None, pre="", suf=""):
639 if dir is None:
640 dir = tempfile.gettempdir()
641 try:
642 file = tempfile.SpooledTemporaryFile(max_size=max_size, dir=dir, prefix=pre, suffix=suf)
643 except:
644 self.failOnException("SpooledTemporaryFile")
645
646 return file
647
648
649 def test_basic(self):
650 # SpooledTemporaryFile can create files
651 f = self.do_create()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000652 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000653 f = self.do_create(max_size=100, pre="a", suf=".txt")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000654 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000655
656 def test_del_on_close(self):
657 # A SpooledTemporaryFile is deleted when closed
658 dir = tempfile.mkdtemp()
659 try:
660 f = tempfile.SpooledTemporaryFile(max_size=10, dir=dir)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000661 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000662 f.write('blat ' * 5)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000663 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000664 filename = f.name
665 f.close()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000666 self.assertFalse(os.path.exists(filename),
Collin Wintera8785cc2007-03-19 18:52:08 +0000667 "SpooledTemporaryFile %s exists after close" % filename)
668 finally:
669 os.rmdir(dir)
670
671 def test_rewrite_small(self):
672 # A SpooledTemporaryFile can be written to multiple within the max_size
673 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000674 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000675 for i in range(5):
676 f.seek(0, 0)
677 f.write('x' * 20)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000678 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000679
680 def test_write_sequential(self):
681 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
682 # over afterward
683 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000684 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000685 f.write('x' * 20)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000686 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000687 f.write('x' * 10)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000688 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000689 f.write('x')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000690 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000691
692 def test_sparse(self):
693 # A SpooledTemporaryFile that is written late in the file will extend
694 # when that occurs
695 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000696 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000697 f.seek(100, 0)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000698 self.assertFalse(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000699 f.write('x')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000700 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000701
702 def test_fileno(self):
703 # A SpooledTemporaryFile should roll over to a real file on fileno()
704 f = self.do_create(max_size=30)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000705 self.assertFalse(f._rolled)
706 self.assertTrue(f.fileno() > 0)
707 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000708
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000709 def test_multiple_close_before_rollover(self):
Collin Wintera8785cc2007-03-19 18:52:08 +0000710 # A SpooledTemporaryFile can be closed many times without error
711 f = tempfile.SpooledTemporaryFile()
712 f.write('abc\n')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000713 self.assertFalse(f._rolled)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000714 f.close()
715 try:
716 f.close()
717 f.close()
718 except:
719 self.failOnException("close")
720
721 def test_multiple_close_after_rollover(self):
722 # A SpooledTemporaryFile can be closed many times without error
723 f = tempfile.SpooledTemporaryFile(max_size=1)
724 f.write('abc\n')
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000725 self.assertTrue(f._rolled)
Collin Wintera8785cc2007-03-19 18:52:08 +0000726 f.close()
727 try:
728 f.close()
729 f.close()
730 except:
731 self.failOnException("close")
732
733 def test_bound_methods(self):
734 # It should be OK to steal a bound method from a SpooledTemporaryFile
735 # and use it independently; when the file rolls over, those bound
736 # methods should continue to function
737 f = self.do_create(max_size=30)
738 read = f.read
739 write = f.write
740 seek = f.seek
741
742 write("a" * 35)
743 write("b" * 35)
744 seek(0, 0)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000745 self.assertTrue(read(70) == 'a'*35 + 'b'*35)
Collin Wintera8785cc2007-03-19 18:52:08 +0000746
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000747 def test_context_manager_before_rollover(self):
748 # A SpooledTemporaryFile can be used as a context manager
749 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000750 self.assertFalse(f._rolled)
751 self.assertFalse(f.closed)
752 self.assertTrue(f.closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000753 def use_closed():
754 with f:
755 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000756 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000757
758 def test_context_manager_during_rollover(self):
759 # A SpooledTemporaryFile can be used as a context manager
760 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000761 self.assertFalse(f._rolled)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000762 f.write('abc\n')
763 f.flush()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000764 self.assertTrue(f._rolled)
765 self.assertFalse(f.closed)
766 self.assertTrue(f.closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000767 def use_closed():
768 with f:
769 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000770 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000771
772 def test_context_manager_after_rollover(self):
773 # A SpooledTemporaryFile can be used as a context manager
774 f = tempfile.SpooledTemporaryFile(max_size=1)
775 f.write('abc\n')
776 f.flush()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000777 self.assertTrue(f._rolled)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000778 with f:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000779 self.assertFalse(f.closed)
780 self.assertTrue(f.closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000781 def use_closed():
782 with f:
783 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000784 self.assertRaises(ValueError, use_closed)
Nick Coghlan97fac3e2008-02-09 15:28:09 +0000785
786
Collin Wintera8785cc2007-03-19 18:52:08 +0000787test_classes.append(test_SpooledTemporaryFile)
788
Guido van Rossum0e548712002-08-09 16:14:33 +0000789
790class test_TemporaryFile(TC):
791 """Test TemporaryFile()."""
792
793 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000794 # TemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000795 # No point in testing the name params - the file has no name.
796 try:
797 tempfile.TemporaryFile()
798 except:
799 self.failOnException("TemporaryFile")
800
801 def test_has_no_name(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000802 # TemporaryFile creates files with no names (on this system)
Guido van Rossum0e548712002-08-09 16:14:33 +0000803 dir = tempfile.mkdtemp()
804 f = tempfile.TemporaryFile(dir=dir)
805 f.write('blat')
806
807 # Sneaky: because this file has no name, it should not prevent
808 # us from removing the directory it was created in.
809 try:
810 os.rmdir(dir)
811 except:
812 ei = sys.exc_info()
813 # cleanup
814 f.close()
815 os.rmdir(dir)
816 self.failOnException("rmdir", ei)
817
818 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000819 # A TemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000820 f = tempfile.TemporaryFile()
821 f.write('abc\n')
822 f.close()
823 try:
824 f.close()
825 f.close()
826 except:
827 self.failOnException("close")
828
829 # How to test the mode and bufsize parameters?
830
Guido van Rossum0e548712002-08-09 16:14:33 +0000831
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000832if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
Guido van Rossum0e548712002-08-09 16:14:33 +0000833 test_classes.append(test_TemporaryFile)
834
835def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000836 test_support.run_unittest(*test_classes)
Guido van Rossum0e548712002-08-09 16:14:33 +0000837
838if __name__ == "__main__":
839 test_main()