|
1 # tempfile.py unit tests. |
|
2 import tempfile |
|
3 import os |
|
4 import sys |
|
5 import re |
|
6 import errno |
|
7 import warnings |
|
8 |
|
9 import unittest |
|
10 from test import test_support |
|
11 |
|
12 warnings.filterwarnings("ignore", |
|
13 category=RuntimeWarning, |
|
14 message="mktemp", module=__name__) |
|
15 |
|
16 if hasattr(os, 'stat'): |
|
17 import stat |
|
18 has_stat = 1 |
|
19 else: |
|
20 has_stat = 0 |
|
21 |
|
22 has_textmode = (tempfile._text_openflags != tempfile._bin_openflags) |
|
23 has_spawnl = hasattr(os, 'spawnl') |
|
24 |
|
25 # TEST_FILES may need to be tweaked for systems depending on the maximum |
|
26 # number of files that can be opened at one time (see ulimit -n) |
|
27 if sys.platform == 'mac': |
|
28 TEST_FILES = 32 |
|
29 elif sys.platform in ('openbsd3', 'openbsd4'): |
|
30 TEST_FILES = 48 |
|
31 else: |
|
32 TEST_FILES = 100 |
|
33 |
|
34 # This is organized as one test for each chunk of code in tempfile.py, |
|
35 # in order of their appearance in the file. Testing which requires |
|
36 # threads is not done here. |
|
37 |
|
38 # Common functionality. |
|
39 class TC(unittest.TestCase): |
|
40 |
|
41 str_check = re.compile(r"[a-zA-Z0-9_-]{6}$") |
|
42 |
|
43 def failOnException(self, what, ei=None): |
|
44 if ei is None: |
|
45 ei = sys.exc_info() |
|
46 self.fail("%s raised %s: %s" % (what, ei[0], ei[1])) |
|
47 |
|
48 def nameCheck(self, name, dir, pre, suf): |
|
49 (ndir, nbase) = os.path.split(name) |
|
50 npre = nbase[:len(pre)] |
|
51 nsuf = nbase[len(nbase)-len(suf):] |
|
52 |
|
53 # check for equality of the absolute paths! |
|
54 self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir), |
|
55 "file '%s' not in directory '%s'" % (name, dir)) |
|
56 self.assertEqual(npre, pre, |
|
57 "file '%s' does not begin with '%s'" % (nbase, pre)) |
|
58 self.assertEqual(nsuf, suf, |
|
59 "file '%s' does not end with '%s'" % (nbase, suf)) |
|
60 |
|
61 nbase = nbase[len(pre):len(nbase)-len(suf)] |
|
62 self.assert_(self.str_check.match(nbase), |
|
63 "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/" |
|
64 % nbase) |
|
65 |
|
66 test_classes = [] |
|
67 |
|
68 class test_exports(TC): |
|
69 def test_exports(self): |
|
70 # There are no surprising symbols in the tempfile module |
|
71 dict = tempfile.__dict__ |
|
72 |
|
73 expected = { |
|
74 "NamedTemporaryFile" : 1, |
|
75 "TemporaryFile" : 1, |
|
76 "mkstemp" : 1, |
|
77 "mkdtemp" : 1, |
|
78 "mktemp" : 1, |
|
79 "TMP_MAX" : 1, |
|
80 "gettempprefix" : 1, |
|
81 "gettempdir" : 1, |
|
82 "tempdir" : 1, |
|
83 "template" : 1, |
|
84 "SpooledTemporaryFile" : 1 |
|
85 } |
|
86 |
|
87 unexp = [] |
|
88 for key in dict: |
|
89 if key[0] != '_' and key not in expected: |
|
90 unexp.append(key) |
|
91 self.failUnless(len(unexp) == 0, |
|
92 "unexpected keys: %s" % unexp) |
|
93 |
|
94 test_classes.append(test_exports) |
|
95 |
|
96 |
|
97 class test__RandomNameSequence(TC): |
|
98 """Test the internal iterator object _RandomNameSequence.""" |
|
99 |
|
100 def setUp(self): |
|
101 self.r = tempfile._RandomNameSequence() |
|
102 |
|
103 def test_get_six_char_str(self): |
|
104 # _RandomNameSequence returns a six-character string |
|
105 s = self.r.next() |
|
106 self.nameCheck(s, '', '', '') |
|
107 |
|
108 def test_many(self): |
|
109 # _RandomNameSequence returns no duplicate strings (stochastic) |
|
110 |
|
111 dict = {} |
|
112 r = self.r |
|
113 for i in xrange(TEST_FILES): |
|
114 s = r.next() |
|
115 self.nameCheck(s, '', '', '') |
|
116 self.failIf(s in dict) |
|
117 dict[s] = 1 |
|
118 |
|
119 def test_supports_iter(self): |
|
120 # _RandomNameSequence supports the iterator protocol |
|
121 |
|
122 i = 0 |
|
123 r = self.r |
|
124 try: |
|
125 for s in r: |
|
126 i += 1 |
|
127 if i == 20: |
|
128 break |
|
129 except: |
|
130 failOnException("iteration") |
|
131 |
|
132 test_classes.append(test__RandomNameSequence) |
|
133 |
|
134 |
|
135 class test__candidate_tempdir_list(TC): |
|
136 """Test the internal function _candidate_tempdir_list.""" |
|
137 |
|
138 def test_nonempty_list(self): |
|
139 # _candidate_tempdir_list returns a nonempty list of strings |
|
140 |
|
141 cand = tempfile._candidate_tempdir_list() |
|
142 |
|
143 self.failIf(len(cand) == 0) |
|
144 for c in cand: |
|
145 self.assert_(isinstance(c, basestring), |
|
146 "%s is not a string" % c) |
|
147 |
|
148 def test_wanted_dirs(self): |
|
149 # _candidate_tempdir_list contains the expected directories |
|
150 |
|
151 # Make sure the interesting environment variables are all set. |
|
152 added = [] |
|
153 try: |
|
154 for envname in 'TMPDIR', 'TEMP', 'TMP': |
|
155 dirname = os.getenv(envname) |
|
156 if not dirname: |
|
157 os.environ[envname] = os.path.abspath(envname) |
|
158 added.append(envname) |
|
159 |
|
160 cand = tempfile._candidate_tempdir_list() |
|
161 |
|
162 for envname in 'TMPDIR', 'TEMP', 'TMP': |
|
163 dirname = os.getenv(envname) |
|
164 if not dirname: raise ValueError |
|
165 self.assert_(dirname in cand) |
|
166 |
|
167 try: |
|
168 dirname = os.getcwd() |
|
169 except (AttributeError, os.error): |
|
170 dirname = os.curdir |
|
171 |
|
172 self.assert_(dirname in cand) |
|
173 |
|
174 # Not practical to try to verify the presence of OS-specific |
|
175 # paths in this list. |
|
176 finally: |
|
177 for p in added: |
|
178 del os.environ[p] |
|
179 |
|
180 test_classes.append(test__candidate_tempdir_list) |
|
181 |
|
182 |
|
183 # We test _get_default_tempdir by testing gettempdir. |
|
184 |
|
185 |
|
186 class test__get_candidate_names(TC): |
|
187 """Test the internal function _get_candidate_names.""" |
|
188 |
|
189 def test_retval(self): |
|
190 # _get_candidate_names returns a _RandomNameSequence object |
|
191 obj = tempfile._get_candidate_names() |
|
192 self.assert_(isinstance(obj, tempfile._RandomNameSequence)) |
|
193 |
|
194 def test_same_thing(self): |
|
195 # _get_candidate_names always returns the same object |
|
196 a = tempfile._get_candidate_names() |
|
197 b = tempfile._get_candidate_names() |
|
198 |
|
199 self.assert_(a is b) |
|
200 |
|
201 test_classes.append(test__get_candidate_names) |
|
202 |
|
203 |
|
204 class test__mkstemp_inner(TC): |
|
205 """Test the internal function _mkstemp_inner.""" |
|
206 |
|
207 class mkstemped: |
|
208 _bflags = tempfile._bin_openflags |
|
209 _tflags = tempfile._text_openflags |
|
210 _close = os.close |
|
211 _unlink = os.unlink |
|
212 |
|
213 def __init__(self, dir, pre, suf, bin): |
|
214 if bin: flags = self._bflags |
|
215 else: flags = self._tflags |
|
216 |
|
217 (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags) |
|
218 |
|
219 def write(self, str): |
|
220 os.write(self.fd, str) |
|
221 |
|
222 def __del__(self): |
|
223 self._close(self.fd) |
|
224 self._unlink(self.name) |
|
225 |
|
226 def do_create(self, dir=None, pre="", suf="", bin=1): |
|
227 if dir is None: |
|
228 dir = tempfile.gettempdir() |
|
229 try: |
|
230 file = self.mkstemped(dir, pre, suf, bin) |
|
231 except: |
|
232 self.failOnException("_mkstemp_inner") |
|
233 |
|
234 self.nameCheck(file.name, dir, pre, suf) |
|
235 return file |
|
236 |
|
237 def test_basic(self): |
|
238 # _mkstemp_inner can create files |
|
239 self.do_create().write("blat") |
|
240 self.do_create(pre="a").write("blat") |
|
241 self.do_create(suf="b").write("blat") |
|
242 self.do_create(pre="a", suf="b").write("blat") |
|
243 self.do_create(pre="aa", suf=".txt").write("blat") |
|
244 |
|
245 def test_basic_many(self): |
|
246 # _mkstemp_inner can create many files (stochastic) |
|
247 extant = range(TEST_FILES) |
|
248 for i in extant: |
|
249 extant[i] = self.do_create(pre="aa") |
|
250 |
|
251 def test_choose_directory(self): |
|
252 # _mkstemp_inner can create files in a user-selected directory |
|
253 dir = tempfile.mkdtemp() |
|
254 try: |
|
255 self.do_create(dir=dir).write("blat") |
|
256 finally: |
|
257 os.rmdir(dir) |
|
258 |
|
259 def test_file_mode(self): |
|
260 # _mkstemp_inner creates files with the proper mode |
|
261 if not has_stat: |
|
262 return # ugh, can't use TestSkipped. |
|
263 |
|
264 file = self.do_create() |
|
265 mode = stat.S_IMODE(os.stat(file.name).st_mode) |
|
266 expected = 0600 |
|
267 if sys.platform in ('win32', 'os2emx', 'mac'): |
|
268 # There's no distinction among 'user', 'group' and 'world'; |
|
269 # replicate the 'user' bits. |
|
270 user = expected >> 6 |
|
271 expected = user * (1 + 8 + 64) |
|
272 self.assertEqual(mode, expected) |
|
273 |
|
274 def test_noinherit(self): |
|
275 # _mkstemp_inner file handles are not inherited by child processes |
|
276 if not has_spawnl: |
|
277 return # ugh, can't use TestSkipped. |
|
278 |
|
279 if test_support.verbose: |
|
280 v="v" |
|
281 else: |
|
282 v="q" |
|
283 |
|
284 file = self.do_create() |
|
285 fd = "%d" % file.fd |
|
286 |
|
287 try: |
|
288 me = __file__ |
|
289 except NameError: |
|
290 me = sys.argv[0] |
|
291 |
|
292 # We have to exec something, so that FD_CLOEXEC will take |
|
293 # effect. The core of this test is therefore in |
|
294 # tf_inherit_check.py, which see. |
|
295 tester = os.path.join(os.path.dirname(os.path.abspath(me)), |
|
296 "tf_inherit_check.py") |
|
297 |
|
298 # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted, |
|
299 # but an arg with embedded spaces should be decorated with double |
|
300 # quotes on each end |
|
301 if sys.platform in ('win32',): |
|
302 decorated = '"%s"' % sys.executable |
|
303 tester = '"%s"' % tester |
|
304 else: |
|
305 decorated = sys.executable |
|
306 |
|
307 retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd) |
|
308 self.failIf(retval < 0, |
|
309 "child process caught fatal signal %d" % -retval) |
|
310 self.failIf(retval > 0, "child process reports failure %d"%retval) |
|
311 |
|
312 def test_textmode(self): |
|
313 # _mkstemp_inner can create files in text mode |
|
314 if not has_textmode: |
|
315 return # ugh, can't use TestSkipped. |
|
316 |
|
317 self.do_create(bin=0).write("blat\n") |
|
318 # XXX should test that the file really is a text file |
|
319 |
|
320 test_classes.append(test__mkstemp_inner) |
|
321 |
|
322 |
|
323 class test_gettempprefix(TC): |
|
324 """Test gettempprefix().""" |
|
325 |
|
326 def test_sane_template(self): |
|
327 # gettempprefix returns a nonempty prefix string |
|
328 p = tempfile.gettempprefix() |
|
329 |
|
330 self.assert_(isinstance(p, basestring)) |
|
331 self.assert_(len(p) > 0) |
|
332 |
|
333 def test_usable_template(self): |
|
334 # gettempprefix returns a usable prefix string |
|
335 |
|
336 # Create a temp directory, avoiding use of the prefix. |
|
337 # Then attempt to create a file whose name is |
|
338 # prefix + 'xxxxxx.xxx' in that directory. |
|
339 p = tempfile.gettempprefix() + "xxxxxx.xxx" |
|
340 d = tempfile.mkdtemp(prefix="") |
|
341 try: |
|
342 p = os.path.join(d, p) |
|
343 try: |
|
344 fd = os.open(p, os.O_RDWR | os.O_CREAT) |
|
345 except: |
|
346 self.failOnException("os.open") |
|
347 os.close(fd) |
|
348 os.unlink(p) |
|
349 finally: |
|
350 os.rmdir(d) |
|
351 |
|
352 test_classes.append(test_gettempprefix) |
|
353 |
|
354 |
|
355 class test_gettempdir(TC): |
|
356 """Test gettempdir().""" |
|
357 |
|
358 def test_directory_exists(self): |
|
359 # gettempdir returns a directory which exists |
|
360 |
|
361 dir = tempfile.gettempdir() |
|
362 self.assert_(os.path.isabs(dir) or dir == os.curdir, |
|
363 "%s is not an absolute path" % dir) |
|
364 self.assert_(os.path.isdir(dir), |
|
365 "%s is not a directory" % dir) |
|
366 |
|
367 def test_directory_writable(self): |
|
368 # gettempdir returns a directory writable by the user |
|
369 |
|
370 # sneaky: just instantiate a NamedTemporaryFile, which |
|
371 # defaults to writing into the directory returned by |
|
372 # gettempdir. |
|
373 try: |
|
374 file = tempfile.NamedTemporaryFile() |
|
375 file.write("blat") |
|
376 file.close() |
|
377 except: |
|
378 self.failOnException("create file in %s" % tempfile.gettempdir()) |
|
379 |
|
380 def test_same_thing(self): |
|
381 # gettempdir always returns the same object |
|
382 a = tempfile.gettempdir() |
|
383 b = tempfile.gettempdir() |
|
384 |
|
385 self.assert_(a is b) |
|
386 |
|
387 test_classes.append(test_gettempdir) |
|
388 |
|
389 |
|
390 class test_mkstemp(TC): |
|
391 """Test mkstemp().""" |
|
392 |
|
393 def do_create(self, dir=None, pre="", suf=""): |
|
394 if dir is None: |
|
395 dir = tempfile.gettempdir() |
|
396 try: |
|
397 (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf) |
|
398 (ndir, nbase) = os.path.split(name) |
|
399 adir = os.path.abspath(dir) |
|
400 self.assertEqual(adir, ndir, |
|
401 "Directory '%s' incorrectly returned as '%s'" % (adir, ndir)) |
|
402 except: |
|
403 self.failOnException("mkstemp") |
|
404 |
|
405 try: |
|
406 self.nameCheck(name, dir, pre, suf) |
|
407 finally: |
|
408 os.close(fd) |
|
409 os.unlink(name) |
|
410 |
|
411 def test_basic(self): |
|
412 # mkstemp can create files |
|
413 self.do_create() |
|
414 self.do_create(pre="a") |
|
415 self.do_create(suf="b") |
|
416 self.do_create(pre="a", suf="b") |
|
417 self.do_create(pre="aa", suf=".txt") |
|
418 self.do_create(dir=".") |
|
419 |
|
420 def test_choose_directory(self): |
|
421 # mkstemp can create directories in a user-selected directory |
|
422 dir = tempfile.mkdtemp() |
|
423 try: |
|
424 self.do_create(dir=dir) |
|
425 finally: |
|
426 os.rmdir(dir) |
|
427 |
|
428 test_classes.append(test_mkstemp) |
|
429 |
|
430 |
|
431 class test_mkdtemp(TC): |
|
432 """Test mkdtemp().""" |
|
433 |
|
434 def do_create(self, dir=None, pre="", suf=""): |
|
435 if dir is None: |
|
436 dir = tempfile.gettempdir() |
|
437 try: |
|
438 name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf) |
|
439 except: |
|
440 self.failOnException("mkdtemp") |
|
441 |
|
442 try: |
|
443 self.nameCheck(name, dir, pre, suf) |
|
444 return name |
|
445 except: |
|
446 os.rmdir(name) |
|
447 raise |
|
448 |
|
449 def test_basic(self): |
|
450 # mkdtemp can create directories |
|
451 os.rmdir(self.do_create()) |
|
452 os.rmdir(self.do_create(pre="a")) |
|
453 os.rmdir(self.do_create(suf="b")) |
|
454 os.rmdir(self.do_create(pre="a", suf="b")) |
|
455 os.rmdir(self.do_create(pre="aa", suf=".txt")) |
|
456 |
|
457 def test_basic_many(self): |
|
458 # mkdtemp can create many directories (stochastic) |
|
459 extant = range(TEST_FILES) |
|
460 try: |
|
461 for i in extant: |
|
462 extant[i] = self.do_create(pre="aa") |
|
463 finally: |
|
464 for i in extant: |
|
465 if(isinstance(i, basestring)): |
|
466 os.rmdir(i) |
|
467 |
|
468 def test_choose_directory(self): |
|
469 # mkdtemp can create directories in a user-selected directory |
|
470 dir = tempfile.mkdtemp() |
|
471 try: |
|
472 os.rmdir(self.do_create(dir=dir)) |
|
473 finally: |
|
474 os.rmdir(dir) |
|
475 |
|
476 def test_mode(self): |
|
477 # mkdtemp creates directories with the proper mode |
|
478 if not has_stat: |
|
479 return # ugh, can't use TestSkipped. |
|
480 |
|
481 dir = self.do_create() |
|
482 try: |
|
483 mode = stat.S_IMODE(os.stat(dir).st_mode) |
|
484 mode &= 0777 # Mask off sticky bits inherited from /tmp |
|
485 expected = 0700 |
|
486 if sys.platform in ('win32', 'os2emx', 'mac'): |
|
487 # There's no distinction among 'user', 'group' and 'world'; |
|
488 # replicate the 'user' bits. |
|
489 user = expected >> 6 |
|
490 expected = user * (1 + 8 + 64) |
|
491 self.assertEqual(mode, expected) |
|
492 finally: |
|
493 os.rmdir(dir) |
|
494 |
|
495 test_classes.append(test_mkdtemp) |
|
496 |
|
497 |
|
498 class test_mktemp(TC): |
|
499 """Test mktemp().""" |
|
500 |
|
501 # For safety, all use of mktemp must occur in a private directory. |
|
502 # We must also suppress the RuntimeWarning it generates. |
|
503 def setUp(self): |
|
504 self.dir = tempfile.mkdtemp() |
|
505 |
|
506 def tearDown(self): |
|
507 if self.dir: |
|
508 os.rmdir(self.dir) |
|
509 self.dir = None |
|
510 |
|
511 class mktemped: |
|
512 _unlink = os.unlink |
|
513 _bflags = tempfile._bin_openflags |
|
514 |
|
515 def __init__(self, dir, pre, suf): |
|
516 self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf) |
|
517 # Create the file. This will raise an exception if it's |
|
518 # mysteriously appeared in the meanwhile. |
|
519 os.close(os.open(self.name, self._bflags, 0600)) |
|
520 |
|
521 def __del__(self): |
|
522 self._unlink(self.name) |
|
523 |
|
524 def do_create(self, pre="", suf=""): |
|
525 try: |
|
526 file = self.mktemped(self.dir, pre, suf) |
|
527 except: |
|
528 self.failOnException("mktemp") |
|
529 |
|
530 self.nameCheck(file.name, self.dir, pre, suf) |
|
531 return file |
|
532 |
|
533 def test_basic(self): |
|
534 # mktemp can choose usable file names |
|
535 self.do_create() |
|
536 self.do_create(pre="a") |
|
537 self.do_create(suf="b") |
|
538 self.do_create(pre="a", suf="b") |
|
539 self.do_create(pre="aa", suf=".txt") |
|
540 |
|
541 def test_many(self): |
|
542 # mktemp can choose many usable file names (stochastic) |
|
543 extant = range(TEST_FILES) |
|
544 for i in extant: |
|
545 extant[i] = self.do_create(pre="aa") |
|
546 |
|
547 ## def test_warning(self): |
|
548 ## # mktemp issues a warning when used |
|
549 ## warnings.filterwarnings("error", |
|
550 ## category=RuntimeWarning, |
|
551 ## message="mktemp") |
|
552 ## self.assertRaises(RuntimeWarning, |
|
553 ## tempfile.mktemp, dir=self.dir) |
|
554 |
|
555 test_classes.append(test_mktemp) |
|
556 |
|
557 |
|
558 # We test _TemporaryFileWrapper by testing NamedTemporaryFile. |
|
559 |
|
560 |
|
561 class test_NamedTemporaryFile(TC): |
|
562 """Test NamedTemporaryFile().""" |
|
563 |
|
564 def do_create(self, dir=None, pre="", suf="", delete=True): |
|
565 if dir is None: |
|
566 dir = tempfile.gettempdir() |
|
567 try: |
|
568 file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf, |
|
569 delete=delete) |
|
570 except: |
|
571 self.failOnException("NamedTemporaryFile") |
|
572 |
|
573 self.nameCheck(file.name, dir, pre, suf) |
|
574 return file |
|
575 |
|
576 |
|
577 def test_basic(self): |
|
578 # NamedTemporaryFile can create files |
|
579 self.do_create() |
|
580 self.do_create(pre="a") |
|
581 self.do_create(suf="b") |
|
582 self.do_create(pre="a", suf="b") |
|
583 self.do_create(pre="aa", suf=".txt") |
|
584 |
|
585 def test_creates_named(self): |
|
586 # NamedTemporaryFile creates files with names |
|
587 f = tempfile.NamedTemporaryFile() |
|
588 self.failUnless(os.path.exists(f.name), |
|
589 "NamedTemporaryFile %s does not exist" % f.name) |
|
590 |
|
591 def test_del_on_close(self): |
|
592 # A NamedTemporaryFile is deleted when closed |
|
593 dir = tempfile.mkdtemp() |
|
594 try: |
|
595 f = tempfile.NamedTemporaryFile(dir=dir) |
|
596 f.write('blat') |
|
597 f.close() |
|
598 self.failIf(os.path.exists(f.name), |
|
599 "NamedTemporaryFile %s exists after close" % f.name) |
|
600 finally: |
|
601 os.rmdir(dir) |
|
602 |
|
603 def test_dis_del_on_close(self): |
|
604 # Tests that delete-on-close can be disabled |
|
605 dir = tempfile.mkdtemp() |
|
606 tmp = None |
|
607 try: |
|
608 f = tempfile.NamedTemporaryFile(dir=dir, delete=False) |
|
609 tmp = f.name |
|
610 f.write('blat') |
|
611 f.close() |
|
612 self.failUnless(os.path.exists(f.name), |
|
613 "NamedTemporaryFile %s missing after close" % f.name) |
|
614 finally: |
|
615 if tmp is not None: |
|
616 os.unlink(tmp) |
|
617 os.rmdir(dir) |
|
618 |
|
619 def test_multiple_close(self): |
|
620 # A NamedTemporaryFile can be closed many times without error |
|
621 f = tempfile.NamedTemporaryFile() |
|
622 f.write('abc\n') |
|
623 f.close() |
|
624 try: |
|
625 f.close() |
|
626 f.close() |
|
627 except: |
|
628 self.failOnException("close") |
|
629 |
|
630 def test_context_manager(self): |
|
631 # A NamedTemporaryFile can be used as a context manager |
|
632 with tempfile.NamedTemporaryFile() as f: |
|
633 self.failUnless(os.path.exists(f.name)) |
|
634 self.failIf(os.path.exists(f.name)) |
|
635 def use_closed(): |
|
636 with f: |
|
637 pass |
|
638 self.failUnlessRaises(ValueError, use_closed) |
|
639 |
|
640 # How to test the mode and bufsize parameters? |
|
641 |
|
642 test_classes.append(test_NamedTemporaryFile) |
|
643 |
|
644 class test_SpooledTemporaryFile(TC): |
|
645 """Test SpooledTemporaryFile().""" |
|
646 |
|
647 def do_create(self, max_size=0, dir=None, pre="", suf=""): |
|
648 if dir is None: |
|
649 dir = tempfile.gettempdir() |
|
650 try: |
|
651 file = tempfile.SpooledTemporaryFile(max_size=max_size, dir=dir, prefix=pre, suffix=suf) |
|
652 except: |
|
653 self.failOnException("SpooledTemporaryFile") |
|
654 |
|
655 return file |
|
656 |
|
657 |
|
658 def test_basic(self): |
|
659 # SpooledTemporaryFile can create files |
|
660 f = self.do_create() |
|
661 self.failIf(f._rolled) |
|
662 f = self.do_create(max_size=100, pre="a", suf=".txt") |
|
663 self.failIf(f._rolled) |
|
664 |
|
665 def test_del_on_close(self): |
|
666 # A SpooledTemporaryFile is deleted when closed |
|
667 dir = tempfile.mkdtemp() |
|
668 try: |
|
669 f = tempfile.SpooledTemporaryFile(max_size=10, dir=dir) |
|
670 self.failIf(f._rolled) |
|
671 f.write('blat ' * 5) |
|
672 self.failUnless(f._rolled) |
|
673 filename = f.name |
|
674 f.close() |
|
675 self.failIf(os.path.exists(filename), |
|
676 "SpooledTemporaryFile %s exists after close" % filename) |
|
677 finally: |
|
678 os.rmdir(dir) |
|
679 |
|
680 def test_rewrite_small(self): |
|
681 # A SpooledTemporaryFile can be written to multiple within the max_size |
|
682 f = self.do_create(max_size=30) |
|
683 self.failIf(f._rolled) |
|
684 for i in range(5): |
|
685 f.seek(0, 0) |
|
686 f.write('x' * 20) |
|
687 self.failIf(f._rolled) |
|
688 |
|
689 def test_write_sequential(self): |
|
690 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll |
|
691 # over afterward |
|
692 f = self.do_create(max_size=30) |
|
693 self.failIf(f._rolled) |
|
694 f.write('x' * 20) |
|
695 self.failIf(f._rolled) |
|
696 f.write('x' * 10) |
|
697 self.failIf(f._rolled) |
|
698 f.write('x') |
|
699 self.failUnless(f._rolled) |
|
700 |
|
701 def test_sparse(self): |
|
702 # A SpooledTemporaryFile that is written late in the file will extend |
|
703 # when that occurs |
|
704 f = self.do_create(max_size=30) |
|
705 self.failIf(f._rolled) |
|
706 f.seek(100, 0) |
|
707 self.failIf(f._rolled) |
|
708 f.write('x') |
|
709 self.failUnless(f._rolled) |
|
710 |
|
711 def test_fileno(self): |
|
712 # A SpooledTemporaryFile should roll over to a real file on fileno() |
|
713 f = self.do_create(max_size=30) |
|
714 self.failIf(f._rolled) |
|
715 self.failUnless(f.fileno() > 0) |
|
716 self.failUnless(f._rolled) |
|
717 |
|
718 def test_multiple_close_before_rollover(self): |
|
719 # A SpooledTemporaryFile can be closed many times without error |
|
720 f = tempfile.SpooledTemporaryFile() |
|
721 f.write('abc\n') |
|
722 self.failIf(f._rolled) |
|
723 f.close() |
|
724 try: |
|
725 f.close() |
|
726 f.close() |
|
727 except: |
|
728 self.failOnException("close") |
|
729 |
|
730 def test_multiple_close_after_rollover(self): |
|
731 # A SpooledTemporaryFile can be closed many times without error |
|
732 f = tempfile.SpooledTemporaryFile(max_size=1) |
|
733 f.write('abc\n') |
|
734 self.failUnless(f._rolled) |
|
735 f.close() |
|
736 try: |
|
737 f.close() |
|
738 f.close() |
|
739 except: |
|
740 self.failOnException("close") |
|
741 |
|
742 def test_bound_methods(self): |
|
743 # It should be OK to steal a bound method from a SpooledTemporaryFile |
|
744 # and use it independently; when the file rolls over, those bound |
|
745 # methods should continue to function |
|
746 f = self.do_create(max_size=30) |
|
747 read = f.read |
|
748 write = f.write |
|
749 seek = f.seek |
|
750 |
|
751 write("a" * 35) |
|
752 write("b" * 35) |
|
753 seek(0, 0) |
|
754 self.failUnless(read(70) == 'a'*35 + 'b'*35) |
|
755 |
|
756 def test_context_manager_before_rollover(self): |
|
757 # A SpooledTemporaryFile can be used as a context manager |
|
758 with tempfile.SpooledTemporaryFile(max_size=1) as f: |
|
759 self.failIf(f._rolled) |
|
760 self.failIf(f.closed) |
|
761 self.failUnless(f.closed) |
|
762 def use_closed(): |
|
763 with f: |
|
764 pass |
|
765 self.failUnlessRaises(ValueError, use_closed) |
|
766 |
|
767 def test_context_manager_during_rollover(self): |
|
768 # A SpooledTemporaryFile can be used as a context manager |
|
769 with tempfile.SpooledTemporaryFile(max_size=1) as f: |
|
770 self.failIf(f._rolled) |
|
771 f.write('abc\n') |
|
772 f.flush() |
|
773 self.failUnless(f._rolled) |
|
774 self.failIf(f.closed) |
|
775 self.failUnless(f.closed) |
|
776 def use_closed(): |
|
777 with f: |
|
778 pass |
|
779 self.failUnlessRaises(ValueError, use_closed) |
|
780 |
|
781 def test_context_manager_after_rollover(self): |
|
782 # A SpooledTemporaryFile can be used as a context manager |
|
783 f = tempfile.SpooledTemporaryFile(max_size=1) |
|
784 f.write('abc\n') |
|
785 f.flush() |
|
786 self.failUnless(f._rolled) |
|
787 with f: |
|
788 self.failIf(f.closed) |
|
789 self.failUnless(f.closed) |
|
790 def use_closed(): |
|
791 with f: |
|
792 pass |
|
793 self.failUnlessRaises(ValueError, use_closed) |
|
794 |
|
795 |
|
796 test_classes.append(test_SpooledTemporaryFile) |
|
797 |
|
798 |
|
799 class test_TemporaryFile(TC): |
|
800 """Test TemporaryFile().""" |
|
801 |
|
802 def test_basic(self): |
|
803 # TemporaryFile can create files |
|
804 # No point in testing the name params - the file has no name. |
|
805 try: |
|
806 tempfile.TemporaryFile() |
|
807 except: |
|
808 self.failOnException("TemporaryFile") |
|
809 |
|
810 def test_has_no_name(self): |
|
811 # TemporaryFile creates files with no names (on this system) |
|
812 dir = tempfile.mkdtemp() |
|
813 f = tempfile.TemporaryFile(dir=dir) |
|
814 f.write('blat') |
|
815 |
|
816 # Sneaky: because this file has no name, it should not prevent |
|
817 # us from removing the directory it was created in. |
|
818 try: |
|
819 os.rmdir(dir) |
|
820 except: |
|
821 ei = sys.exc_info() |
|
822 # cleanup |
|
823 f.close() |
|
824 os.rmdir(dir) |
|
825 self.failOnException("rmdir", ei) |
|
826 |
|
827 def test_multiple_close(self): |
|
828 # A TemporaryFile can be closed many times without error |
|
829 f = tempfile.TemporaryFile() |
|
830 f.write('abc\n') |
|
831 f.close() |
|
832 try: |
|
833 f.close() |
|
834 f.close() |
|
835 except: |
|
836 self.failOnException("close") |
|
837 |
|
838 # How to test the mode and bufsize parameters? |
|
839 |
|
840 |
|
841 if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile: |
|
842 test_classes.append(test_TemporaryFile) |
|
843 |
|
844 def test_main(): |
|
845 test_support.run_unittest(*test_classes) |
|
846 |
|
847 if __name__ == "__main__": |
|
848 test_main() |