blob: 73261e00b3d8d021ad096eca2c2d0e8a6e56d151 [file] [log] [blame]
Fred Drake38c2ef02001-07-17 20:52:51 +00001# As a test suite for the os module, this is woefully inadequate, but this
2# does add tests for a few functions which have been determined to be more
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00003# portable than they had been thought to be.
Fred Drake38c2ef02001-07-17 20:52:51 +00004
5import os
Benjamin Peterson5c6d7872009-02-06 02:40:07 +00006import errno
Fred Drake38c2ef02001-07-17 20:52:51 +00007import unittest
Jeremy Hyltona7fc21b2001-08-20 20:10:01 +00008import warnings
Thomas Wouters477c8d52006-05-27 19:21:47 +00009import sys
Brian Curtineb24d742010-04-12 17:16:38 +000010import signal
11import subprocess
12import time
Martin v. Löwis011e8422009-05-05 04:43:17 +000013import shutil
Benjamin Petersonee8712c2008-05-20 21:35:26 +000014from test import support
Victor Stinnerc2d095f2010-05-17 00:14:53 +000015import contextlib
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +000016import mmap
17import uuid
Fred Drake38c2ef02001-07-17 20:52:51 +000018
Mark Dickinson7cf03892010-04-16 13:45:35 +000019# Detect whether we're on a Linux system that uses the (now outdated
20# and unmaintained) linuxthreads threading library. There's an issue
21# when combining linuxthreads with a failed execv call: see
22# http://bugs.python.org/issue4970.
Mark Dickinson89589c92010-04-16 13:51:27 +000023if (hasattr(os, "confstr_names") and
24 "CS_GNU_LIBPTHREAD_VERSION" in os.confstr_names):
Mark Dickinson7cf03892010-04-16 13:45:35 +000025 libpthread = os.confstr("CS_GNU_LIBPTHREAD_VERSION")
26 USING_LINUXTHREADS= libpthread.startswith("linuxthreads")
27else:
28 USING_LINUXTHREADS= False
Brian Curtineb24d742010-04-12 17:16:38 +000029
Thomas Wouters0e3f5912006-08-11 14:57:12 +000030# Tests creating TESTFN
31class FileTests(unittest.TestCase):
32 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000033 if os.path.exists(support.TESTFN):
34 os.unlink(support.TESTFN)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000035 tearDown = setUp
36
37 def test_access(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000038 f = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000039 os.close(f)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000040 self.assertTrue(os.access(support.TESTFN, os.W_OK))
Thomas Wouters0e3f5912006-08-11 14:57:12 +000041
Christian Heimesfdab48e2008-01-20 09:06:41 +000042 def test_closerange(self):
Antoine Pitroub9ee06c2008-08-16 22:03:17 +000043 first = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR)
44 # We must allocate two consecutive file descriptors, otherwise
45 # it will mess up other file descriptors (perhaps even the three
46 # standard ones).
47 second = os.dup(first)
48 try:
49 retries = 0
50 while second != first + 1:
51 os.close(first)
52 retries += 1
53 if retries > 10:
54 # XXX test skipped
Benjamin Petersonfa0d7032009-06-01 22:42:33 +000055 self.skipTest("couldn't allocate two consecutive fds")
Antoine Pitroub9ee06c2008-08-16 22:03:17 +000056 first, second = second, os.dup(second)
57 finally:
58 os.close(second)
Christian Heimesfdab48e2008-01-20 09:06:41 +000059 # close a fd that is open, and one that isn't
Antoine Pitroub9ee06c2008-08-16 22:03:17 +000060 os.closerange(first, first + 2)
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +000061 self.assertRaises(OSError, os.write, first, b"a")
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062
Benjamin Peterson1cc6df92010-06-30 17:39:45 +000063 @support.cpython_only
Hirokazu Yamamoto4c19e6e2008-09-08 23:41:21 +000064 def test_rename(self):
65 path = support.TESTFN
66 old = sys.getrefcount(path)
67 self.assertRaises(TypeError, os.rename, path, 0)
68 new = sys.getrefcount(path)
69 self.assertEqual(old, new)
70
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +000071 def test_read(self):
72 with open(support.TESTFN, "w+b") as fobj:
73 fobj.write(b"spam")
74 fobj.flush()
75 fd = fobj.fileno()
76 os.lseek(fd, 0, 0)
77 s = os.read(fd, 4)
78 self.assertEqual(type(s), bytes)
79 self.assertEqual(s, b"spam")
80
81 def test_write(self):
82 # os.write() accepts bytes- and buffer-like objects but not strings
83 fd = os.open(support.TESTFN, os.O_CREAT | os.O_WRONLY)
84 self.assertRaises(TypeError, os.write, fd, "beans")
85 os.write(fd, b"bacon\n")
86 os.write(fd, bytearray(b"eggs\n"))
87 os.write(fd, memoryview(b"spam\n"))
88 os.close(fd)
89 with open(support.TESTFN, "rb") as fobj:
Antoine Pitroud62269f2008-09-15 23:54:52 +000090 self.assertEqual(fobj.read().splitlines(),
91 [b"bacon", b"eggs", b"spam"])
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +000092
93
Christian Heimesdd15f6c2008-03-16 00:07:10 +000094class TemporaryFileTests(unittest.TestCase):
95 def setUp(self):
96 self.files = []
Benjamin Petersonee8712c2008-05-20 21:35:26 +000097 os.mkdir(support.TESTFN)
Christian Heimesdd15f6c2008-03-16 00:07:10 +000098
99 def tearDown(self):
100 for name in self.files:
101 os.unlink(name)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000102 os.rmdir(support.TESTFN)
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000103
104 def check_tempfile(self, name):
105 # make sure it doesn't already exist:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000106 self.assertFalse(os.path.exists(name),
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000107 "file already exists for temporary file")
108 # make sure we can create the file
109 open(name, "w")
110 self.files.append(name)
111
112 def test_tempnam(self):
113 if not hasattr(os, "tempnam"):
114 return
115 warnings.filterwarnings("ignore", "tempnam", RuntimeWarning,
116 r"test_os$")
117 self.check_tempfile(os.tempnam())
118
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000119 name = os.tempnam(support.TESTFN)
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000120 self.check_tempfile(name)
121
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000122 name = os.tempnam(support.TESTFN, "pfx")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000123 self.assertTrue(os.path.basename(name)[:3] == "pfx")
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000124 self.check_tempfile(name)
125
126 def test_tmpfile(self):
127 if not hasattr(os, "tmpfile"):
128 return
129 # As with test_tmpnam() below, the Windows implementation of tmpfile()
130 # attempts to create a file in the root directory of the current drive.
131 # On Vista and Server 2008, this test will always fail for normal users
132 # as writing to the root directory requires elevated privileges. With
133 # XP and below, the semantics of tmpfile() are the same, but the user
134 # running the test is more likely to have administrative privileges on
135 # their account already. If that's the case, then os.tmpfile() should
136 # work. In order to make this test as useful as possible, rather than
137 # trying to detect Windows versions or whether or not the user has the
138 # right permissions, just try and create a file in the root directory
139 # and see if it raises a 'Permission denied' OSError. If it does, then
140 # test that a subsequent call to os.tmpfile() raises the same error. If
141 # it doesn't, assume we're on XP or below and the user running the test
142 # has administrative privileges, and proceed with the test as normal.
143 if sys.platform == 'win32':
144 name = '\\python_test_os_test_tmpfile.txt'
145 if os.path.exists(name):
146 os.remove(name)
147 try:
148 fp = open(name, 'w')
149 except IOError as first:
150 # open() failed, assert tmpfile() fails in the same way.
151 # Although open() raises an IOError and os.tmpfile() raises an
152 # OSError(), 'args' will be (13, 'Permission denied') in both
153 # cases.
154 try:
155 fp = os.tmpfile()
156 except OSError as second:
157 self.assertEqual(first.args, second.args)
158 else:
159 self.fail("expected os.tmpfile() to raise OSError")
160 return
161 else:
162 # open() worked, therefore, tmpfile() should work. Close our
163 # dummy file and proceed with the test as normal.
164 fp.close()
165 os.remove(name)
166
167 fp = os.tmpfile()
168 fp.write("foobar")
169 fp.seek(0,0)
170 s = fp.read()
171 fp.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000172 self.assertTrue(s == "foobar")
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000173
174 def test_tmpnam(self):
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000175 if not hasattr(os, "tmpnam"):
176 return
177 warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning,
178 r"test_os$")
179 name = os.tmpnam()
180 if sys.platform in ("win32",):
181 # The Windows tmpnam() seems useless. From the MS docs:
182 #
183 # The character string that tmpnam creates consists of
184 # the path prefix, defined by the entry P_tmpdir in the
185 # file STDIO.H, followed by a sequence consisting of the
186 # digit characters '0' through '9'; the numerical value
187 # of this string is in the range 1 - 65,535. Changing the
188 # definitions of L_tmpnam or P_tmpdir in STDIO.H does not
189 # change the operation of tmpnam.
190 #
191 # The really bizarre part is that, at least under MSVC6,
192 # P_tmpdir is "\\". That is, the path returned refers to
193 # the root of the current drive. That's a terrible place to
194 # put temp files, and, depending on privileges, the user
195 # may not even be able to open a file in the root directory.
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000196 self.assertFalse(os.path.exists(name),
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000197 "file already exists for temporary file")
198 else:
199 self.check_tempfile(name)
200
Amaury Forgeot d'Arce2e36ba2008-08-01 00:14:22 +0000201 def fdopen_helper(self, *args):
202 fd = os.open(support.TESTFN, os.O_RDONLY)
203 fp2 = os.fdopen(fd, *args)
204 fp2.close()
205
206 def test_fdopen(self):
207 self.fdopen_helper()
208 self.fdopen_helper('r')
209 self.fdopen_helper('r', 100)
210
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000211# Test attributes on return values from os.*stat* family.
212class StatAttributeTests(unittest.TestCase):
213 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000214 os.mkdir(support.TESTFN)
215 self.fname = os.path.join(support.TESTFN, "f1")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000216 f = open(self.fname, 'wb')
Guido van Rossum26d95c32007-08-27 23:18:54 +0000217 f.write(b"ABC")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000218 f.close()
Tim Peterse0c446b2001-10-18 21:57:37 +0000219
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000220 def tearDown(self):
221 os.unlink(self.fname)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000222 os.rmdir(support.TESTFN)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000223
Antoine Pitrou38425292010-09-21 18:19:07 +0000224 def check_stat_attributes(self, fname):
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000225 if not hasattr(os, "stat"):
226 return
227
228 import stat
Antoine Pitrou38425292010-09-21 18:19:07 +0000229 result = os.stat(fname)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000230
231 # Make sure direct access works
232 self.assertEquals(result[stat.ST_SIZE], 3)
233 self.assertEquals(result.st_size, 3)
234
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000235 # Make sure all the attributes are there
236 members = dir(result)
237 for name in dir(stat):
238 if name[:3] == 'ST_':
239 attr = name.lower()
Martin v. Löwis4d394df2005-01-23 09:19:22 +0000240 if name.endswith("TIME"):
241 def trunc(x): return int(x)
242 else:
243 def trunc(x): return x
244 self.assertEquals(trunc(getattr(result, attr)),
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000245 result[getattr(stat, name)])
Benjamin Peterson577473f2010-01-19 00:09:57 +0000246 self.assertIn(attr, members)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000247
248 try:
249 result[200]
250 self.fail("No exception thrown")
251 except IndexError:
252 pass
253
254 # Make sure that assignment fails
255 try:
256 result.st_mode = 1
257 self.fail("No exception thrown")
Collin Winter42dae6a2007-03-28 21:44:53 +0000258 except AttributeError:
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000259 pass
260
261 try:
262 result.st_rdev = 1
263 self.fail("No exception thrown")
Guido van Rossum1fff8782001-10-18 21:19:31 +0000264 except (AttributeError, TypeError):
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000265 pass
266
267 try:
268 result.parrot = 1
269 self.fail("No exception thrown")
270 except AttributeError:
271 pass
272
273 # Use the stat_result constructor with a too-short tuple.
274 try:
275 result2 = os.stat_result((10,))
276 self.fail("No exception thrown")
277 except TypeError:
278 pass
279
280 # Use the constructr with a too-long tuple.
281 try:
282 result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
283 except TypeError:
284 pass
285
Antoine Pitrou38425292010-09-21 18:19:07 +0000286 def test_stat_attributes(self):
287 self.check_stat_attributes(self.fname)
288
289 def test_stat_attributes_bytes(self):
290 try:
291 fname = self.fname.encode(sys.getfilesystemencoding())
292 except UnicodeEncodeError:
293 self.skipTest("cannot encode %a for the filesystem" % self.fname)
294 self.check_stat_attributes(fname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000295
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000296 def test_statvfs_attributes(self):
297 if not hasattr(os, "statvfs"):
298 return
299
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000300 try:
301 result = os.statvfs(self.fname)
Guido van Rossumb940e112007-01-10 16:19:56 +0000302 except OSError as e:
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000303 # On AtheOS, glibc always returns ENOSYS
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000304 if e.errno == errno.ENOSYS:
305 return
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000306
307 # Make sure direct access works
Brett Cannoncfaf10c2008-05-16 00:45:35 +0000308 self.assertEquals(result.f_bfree, result[3])
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000309
Brett Cannoncfaf10c2008-05-16 00:45:35 +0000310 # Make sure all the attributes are there.
311 members = ('bsize', 'frsize', 'blocks', 'bfree', 'bavail', 'files',
312 'ffree', 'favail', 'flag', 'namemax')
313 for value, member in enumerate(members):
314 self.assertEquals(getattr(result, 'f_' + member), result[value])
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000315
316 # Make sure that assignment really fails
317 try:
318 result.f_bfree = 1
319 self.fail("No exception thrown")
Collin Winter42dae6a2007-03-28 21:44:53 +0000320 except AttributeError:
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000321 pass
322
323 try:
324 result.parrot = 1
325 self.fail("No exception thrown")
326 except AttributeError:
327 pass
328
329 # Use the constructor with a too-short tuple.
330 try:
331 result2 = os.statvfs_result((10,))
332 self.fail("No exception thrown")
333 except TypeError:
334 pass
335
336 # Use the constructr with a too-long tuple.
337 try:
338 result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
339 except TypeError:
340 pass
Fred Drake38c2ef02001-07-17 20:52:51 +0000341
Thomas Wouters89f507f2006-12-13 04:49:30 +0000342 def test_utime_dir(self):
343 delta = 1000000
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000344 st = os.stat(support.TESTFN)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000345 # round to int, because some systems may support sub-second
346 # time stamps in stat, but not in utime.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000347 os.utime(support.TESTFN, (st.st_atime, int(st.st_mtime-delta)))
348 st2 = os.stat(support.TESTFN)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000349 self.assertEquals(st2.st_mtime, int(st.st_mtime-delta))
350
351 # Restrict test to Win32, since there is no guarantee other
352 # systems support centiseconds
353 if sys.platform == 'win32':
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000354 def get_file_system(path):
Hirokazu Yamamoto5ef6d182008-08-20 04:17:24 +0000355 root = os.path.splitdrive(os.path.abspath(path))[0] + '\\'
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000356 import ctypes
Hirokazu Yamamotoca765d52008-08-20 16:18:19 +0000357 kernel32 = ctypes.windll.kernel32
Hirokazu Yamamoto5ef6d182008-08-20 04:17:24 +0000358 buf = ctypes.create_unicode_buffer("", 100)
Hirokazu Yamamotoca765d52008-08-20 16:18:19 +0000359 if kernel32.GetVolumeInformationW(root, None, 0, None, None, None, buf, len(buf)):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000360 return buf.value
361
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000362 if get_file_system(support.TESTFN) == "NTFS":
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000363 def test_1565150(self):
364 t1 = 1159195039.25
365 os.utime(self.fname, (t1, t1))
366 self.assertEquals(os.stat(self.fname).st_mtime, t1)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000367
Guido van Rossumd8faa362007-04-27 19:54:29 +0000368 def test_1686475(self):
369 # Verify that an open file can be stat'ed
370 try:
371 os.stat(r"c:\pagefile.sys")
372 except WindowsError as e:
Benjamin Petersonc4fe6f32008-08-19 18:57:56 +0000373 if e.errno == 2: # file does not exist; cannot run test
Guido van Rossumd8faa362007-04-27 19:54:29 +0000374 return
375 self.fail("Could not stat pagefile.sys")
376
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000377from test import mapping_tests
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000378
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000379class EnvironTests(mapping_tests.BasicTestMappingProtocol):
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000380 """check that os.environ object conform to mapping protocol"""
Walter Dörwald118f9312004-06-02 18:42:25 +0000381 type2test = None
Christian Heimes90333392007-11-01 19:08:42 +0000382
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000383 def setUp(self):
384 self.__save = dict(os.environ)
Victor Stinnerb745a742010-05-18 17:17:23 +0000385 if os.supports_bytes_environ:
Victor Stinner208d28c2010-05-07 00:54:14 +0000386 self.__saveb = dict(os.environb)
Christian Heimes90333392007-11-01 19:08:42 +0000387 for key, value in self._reference().items():
388 os.environ[key] = value
389
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000390 def tearDown(self):
391 os.environ.clear()
392 os.environ.update(self.__save)
Victor Stinnerb745a742010-05-18 17:17:23 +0000393 if os.supports_bytes_environ:
Victor Stinner208d28c2010-05-07 00:54:14 +0000394 os.environb.clear()
395 os.environb.update(self.__saveb)
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000396
Christian Heimes90333392007-11-01 19:08:42 +0000397 def _reference(self):
398 return {"KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3"}
399
400 def _empty_mapping(self):
401 os.environ.clear()
402 return os.environ
403
Martin v. Löwis1d11de62005-01-29 13:29:23 +0000404 # Bug 1110478
Martin v. Löwis5510f652005-02-17 21:23:20 +0000405 def test_update2(self):
Christian Heimes90333392007-11-01 19:08:42 +0000406 os.environ.clear()
Martin v. Löwis1d11de62005-01-29 13:29:23 +0000407 if os.path.exists("/bin/sh"):
408 os.environ.update(HELLO="World")
409 value = os.popen("/bin/sh -c 'echo $HELLO'").read().strip()
410 self.assertEquals(value, "World")
411
Christian Heimes1a13d592007-11-08 14:16:55 +0000412 def test_os_popen_iter(self):
413 if os.path.exists("/bin/sh"):
414 popen = os.popen("/bin/sh -c 'echo \"line1\nline2\nline3\"'")
415 it = iter(popen)
416 self.assertEquals(next(it), "line1\n")
417 self.assertEquals(next(it), "line2\n")
418 self.assertEquals(next(it), "line3\n")
419 self.assertRaises(StopIteration, next, it)
420
Guido van Rossum67aca9e2007-06-13 21:51:27 +0000421 # Verify environ keys and values from the OS are of the
422 # correct str type.
423 def test_keyvalue_types(self):
424 for key, val in os.environ.items():
425 self.assertEquals(type(key), str)
426 self.assertEquals(type(val), str)
427
Christian Heimes90333392007-11-01 19:08:42 +0000428 def test_items(self):
429 for key, value in self._reference().items():
430 self.assertEqual(os.environ.get(key), value)
431
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000432 # Issue 7310
433 def test___repr__(self):
434 """Check that the repr() of os.environ looks like environ({...})."""
435 env = os.environ
Victor Stinner96f0de92010-07-29 00:29:00 +0000436 self.assertEqual(repr(env), 'environ({{{}}})'.format(', '.join(
437 '{!r}: {!r}'.format(key, value)
438 for key, value in env.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000439
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000440 def test_get_exec_path(self):
441 defpath_list = os.defpath.split(os.pathsep)
442 test_path = ['/monty', '/python', '', '/flying/circus']
443 test_env = {'PATH': os.pathsep.join(test_path)}
444
445 saved_environ = os.environ
446 try:
447 os.environ = dict(test_env)
448 # Test that defaulting to os.environ works.
449 self.assertSequenceEqual(test_path, os.get_exec_path())
450 self.assertSequenceEqual(test_path, os.get_exec_path(env=None))
451 finally:
452 os.environ = saved_environ
453
454 # No PATH environment variable
455 self.assertSequenceEqual(defpath_list, os.get_exec_path({}))
456 # Empty PATH environment variable
457 self.assertSequenceEqual(('',), os.get_exec_path({'PATH':''}))
458 # Supplied PATH environment variable
459 self.assertSequenceEqual(test_path, os.get_exec_path(test_env))
460
Victor Stinnerb745a742010-05-18 17:17:23 +0000461 if os.supports_bytes_environ:
462 # env cannot contain 'PATH' and b'PATH' keys
Victor Stinner38430e22010-08-19 17:10:18 +0000463 try:
Victor Stinner6f35eda2010-10-29 00:38:58 +0000464 # ignore BytesWarning warning
465 with warnings.catch_warnings(record=True):
466 mixed_env = {'PATH': '1', b'PATH': b'2'}
Victor Stinner38430e22010-08-19 17:10:18 +0000467 except BytesWarning:
Victor Stinner6f35eda2010-10-29 00:38:58 +0000468 # mixed_env cannot be created with python -bb
Victor Stinner38430e22010-08-19 17:10:18 +0000469 pass
470 else:
471 self.assertRaises(ValueError, os.get_exec_path, mixed_env)
Victor Stinnerb745a742010-05-18 17:17:23 +0000472
473 # bytes key and/or value
474 self.assertSequenceEqual(os.get_exec_path({b'PATH': b'abc'}),
475 ['abc'])
476 self.assertSequenceEqual(os.get_exec_path({b'PATH': 'abc'}),
477 ['abc'])
478 self.assertSequenceEqual(os.get_exec_path({'PATH': b'abc'}),
479 ['abc'])
480
481 @unittest.skipUnless(os.supports_bytes_environ,
482 "os.environb required for this test.")
Victor Stinner84ae1182010-05-06 22:05:07 +0000483 def test_environb(self):
484 # os.environ -> os.environb
485 value = 'euro\u20ac'
486 try:
Benjamin Peterson180799d2010-05-06 22:25:42 +0000487 value_bytes = value.encode(sys.getfilesystemencoding(),
488 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000489 except UnicodeEncodeError:
Benjamin Peterson180799d2010-05-06 22:25:42 +0000490 msg = "U+20AC character is not encodable to %s" % (
491 sys.getfilesystemencoding(),)
Benjamin Peterson932d3f42010-05-06 22:26:31 +0000492 self.skipTest(msg)
Victor Stinner84ae1182010-05-06 22:05:07 +0000493 os.environ['unicode'] = value
494 self.assertEquals(os.environ['unicode'], value)
495 self.assertEquals(os.environb[b'unicode'], value_bytes)
496
497 # os.environb -> os.environ
498 value = b'\xff'
499 os.environb[b'bytes'] = value
500 self.assertEquals(os.environb[b'bytes'], value)
501 value_str = value.decode(sys.getfilesystemencoding(), 'surrogateescape')
502 self.assertEquals(os.environ['bytes'], value_str)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000503
Tim Petersc4e09402003-04-25 07:11:48 +0000504class WalkTests(unittest.TestCase):
505 """Tests for os.walk()."""
506
507 def test_traversal(self):
508 import os
509 from os.path import join
510
511 # Build:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000512 # TESTFN/
513 # TEST1/ a file kid and two directory kids
Tim Petersc4e09402003-04-25 07:11:48 +0000514 # tmp1
515 # SUB1/ a file kid and a directory kid
Guido van Rossumd8faa362007-04-27 19:54:29 +0000516 # tmp2
517 # SUB11/ no kids
518 # SUB2/ a file kid and a dirsymlink kid
519 # tmp3
520 # link/ a symlink to TESTFN.2
521 # TEST2/
522 # tmp4 a lone file
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000523 walk_path = join(support.TESTFN, "TEST1")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000524 sub1_path = join(walk_path, "SUB1")
Tim Petersc4e09402003-04-25 07:11:48 +0000525 sub11_path = join(sub1_path, "SUB11")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000526 sub2_path = join(walk_path, "SUB2")
527 tmp1_path = join(walk_path, "tmp1")
Tim Petersc4e09402003-04-25 07:11:48 +0000528 tmp2_path = join(sub1_path, "tmp2")
529 tmp3_path = join(sub2_path, "tmp3")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000530 link_path = join(sub2_path, "link")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000531 t2_path = join(support.TESTFN, "TEST2")
532 tmp4_path = join(support.TESTFN, "TEST2", "tmp4")
Tim Petersc4e09402003-04-25 07:11:48 +0000533
534 # Create stuff.
535 os.makedirs(sub11_path)
536 os.makedirs(sub2_path)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000537 os.makedirs(t2_path)
538 for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path:
Alex Martelli01c77c62006-08-24 02:58:11 +0000539 f = open(path, "w")
Tim Petersc4e09402003-04-25 07:11:48 +0000540 f.write("I'm " + path + " and proud of it. Blame test_os.\n")
541 f.close()
Brian Curtind40e6f72010-07-08 21:39:08 +0000542 if support.can_symlink():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000543 os.symlink(os.path.abspath(t2_path), link_path)
544 sub2_tree = (sub2_path, ["link"], ["tmp3"])
545 else:
546 sub2_tree = (sub2_path, [], ["tmp3"])
Tim Petersc4e09402003-04-25 07:11:48 +0000547
548 # Walk top-down.
Guido van Rossumd8faa362007-04-27 19:54:29 +0000549 all = list(os.walk(walk_path))
Tim Petersc4e09402003-04-25 07:11:48 +0000550 self.assertEqual(len(all), 4)
551 # We can't know which order SUB1 and SUB2 will appear in.
552 # Not flipped: TESTFN, SUB1, SUB11, SUB2
553 # flipped: TESTFN, SUB2, SUB1, SUB11
554 flipped = all[0][1][0] != "SUB1"
555 all[0][1].sort()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000556 self.assertEqual(all[0], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
Tim Petersc4e09402003-04-25 07:11:48 +0000557 self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"]))
558 self.assertEqual(all[2 + flipped], (sub11_path, [], []))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000559 self.assertEqual(all[3 - 2 * flipped], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000560
561 # Prune the search.
562 all = []
Guido van Rossumd8faa362007-04-27 19:54:29 +0000563 for root, dirs, files in os.walk(walk_path):
Tim Petersc4e09402003-04-25 07:11:48 +0000564 all.append((root, dirs, files))
565 # Don't descend into SUB1.
566 if 'SUB1' in dirs:
567 # Note that this also mutates the dirs we appended to all!
568 dirs.remove('SUB1')
569 self.assertEqual(len(all), 2)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000570 self.assertEqual(all[0], (walk_path, ["SUB2"], ["tmp1"]))
571 self.assertEqual(all[1], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000572
573 # Walk bottom-up.
Guido van Rossumd8faa362007-04-27 19:54:29 +0000574 all = list(os.walk(walk_path, topdown=False))
Tim Petersc4e09402003-04-25 07:11:48 +0000575 self.assertEqual(len(all), 4)
576 # We can't know which order SUB1 and SUB2 will appear in.
577 # Not flipped: SUB11, SUB1, SUB2, TESTFN
578 # flipped: SUB2, SUB11, SUB1, TESTFN
579 flipped = all[3][1][0] != "SUB1"
580 all[3][1].sort()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000581 self.assertEqual(all[3], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
Tim Petersc4e09402003-04-25 07:11:48 +0000582 self.assertEqual(all[flipped], (sub11_path, [], []))
583 self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"]))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000584 self.assertEqual(all[2 - 2 * flipped], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000585
Brian Curtind40e6f72010-07-08 21:39:08 +0000586 if support.can_symlink():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000587 # Walk, following symlinks.
588 for root, dirs, files in os.walk(walk_path, followlinks=True):
589 if root == link_path:
590 self.assertEqual(dirs, [])
591 self.assertEqual(files, ["tmp4"])
592 break
593 else:
594 self.fail("Didn't follow symlink with followlinks=True")
595
596 def tearDown(self):
Tim Petersc4e09402003-04-25 07:11:48 +0000597 # Tear everything down. This is a decent use for bottom-up on
598 # Windows, which doesn't have a recursive delete command. The
599 # (not so) subtlety is that rmdir will fail unless the dir's
600 # kids are removed first, so bottom up is essential.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000601 for root, dirs, files in os.walk(support.TESTFN, topdown=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000602 for name in files:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000603 os.remove(os.path.join(root, name))
Tim Petersc4e09402003-04-25 07:11:48 +0000604 for name in dirs:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000605 dirname = os.path.join(root, name)
606 if not os.path.islink(dirname):
607 os.rmdir(dirname)
608 else:
609 os.remove(dirname)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000610 os.rmdir(support.TESTFN)
Tim Petersc4e09402003-04-25 07:11:48 +0000611
Guido van Rossume7ba4952007-06-06 23:52:48 +0000612class MakedirTests(unittest.TestCase):
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000613 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000614 os.mkdir(support.TESTFN)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000615
616 def test_makedir(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000617 base = support.TESTFN
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000618 path = os.path.join(base, 'dir1', 'dir2', 'dir3')
619 os.makedirs(path) # Should work
620 path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4')
621 os.makedirs(path)
622
623 # Try paths with a '.' in them
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000624 self.assertRaises(OSError, os.makedirs, os.curdir)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000625 path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir)
626 os.makedirs(path)
627 path = os.path.join(base, 'dir1', os.curdir, 'dir2', 'dir3', 'dir4',
628 'dir5', 'dir6')
629 os.makedirs(path)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000630
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000631 def tearDown(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000632 path = os.path.join(support.TESTFN, 'dir1', 'dir2', 'dir3',
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000633 'dir4', 'dir5', 'dir6')
634 # If the tests failed, the bottom-most directory ('../dir6')
635 # may not have been created, so we look for the outermost directory
636 # that exists.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000637 while not os.path.exists(path) and path != support.TESTFN:
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000638 path = os.path.dirname(path)
639
640 os.removedirs(path)
641
Guido van Rossume7ba4952007-06-06 23:52:48 +0000642class DevNullTests(unittest.TestCase):
Martin v. Löwisbdec50f2004-06-08 08:29:33 +0000643 def test_devnull(self):
Alex Martelli01c77c62006-08-24 02:58:11 +0000644 f = open(os.devnull, 'w')
Martin v. Löwisbdec50f2004-06-08 08:29:33 +0000645 f.write('hello')
646 f.close()
Alex Martelli01c77c62006-08-24 02:58:11 +0000647 f = open(os.devnull, 'r')
Tim Peters4182cfd2004-06-08 20:34:34 +0000648 self.assertEqual(f.read(), '')
Martin v. Löwisbdec50f2004-06-08 08:29:33 +0000649 f.close()
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000650
Guido van Rossume7ba4952007-06-06 23:52:48 +0000651class URandomTests(unittest.TestCase):
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000652 def test_urandom(self):
653 try:
654 self.assertEqual(len(os.urandom(1)), 1)
655 self.assertEqual(len(os.urandom(10)), 10)
656 self.assertEqual(len(os.urandom(100)), 100)
657 self.assertEqual(len(os.urandom(1000)), 1000)
658 except NotImplementedError:
659 pass
660
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000661@contextlib.contextmanager
662def _execvpe_mockup(defpath=None):
663 """
664 Stubs out execv and execve functions when used as context manager.
665 Records exec calls. The mock execv and execve functions always raise an
666 exception as they would normally never return.
667 """
668 # A list of tuples containing (function name, first arg, args)
669 # of calls to execv or execve that have been made.
670 calls = []
671
672 def mock_execv(name, *args):
673 calls.append(('execv', name, args))
674 raise RuntimeError("execv called")
675
676 def mock_execve(name, *args):
677 calls.append(('execve', name, args))
678 raise OSError(errno.ENOTDIR, "execve called")
679
680 try:
681 orig_execv = os.execv
682 orig_execve = os.execve
683 orig_defpath = os.defpath
684 os.execv = mock_execv
685 os.execve = mock_execve
686 if defpath is not None:
687 os.defpath = defpath
688 yield calls
689 finally:
690 os.execv = orig_execv
691 os.execve = orig_execve
692 os.defpath = orig_defpath
693
Guido van Rossume7ba4952007-06-06 23:52:48 +0000694class ExecTests(unittest.TestCase):
Mark Dickinson7cf03892010-04-16 13:45:35 +0000695 @unittest.skipIf(USING_LINUXTHREADS,
696 "avoid triggering a linuxthreads bug: see issue #4970")
Guido van Rossume7ba4952007-06-06 23:52:48 +0000697 def test_execvpe_with_bad_program(self):
Mark Dickinson7cf03892010-04-16 13:45:35 +0000698 self.assertRaises(OSError, os.execvpe, 'no such app-',
699 ['no such app-'], None)
Guido van Rossume7ba4952007-06-06 23:52:48 +0000700
Thomas Heller6790d602007-08-30 17:15:14 +0000701 def test_execvpe_with_bad_arglist(self):
702 self.assertRaises(ValueError, os.execvpe, 'notepad', [], None)
703
Gregory P. Smith4ae37772010-05-08 18:05:46 +0000704 @unittest.skipUnless(hasattr(os, '_execvpe'),
705 "No internal os._execvpe function to test.")
Victor Stinnerb745a742010-05-18 17:17:23 +0000706 def _test_internal_execvpe(self, test_type):
707 program_path = os.sep + 'absolutepath'
708 if test_type is bytes:
709 program = b'executable'
710 fullpath = os.path.join(os.fsencode(program_path), program)
711 native_fullpath = fullpath
712 arguments = [b'progname', 'arg1', 'arg2']
713 else:
714 program = 'executable'
715 arguments = ['progname', 'arg1', 'arg2']
716 fullpath = os.path.join(program_path, program)
717 if os.name != "nt":
718 native_fullpath = os.fsencode(fullpath)
719 else:
720 native_fullpath = fullpath
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000721 env = {'spam': 'beans'}
722
Victor Stinnerb745a742010-05-18 17:17:23 +0000723 # test os._execvpe() with an absolute path
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000724 with _execvpe_mockup() as calls:
Victor Stinnerb745a742010-05-18 17:17:23 +0000725 self.assertRaises(RuntimeError,
726 os._execvpe, fullpath, arguments)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000727 self.assertEqual(len(calls), 1)
728 self.assertEqual(calls[0], ('execv', fullpath, (arguments,)))
729
Victor Stinnerb745a742010-05-18 17:17:23 +0000730 # test os._execvpe() with a relative path:
731 # os.get_exec_path() returns defpath
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000732 with _execvpe_mockup(defpath=program_path) as calls:
Victor Stinnerb745a742010-05-18 17:17:23 +0000733 self.assertRaises(OSError,
734 os._execvpe, program, arguments, env=env)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000735 self.assertEqual(len(calls), 1)
Victor Stinnerb745a742010-05-18 17:17:23 +0000736 self.assertSequenceEqual(calls[0],
737 ('execve', native_fullpath, (arguments, env)))
738
739 # test os._execvpe() with a relative path:
740 # os.get_exec_path() reads the 'PATH' variable
741 with _execvpe_mockup() as calls:
742 env_path = env.copy()
Victor Stinner38430e22010-08-19 17:10:18 +0000743 if test_type is bytes:
744 env_path[b'PATH'] = program_path
745 else:
746 env_path['PATH'] = program_path
Victor Stinnerb745a742010-05-18 17:17:23 +0000747 self.assertRaises(OSError,
748 os._execvpe, program, arguments, env=env_path)
749 self.assertEqual(len(calls), 1)
750 self.assertSequenceEqual(calls[0],
751 ('execve', native_fullpath, (arguments, env_path)))
752
753 def test_internal_execvpe_str(self):
754 self._test_internal_execvpe(str)
755 if os.name != "nt":
756 self._test_internal_execvpe(bytes)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000757
Gregory P. Smith4ae37772010-05-08 18:05:46 +0000758
Thomas Wouters477c8d52006-05-27 19:21:47 +0000759class Win32ErrorTests(unittest.TestCase):
760 def test_rename(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000761 self.assertRaises(WindowsError, os.rename, support.TESTFN, support.TESTFN+".bak")
Thomas Wouters477c8d52006-05-27 19:21:47 +0000762
763 def test_remove(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000764 self.assertRaises(WindowsError, os.remove, support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000765
766 def test_chdir(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000767 self.assertRaises(WindowsError, os.chdir, support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000768
769 def test_mkdir(self):
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000770 f = open(support.TESTFN, "w")
Benjamin Petersonf91df042009-02-13 02:50:59 +0000771 try:
772 self.assertRaises(WindowsError, os.mkdir, support.TESTFN)
773 finally:
774 f.close()
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000775 os.unlink(support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000776
777 def test_utime(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000778 self.assertRaises(WindowsError, os.utime, support.TESTFN, None)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000779
Thomas Wouters477c8d52006-05-27 19:21:47 +0000780 def test_chmod(self):
Benjamin Petersonf91df042009-02-13 02:50:59 +0000781 self.assertRaises(WindowsError, os.chmod, support.TESTFN, 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000782
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000783class TestInvalidFD(unittest.TestCase):
Benjamin Peterson05e782f2009-01-19 15:15:02 +0000784 singles = ["fchdir", "dup", "fdopen", "fdatasync", "fstat",
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000785 "fstatvfs", "fsync", "tcgetpgrp", "ttyname"]
786 #singles.append("close")
787 #We omit close because it doesn'r raise an exception on some platforms
788 def get_single(f):
789 def helper(self):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000790 if hasattr(os, f):
791 self.check(getattr(os, f))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000792 return helper
793 for f in singles:
794 locals()["test_"+f] = get_single(f)
795
Benjamin Peterson7522c742009-01-19 21:00:09 +0000796 def check(self, f, *args):
Benjamin Peterson5c6d7872009-02-06 02:40:07 +0000797 try:
798 f(support.make_bad_fd(), *args)
799 except OSError as e:
800 self.assertEqual(e.errno, errno.EBADF)
801 else:
802 self.fail("%r didn't raise a OSError with a bad file descriptor"
803 % f)
Benjamin Peterson7522c742009-01-19 21:00:09 +0000804
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000805 def test_isatty(self):
806 if hasattr(os, "isatty"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000807 self.assertEqual(os.isatty(support.make_bad_fd()), False)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000808
809 def test_closerange(self):
810 if hasattr(os, "closerange"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000811 fd = support.make_bad_fd()
R. David Murray630cc482009-07-22 15:20:27 +0000812 # Make sure none of the descriptors we are about to close are
813 # currently valid (issue 6542).
814 for i in range(10):
815 try: os.fstat(fd+i)
816 except OSError:
817 pass
818 else:
819 break
820 if i < 2:
821 raise unittest.SkipTest(
822 "Unable to acquire a range of invalid file descriptors")
823 self.assertEqual(os.closerange(fd, fd + i-1), None)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000824
825 def test_dup2(self):
826 if hasattr(os, "dup2"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000827 self.check(os.dup2, 20)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000828
829 def test_fchmod(self):
830 if hasattr(os, "fchmod"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000831 self.check(os.fchmod, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000832
833 def test_fchown(self):
834 if hasattr(os, "fchown"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000835 self.check(os.fchown, -1, -1)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000836
837 def test_fpathconf(self):
838 if hasattr(os, "fpathconf"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000839 self.check(os.fpathconf, "PC_NAME_MAX")
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000840
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000841 def test_ftruncate(self):
842 if hasattr(os, "ftruncate"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000843 self.check(os.ftruncate, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000844
845 def test_lseek(self):
846 if hasattr(os, "lseek"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000847 self.check(os.lseek, 0, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000848
849 def test_read(self):
850 if hasattr(os, "read"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000851 self.check(os.read, 1)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000852
853 def test_tcsetpgrpt(self):
854 if hasattr(os, "tcsetpgrp"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000855 self.check(os.tcsetpgrp, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000856
857 def test_write(self):
858 if hasattr(os, "write"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000859 self.check(os.write, b" ")
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000860
Thomas Wouters477c8d52006-05-27 19:21:47 +0000861if sys.platform != 'win32':
862 class Win32ErrorTests(unittest.TestCase):
863 pass
864
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000865 class PosixUidGidTests(unittest.TestCase):
866 if hasattr(os, 'setuid'):
867 def test_setuid(self):
868 if os.getuid() != 0:
869 self.assertRaises(os.error, os.setuid, 0)
870 self.assertRaises(OverflowError, os.setuid, 1<<32)
871
872 if hasattr(os, 'setgid'):
873 def test_setgid(self):
874 if os.getuid() != 0:
875 self.assertRaises(os.error, os.setgid, 0)
876 self.assertRaises(OverflowError, os.setgid, 1<<32)
877
878 if hasattr(os, 'seteuid'):
879 def test_seteuid(self):
880 if os.getuid() != 0:
881 self.assertRaises(os.error, os.seteuid, 0)
882 self.assertRaises(OverflowError, os.seteuid, 1<<32)
883
884 if hasattr(os, 'setegid'):
885 def test_setegid(self):
886 if os.getuid() != 0:
887 self.assertRaises(os.error, os.setegid, 0)
888 self.assertRaises(OverflowError, os.setegid, 1<<32)
889
890 if hasattr(os, 'setreuid'):
891 def test_setreuid(self):
892 if os.getuid() != 0:
893 self.assertRaises(os.error, os.setreuid, 0, 0)
894 self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
895 self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000896
897 def test_setreuid_neg1(self):
898 # Needs to accept -1. We run this in a subprocess to avoid
899 # altering the test runner's process state (issue8045).
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000900 subprocess.check_call([
901 sys.executable, '-c',
902 'import os,sys;os.setreuid(-1,-1);sys.exit(0)'])
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000903
904 if hasattr(os, 'setregid'):
905 def test_setregid(self):
906 if os.getuid() != 0:
907 self.assertRaises(os.error, os.setregid, 0, 0)
908 self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
909 self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000910
911 def test_setregid_neg1(self):
912 # Needs to accept -1. We run this in a subprocess to avoid
913 # altering the test runner's process state (issue8045).
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000914 subprocess.check_call([
915 sys.executable, '-c',
916 'import os,sys;os.setregid(-1,-1);sys.exit(0)'])
Martin v. Löwis011e8422009-05-05 04:43:17 +0000917
918 class Pep383Tests(unittest.TestCase):
Martin v. Löwis011e8422009-05-05 04:43:17 +0000919 def setUp(self):
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000920 if support.TESTFN_UNENCODABLE:
921 self.dir = support.TESTFN_UNENCODABLE
922 else:
923 self.dir = support.TESTFN
924 self.bdir = os.fsencode(self.dir)
925
926 bytesfn = []
927 def add_filename(fn):
928 try:
929 fn = os.fsencode(fn)
930 except UnicodeEncodeError:
931 return
932 bytesfn.append(fn)
933 add_filename(support.TESTFN_UNICODE)
934 if support.TESTFN_UNENCODABLE:
935 add_filename(support.TESTFN_UNENCODABLE)
936 if not bytesfn:
937 self.skipTest("couldn't create any non-ascii filename")
938
939 self.unicodefn = set()
Martin v. Löwis011e8422009-05-05 04:43:17 +0000940 os.mkdir(self.dir)
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000941 try:
942 for fn in bytesfn:
943 f = open(os.path.join(self.bdir, fn), "w")
944 f.close()
Victor Stinnere8d51452010-08-19 01:05:19 +0000945 fn = os.fsdecode(fn)
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000946 if fn in self.unicodefn:
947 raise ValueError("duplicate filename")
948 self.unicodefn.add(fn)
949 except:
950 shutil.rmtree(self.dir)
951 raise
Martin v. Löwis011e8422009-05-05 04:43:17 +0000952
953 def tearDown(self):
954 shutil.rmtree(self.dir)
Martin v. Löwis011e8422009-05-05 04:43:17 +0000955
956 def test_listdir(self):
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000957 expected = self.unicodefn
958 found = set(os.listdir(self.dir))
Martin v. Löwis011e8422009-05-05 04:43:17 +0000959 self.assertEquals(found, expected)
960
961 def test_open(self):
962 for fn in self.unicodefn:
963 f = open(os.path.join(self.dir, fn))
964 f.close()
965
966 def test_stat(self):
967 for fn in self.unicodefn:
968 os.stat(os.path.join(self.dir, fn))
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000969else:
970 class PosixUidGidTests(unittest.TestCase):
971 pass
Martin v. Löwis011e8422009-05-05 04:43:17 +0000972 class Pep383Tests(unittest.TestCase):
973 pass
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000974
Brian Curtineb24d742010-04-12 17:16:38 +0000975@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
976class Win32KillTests(unittest.TestCase):
Brian Curtinc3acbc32010-05-28 16:08:40 +0000977 def _kill(self, sig):
978 # Start sys.executable as a subprocess and communicate from the
979 # subprocess to the parent that the interpreter is ready. When it
980 # becomes ready, send *sig* via os.kill to the subprocess and check
981 # that the return code is equal to *sig*.
982 import ctypes
983 from ctypes import wintypes
984 import msvcrt
985
986 # Since we can't access the contents of the process' stdout until the
987 # process has exited, use PeekNamedPipe to see what's inside stdout
988 # without waiting. This is done so we can tell that the interpreter
989 # is started and running at a point where it could handle a signal.
990 PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe
991 PeekNamedPipe.restype = wintypes.BOOL
992 PeekNamedPipe.argtypes = (wintypes.HANDLE, # Pipe handle
993 ctypes.POINTER(ctypes.c_char), # stdout buf
994 wintypes.DWORD, # Buffer size
995 ctypes.POINTER(wintypes.DWORD), # bytes read
996 ctypes.POINTER(wintypes.DWORD), # bytes avail
997 ctypes.POINTER(wintypes.DWORD)) # bytes left
998 msg = "running"
999 proc = subprocess.Popen([sys.executable, "-c",
1000 "import sys;"
1001 "sys.stdout.write('{}');"
1002 "sys.stdout.flush();"
1003 "input()".format(msg)],
1004 stdout=subprocess.PIPE,
1005 stderr=subprocess.PIPE,
1006 stdin=subprocess.PIPE)
1007
1008 count, max = 0, 100
1009 while count < max and proc.poll() is None:
1010 # Create a string buffer to store the result of stdout from the pipe
1011 buf = ctypes.create_string_buffer(len(msg))
1012 # Obtain the text currently in proc.stdout
1013 # Bytes read/avail/left are left as NULL and unused
1014 rslt = PeekNamedPipe(msvcrt.get_osfhandle(proc.stdout.fileno()),
1015 buf, ctypes.sizeof(buf), None, None, None)
1016 self.assertNotEqual(rslt, 0, "PeekNamedPipe failed")
1017 if buf.value:
1018 self.assertEqual(msg, buf.value.decode())
1019 break
1020 time.sleep(0.1)
1021 count += 1
1022 else:
1023 self.fail("Did not receive communication from the subprocess")
1024
Brian Curtineb24d742010-04-12 17:16:38 +00001025 os.kill(proc.pid, sig)
1026 self.assertEqual(proc.wait(), sig)
1027
1028 def test_kill_sigterm(self):
1029 # SIGTERM doesn't mean anything special, but make sure it works
Brian Curtinc3acbc32010-05-28 16:08:40 +00001030 self._kill(signal.SIGTERM)
Brian Curtineb24d742010-04-12 17:16:38 +00001031
1032 def test_kill_int(self):
1033 # os.kill on Windows can take an int which gets set as the exit code
Brian Curtinc3acbc32010-05-28 16:08:40 +00001034 self._kill(100)
Brian Curtineb24d742010-04-12 17:16:38 +00001035
1036 def _kill_with_event(self, event, name):
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001037 tagname = "test_os_%s" % uuid.uuid1()
1038 m = mmap.mmap(-1, 1, tagname)
1039 m[0] = 0
Brian Curtineb24d742010-04-12 17:16:38 +00001040 # Run a script which has console control handling enabled.
1041 proc = subprocess.Popen([sys.executable,
1042 os.path.join(os.path.dirname(__file__),
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001043 "win_console_handler.py"), tagname],
Brian Curtineb24d742010-04-12 17:16:38 +00001044 creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
1045 # Let the interpreter startup before we send signals. See #3137.
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001046 count, max = 0, 20
1047 while count < max and proc.poll() is None:
Brian Curtinf668df52010-10-15 14:21:06 +00001048 if m[0] == 1:
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001049 break
1050 time.sleep(0.5)
1051 count += 1
1052 else:
1053 self.fail("Subprocess didn't finish initialization")
Brian Curtineb24d742010-04-12 17:16:38 +00001054 os.kill(proc.pid, event)
1055 # proc.send_signal(event) could also be done here.
1056 # Allow time for the signal to be passed and the process to exit.
1057 time.sleep(0.5)
1058 if not proc.poll():
1059 # Forcefully kill the process if we weren't able to signal it.
1060 os.kill(proc.pid, signal.SIGINT)
1061 self.fail("subprocess did not stop on {}".format(name))
1062
1063 @unittest.skip("subprocesses aren't inheriting CTRL+C property")
1064 def test_CTRL_C_EVENT(self):
1065 from ctypes import wintypes
1066 import ctypes
1067
1068 # Make a NULL value by creating a pointer with no argument.
1069 NULL = ctypes.POINTER(ctypes.c_int)()
1070 SetConsoleCtrlHandler = ctypes.windll.kernel32.SetConsoleCtrlHandler
1071 SetConsoleCtrlHandler.argtypes = (ctypes.POINTER(ctypes.c_int),
1072 wintypes.BOOL)
1073 SetConsoleCtrlHandler.restype = wintypes.BOOL
1074
1075 # Calling this with NULL and FALSE causes the calling process to
1076 # handle CTRL+C, rather than ignore it. This property is inherited
1077 # by subprocesses.
1078 SetConsoleCtrlHandler(NULL, 0)
1079
1080 self._kill_with_event(signal.CTRL_C_EVENT, "CTRL_C_EVENT")
1081
1082 def test_CTRL_BREAK_EVENT(self):
1083 self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT")
1084
1085
Brian Curtind40e6f72010-07-08 21:39:08 +00001086def skipUnlessWindows6(test):
Brian Curtin74e45612010-07-09 15:58:59 +00001087 if (hasattr(sys, 'getwindowsversion')
1088 and sys.getwindowsversion().major >= 6):
Brian Curtind40e6f72010-07-08 21:39:08 +00001089 return test
1090 return unittest.skip("Requires Windows Vista or later")(test)
1091
1092@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
1093@support.skip_unless_symlink
1094class Win32SymlinkTests(unittest.TestCase):
1095 filelink = 'filelinktest'
1096 filelink_target = os.path.abspath(__file__)
1097 dirlink = 'dirlinktest'
1098 dirlink_target = os.path.dirname(filelink_target)
1099 missing_link = 'missing link'
1100
1101 def setUp(self):
1102 assert os.path.exists(self.dirlink_target)
1103 assert os.path.exists(self.filelink_target)
1104 assert not os.path.exists(self.dirlink)
1105 assert not os.path.exists(self.filelink)
1106 assert not os.path.exists(self.missing_link)
1107
1108 def tearDown(self):
1109 if os.path.exists(self.filelink):
1110 os.remove(self.filelink)
1111 if os.path.exists(self.dirlink):
1112 os.rmdir(self.dirlink)
1113 if os.path.lexists(self.missing_link):
1114 os.remove(self.missing_link)
1115
1116 def test_directory_link(self):
1117 os.symlink(self.dirlink_target, self.dirlink)
1118 self.assertTrue(os.path.exists(self.dirlink))
1119 self.assertTrue(os.path.isdir(self.dirlink))
1120 self.assertTrue(os.path.islink(self.dirlink))
1121 self.check_stat(self.dirlink, self.dirlink_target)
1122
1123 def test_file_link(self):
1124 os.symlink(self.filelink_target, self.filelink)
1125 self.assertTrue(os.path.exists(self.filelink))
1126 self.assertTrue(os.path.isfile(self.filelink))
1127 self.assertTrue(os.path.islink(self.filelink))
1128 self.check_stat(self.filelink, self.filelink_target)
1129
1130 def _create_missing_dir_link(self):
1131 'Create a "directory" link to a non-existent target'
1132 linkname = self.missing_link
1133 if os.path.lexists(linkname):
1134 os.remove(linkname)
1135 target = r'c:\\target does not exist.29r3c740'
1136 assert not os.path.exists(target)
1137 target_is_dir = True
1138 os.symlink(target, linkname, target_is_dir)
1139
1140 def test_remove_directory_link_to_missing_target(self):
1141 self._create_missing_dir_link()
1142 # For compatibility with Unix, os.remove will check the
1143 # directory status and call RemoveDirectory if the symlink
1144 # was created with target_is_dir==True.
1145 os.remove(self.missing_link)
1146
1147 @unittest.skip("currently fails; consider for improvement")
1148 def test_isdir_on_directory_link_to_missing_target(self):
1149 self._create_missing_dir_link()
1150 # consider having isdir return true for directory links
1151 self.assertTrue(os.path.isdir(self.missing_link))
1152
1153 @unittest.skip("currently fails; consider for improvement")
1154 def test_rmdir_on_directory_link_to_missing_target(self):
1155 self._create_missing_dir_link()
1156 # consider allowing rmdir to remove directory links
1157 os.rmdir(self.missing_link)
1158
1159 def check_stat(self, link, target):
1160 self.assertEqual(os.stat(link), os.stat(target))
1161 self.assertNotEqual(os.lstat(link), os.stat(link))
1162
1163
Victor Stinnere8d51452010-08-19 01:05:19 +00001164class FSEncodingTests(unittest.TestCase):
1165 def test_nop(self):
1166 self.assertEquals(os.fsencode(b'abc\xff'), b'abc\xff')
1167 self.assertEquals(os.fsdecode('abc\u0141'), 'abc\u0141')
Benjamin Peterson31191a92010-05-09 03:22:58 +00001168
Victor Stinnere8d51452010-08-19 01:05:19 +00001169 def test_identity(self):
1170 # assert fsdecode(fsencode(x)) == x
1171 for fn in ('unicode\u0141', 'latin\xe9', 'ascii'):
1172 try:
1173 bytesfn = os.fsencode(fn)
1174 except UnicodeEncodeError:
1175 continue
1176 self.assertEquals(os.fsdecode(bytesfn), fn)
1177
Victor Stinnerbf9bcab2010-05-09 03:15:33 +00001178
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00001179class PidTests(unittest.TestCase):
1180 @unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid")
1181 def test_getppid(self):
1182 p = subprocess.Popen([sys.executable, '-c',
1183 'import os; print(os.getppid())'],
1184 stdout=subprocess.PIPE)
1185 stdout, _ = p.communicate()
1186 # We are the parent of our subprocess
1187 self.assertEqual(int(stdout), os.getpid())
1188
1189
Brian Curtin0151b8e2010-09-24 13:43:43 +00001190# The introduction of this TestCase caused at least two different errors on
1191# *nix buildbots. Temporarily skip this to let the buildbots move along.
1192@unittest.skip("Skip due to platform/environment differences on *NIX buildbots")
Brian Curtine8e4b3b2010-09-23 20:04:14 +00001193@unittest.skipUnless(hasattr(os, 'getlogin'), "test needs os.getlogin")
1194class LoginTests(unittest.TestCase):
1195 def test_getlogin(self):
1196 user_name = os.getlogin()
1197 self.assertNotEqual(len(user_name), 0)
1198
1199
Fred Drake2e2be372001-09-20 21:33:42 +00001200def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001201 support.run_unittest(
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001202 FileTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001203 StatAttributeTests,
1204 EnvironTests,
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001205 WalkTests,
1206 MakedirTests,
Martin v. Löwisbdec50f2004-06-08 08:29:33 +00001207 DevNullTests,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001208 URandomTests,
Guido van Rossume7ba4952007-06-06 23:52:48 +00001209 ExecTests,
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001210 Win32ErrorTests,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001211 TestInvalidFD,
Martin v. Löwis011e8422009-05-05 04:43:17 +00001212 PosixUidGidTests,
Brian Curtineb24d742010-04-12 17:16:38 +00001213 Pep383Tests,
Victor Stinnerbf9bcab2010-05-09 03:15:33 +00001214 Win32KillTests,
Brian Curtind40e6f72010-07-08 21:39:08 +00001215 Win32SymlinkTests,
Victor Stinnere8d51452010-08-19 01:05:19 +00001216 FSEncodingTests,
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00001217 PidTests,
Brian Curtine8e4b3b2010-09-23 20:04:14 +00001218 LoginTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001219 )
Fred Drake2e2be372001-09-20 21:33:42 +00001220
1221if __name__ == "__main__":
1222 test_main()