| 1 | # tempfile.py unit tests.
|
|---|
| 2 |
|
|---|
| 3 | import tempfile
|
|---|
| 4 | import os
|
|---|
| 5 | import sys
|
|---|
| 6 | import re
|
|---|
| 7 | import errno
|
|---|
| 8 | import warnings
|
|---|
| 9 |
|
|---|
| 10 | import unittest
|
|---|
| 11 | from test import test_support
|
|---|
| 12 |
|
|---|
| 13 | warnings.filterwarnings("ignore",
|
|---|
| 14 | category=RuntimeWarning,
|
|---|
| 15 | message="mktemp", module=__name__)
|
|---|
| 16 |
|
|---|
| 17 | if hasattr(os, 'stat'):
|
|---|
| 18 | import stat
|
|---|
| 19 | has_stat = 1
|
|---|
| 20 | else:
|
|---|
| 21 | has_stat = 0
|
|---|
| 22 |
|
|---|
| 23 | has_textmode = (tempfile._text_openflags != tempfile._bin_openflags)
|
|---|
| 24 | has_spawnl = hasattr(os, 'spawnl')
|
|---|
| 25 |
|
|---|
| 26 | # TEST_FILES may need to be tweaked for systems depending on the maximum
|
|---|
| 27 | # number of files that can be opened at one time (see ulimit -n)
|
|---|
| 28 | if sys.platform == 'mac':
|
|---|
| 29 | TEST_FILES = 32
|
|---|
| 30 | elif sys.platform in ('openbsd3', 'openbsd4'):
|
|---|
| 31 | TEST_FILES = 48
|
|---|
| 32 | else:
|
|---|
| 33 | TEST_FILES = 100
|
|---|
| 34 |
|
|---|
| 35 | # This is organized as one test for each chunk of code in tempfile.py,
|
|---|
| 36 | # in order of their appearance in the file. Testing which requires
|
|---|
| 37 | # threads is not done here.
|
|---|
| 38 |
|
|---|
| 39 | # Common functionality.
|
|---|
| 40 | class TC(unittest.TestCase):
|
|---|
| 41 |
|
|---|
| 42 | str_check = re.compile(r"[a-zA-Z0-9_-]{6}$")
|
|---|
| 43 |
|
|---|
| 44 | def failOnException(self, what, ei=None):
|
|---|
| 45 | if ei is None:
|
|---|
| 46 | ei = sys.exc_info()
|
|---|
| 47 | self.fail("%s raised %s: %s" % (what, ei[0], ei[1]))
|
|---|
| 48 |
|
|---|
| 49 | def nameCheck(self, name, dir, pre, suf):
|
|---|
| 50 | (ndir, nbase) = os.path.split(name)
|
|---|
| 51 | npre = nbase[:len(pre)]
|
|---|
| 52 | nsuf = nbase[len(nbase)-len(suf):]
|
|---|
| 53 |
|
|---|
| 54 | # check for equality of the absolute paths!
|
|---|
| 55 | self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir),
|
|---|
| 56 | "file '%s' not in directory '%s'" % (name, dir))
|
|---|
| 57 | self.assertEqual(npre, pre,
|
|---|
| 58 | "file '%s' does not begin with '%s'" % (nbase, pre))
|
|---|
| 59 | self.assertEqual(nsuf, suf,
|
|---|
| 60 | "file '%s' does not end with '%s'" % (nbase, suf))
|
|---|
| 61 |
|
|---|
| 62 | nbase = nbase[len(pre):len(nbase)-len(suf)]
|
|---|
| 63 | self.assert_(self.str_check.match(nbase),
|
|---|
| 64 | "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/"
|
|---|
| 65 | % nbase)
|
|---|
| 66 |
|
|---|
| 67 | test_classes = []
|
|---|
| 68 |
|
|---|
| 69 | class test_exports(TC):
|
|---|
| 70 | def test_exports(self):
|
|---|
| 71 | # There are no surprising symbols in the tempfile module
|
|---|
| 72 | dict = tempfile.__dict__
|
|---|
| 73 |
|
|---|
| 74 | expected = {
|
|---|
| 75 | "NamedTemporaryFile" : 1,
|
|---|
| 76 | "TemporaryFile" : 1,
|
|---|
| 77 | "mkstemp" : 1,
|
|---|
| 78 | "mkdtemp" : 1,
|
|---|
| 79 | "mktemp" : 1,
|
|---|
| 80 | "TMP_MAX" : 1,
|
|---|
| 81 | "gettempprefix" : 1,
|
|---|
| 82 | "gettempdir" : 1,
|
|---|
| 83 | "tempdir" : 1,
|
|---|
| 84 | "template" : 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=""):
|
|---|
| 565 | if dir is None:
|
|---|
| 566 | dir = tempfile.gettempdir()
|
|---|
| 567 | try:
|
|---|
| 568 | file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf)
|
|---|
| 569 | except:
|
|---|
| 570 | self.failOnException("NamedTemporaryFile")
|
|---|
| 571 |
|
|---|
| 572 | self.nameCheck(file.name, dir, pre, suf)
|
|---|
| 573 | return file
|
|---|
| 574 |
|
|---|
| 575 |
|
|---|
| 576 | def test_basic(self):
|
|---|
| 577 | # NamedTemporaryFile can create files
|
|---|
| 578 | self.do_create()
|
|---|
| 579 | self.do_create(pre="a")
|
|---|
| 580 | self.do_create(suf="b")
|
|---|
| 581 | self.do_create(pre="a", suf="b")
|
|---|
| 582 | self.do_create(pre="aa", suf=".txt")
|
|---|
| 583 |
|
|---|
| 584 | def test_creates_named(self):
|
|---|
| 585 | # NamedTemporaryFile creates files with names
|
|---|
| 586 | f = tempfile.NamedTemporaryFile()
|
|---|
| 587 | self.failUnless(os.path.exists(f.name),
|
|---|
| 588 | "NamedTemporaryFile %s does not exist" % f.name)
|
|---|
| 589 |
|
|---|
| 590 | def test_del_on_close(self):
|
|---|
| 591 | # A NamedTemporaryFile is deleted when closed
|
|---|
| 592 | dir = tempfile.mkdtemp()
|
|---|
| 593 | try:
|
|---|
| 594 | f = tempfile.NamedTemporaryFile(dir=dir)
|
|---|
| 595 | f.write('blat')
|
|---|
| 596 | f.close()
|
|---|
| 597 | self.failIf(os.path.exists(f.name),
|
|---|
| 598 | "NamedTemporaryFile %s exists after close" % f.name)
|
|---|
| 599 | finally:
|
|---|
| 600 | os.rmdir(dir)
|
|---|
| 601 |
|
|---|
| 602 | def test_multiple_close(self):
|
|---|
| 603 | # A NamedTemporaryFile can be closed many times without error
|
|---|
| 604 |
|
|---|
| 605 | f = tempfile.NamedTemporaryFile()
|
|---|
| 606 | f.write('abc\n')
|
|---|
| 607 | f.close()
|
|---|
| 608 | try:
|
|---|
| 609 | f.close()
|
|---|
| 610 | f.close()
|
|---|
| 611 | except:
|
|---|
| 612 | self.failOnException("close")
|
|---|
| 613 |
|
|---|
| 614 | # How to test the mode and bufsize parameters?
|
|---|
| 615 |
|
|---|
| 616 | test_classes.append(test_NamedTemporaryFile)
|
|---|
| 617 |
|
|---|
| 618 |
|
|---|
| 619 | class test_TemporaryFile(TC):
|
|---|
| 620 | """Test TemporaryFile()."""
|
|---|
| 621 |
|
|---|
| 622 | def test_basic(self):
|
|---|
| 623 | # TemporaryFile can create files
|
|---|
| 624 | # No point in testing the name params - the file has no name.
|
|---|
| 625 | try:
|
|---|
| 626 | tempfile.TemporaryFile()
|
|---|
| 627 | except:
|
|---|
| 628 | self.failOnException("TemporaryFile")
|
|---|
| 629 |
|
|---|
| 630 | def test_has_no_name(self):
|
|---|
| 631 | # TemporaryFile creates files with no names (on this system)
|
|---|
| 632 | dir = tempfile.mkdtemp()
|
|---|
| 633 | f = tempfile.TemporaryFile(dir=dir)
|
|---|
| 634 | f.write('blat')
|
|---|
| 635 |
|
|---|
| 636 | # Sneaky: because this file has no name, it should not prevent
|
|---|
| 637 | # us from removing the directory it was created in.
|
|---|
| 638 | try:
|
|---|
| 639 | os.rmdir(dir)
|
|---|
| 640 | except:
|
|---|
| 641 | ei = sys.exc_info()
|
|---|
| 642 | # cleanup
|
|---|
| 643 | f.close()
|
|---|
| 644 | os.rmdir(dir)
|
|---|
| 645 | self.failOnException("rmdir", ei)
|
|---|
| 646 |
|
|---|
| 647 | def test_multiple_close(self):
|
|---|
| 648 | # A TemporaryFile can be closed many times without error
|
|---|
| 649 | f = tempfile.TemporaryFile()
|
|---|
| 650 | f.write('abc\n')
|
|---|
| 651 | f.close()
|
|---|
| 652 | try:
|
|---|
| 653 | f.close()
|
|---|
| 654 | f.close()
|
|---|
| 655 | except:
|
|---|
| 656 | self.failOnException("close")
|
|---|
| 657 |
|
|---|
| 658 | # How to test the mode and bufsize parameters?
|
|---|
| 659 |
|
|---|
| 660 |
|
|---|
| 661 | if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
|
|---|
| 662 | test_classes.append(test_TemporaryFile)
|
|---|
| 663 |
|
|---|
| 664 | def test_main():
|
|---|
| 665 | test_support.run_unittest(*test_classes)
|
|---|
| 666 |
|
|---|
| 667 | if __name__ == "__main__":
|
|---|
| 668 | test_main()
|
|---|