blob: d73bff2c73dc7ddd023f91704543207589e0ab24 [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
Fred Drake38c2ef02001-07-17 20:52:51 +000016
Mark Dickinson7cf03892010-04-16 13:45:35 +000017# Detect whether we're on a Linux system that uses the (now outdated
18# and unmaintained) linuxthreads threading library. There's an issue
19# when combining linuxthreads with a failed execv call: see
20# http://bugs.python.org/issue4970.
Mark Dickinson89589c92010-04-16 13:51:27 +000021if (hasattr(os, "confstr_names") and
22 "CS_GNU_LIBPTHREAD_VERSION" in os.confstr_names):
Mark Dickinson7cf03892010-04-16 13:45:35 +000023 libpthread = os.confstr("CS_GNU_LIBPTHREAD_VERSION")
24 USING_LINUXTHREADS= libpthread.startswith("linuxthreads")
25else:
26 USING_LINUXTHREADS= False
Brian Curtineb24d742010-04-12 17:16:38 +000027
Thomas Wouters0e3f5912006-08-11 14:57:12 +000028# Tests creating TESTFN
29class FileTests(unittest.TestCase):
30 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000031 if os.path.exists(support.TESTFN):
32 os.unlink(support.TESTFN)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000033 tearDown = setUp
34
35 def test_access(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000036 f = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000037 os.close(f)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000038 self.assertTrue(os.access(support.TESTFN, os.W_OK))
Thomas Wouters0e3f5912006-08-11 14:57:12 +000039
Christian Heimesfdab48e2008-01-20 09:06:41 +000040 def test_closerange(self):
Antoine Pitroub9ee06c2008-08-16 22:03:17 +000041 first = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR)
42 # We must allocate two consecutive file descriptors, otherwise
43 # it will mess up other file descriptors (perhaps even the three
44 # standard ones).
45 second = os.dup(first)
46 try:
47 retries = 0
48 while second != first + 1:
49 os.close(first)
50 retries += 1
51 if retries > 10:
52 # XXX test skipped
Benjamin Petersonfa0d7032009-06-01 22:42:33 +000053 self.skipTest("couldn't allocate two consecutive fds")
Antoine Pitroub9ee06c2008-08-16 22:03:17 +000054 first, second = second, os.dup(second)
55 finally:
56 os.close(second)
Christian Heimesfdab48e2008-01-20 09:06:41 +000057 # close a fd that is open, and one that isn't
Antoine Pitroub9ee06c2008-08-16 22:03:17 +000058 os.closerange(first, first + 2)
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +000059 self.assertRaises(OSError, os.write, first, b"a")
Thomas Wouters0e3f5912006-08-11 14:57:12 +000060
Benjamin Peterson1cc6df92010-06-30 17:39:45 +000061 @support.cpython_only
Hirokazu Yamamoto4c19e6e2008-09-08 23:41:21 +000062 def test_rename(self):
63 path = support.TESTFN
64 old = sys.getrefcount(path)
65 self.assertRaises(TypeError, os.rename, path, 0)
66 new = sys.getrefcount(path)
67 self.assertEqual(old, new)
68
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +000069 def test_read(self):
70 with open(support.TESTFN, "w+b") as fobj:
71 fobj.write(b"spam")
72 fobj.flush()
73 fd = fobj.fileno()
74 os.lseek(fd, 0, 0)
75 s = os.read(fd, 4)
76 self.assertEqual(type(s), bytes)
77 self.assertEqual(s, b"spam")
78
79 def test_write(self):
80 # os.write() accepts bytes- and buffer-like objects but not strings
81 fd = os.open(support.TESTFN, os.O_CREAT | os.O_WRONLY)
82 self.assertRaises(TypeError, os.write, fd, "beans")
83 os.write(fd, b"bacon\n")
84 os.write(fd, bytearray(b"eggs\n"))
85 os.write(fd, memoryview(b"spam\n"))
86 os.close(fd)
87 with open(support.TESTFN, "rb") as fobj:
Antoine Pitroud62269f2008-09-15 23:54:52 +000088 self.assertEqual(fobj.read().splitlines(),
89 [b"bacon", b"eggs", b"spam"])
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +000090
91
Christian Heimesdd15f6c2008-03-16 00:07:10 +000092class TemporaryFileTests(unittest.TestCase):
93 def setUp(self):
94 self.files = []
Benjamin Petersonee8712c2008-05-20 21:35:26 +000095 os.mkdir(support.TESTFN)
Christian Heimesdd15f6c2008-03-16 00:07:10 +000096
97 def tearDown(self):
98 for name in self.files:
99 os.unlink(name)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000100 os.rmdir(support.TESTFN)
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000101
102 def check_tempfile(self, name):
103 # make sure it doesn't already exist:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000104 self.assertFalse(os.path.exists(name),
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000105 "file already exists for temporary file")
106 # make sure we can create the file
107 open(name, "w")
108 self.files.append(name)
109
110 def test_tempnam(self):
111 if not hasattr(os, "tempnam"):
112 return
113 warnings.filterwarnings("ignore", "tempnam", RuntimeWarning,
114 r"test_os$")
115 self.check_tempfile(os.tempnam())
116
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000117 name = os.tempnam(support.TESTFN)
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000118 self.check_tempfile(name)
119
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000120 name = os.tempnam(support.TESTFN, "pfx")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000121 self.assertTrue(os.path.basename(name)[:3] == "pfx")
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000122 self.check_tempfile(name)
123
124 def test_tmpfile(self):
125 if not hasattr(os, "tmpfile"):
126 return
127 # As with test_tmpnam() below, the Windows implementation of tmpfile()
128 # attempts to create a file in the root directory of the current drive.
129 # On Vista and Server 2008, this test will always fail for normal users
130 # as writing to the root directory requires elevated privileges. With
131 # XP and below, the semantics of tmpfile() are the same, but the user
132 # running the test is more likely to have administrative privileges on
133 # their account already. If that's the case, then os.tmpfile() should
134 # work. In order to make this test as useful as possible, rather than
135 # trying to detect Windows versions or whether or not the user has the
136 # right permissions, just try and create a file in the root directory
137 # and see if it raises a 'Permission denied' OSError. If it does, then
138 # test that a subsequent call to os.tmpfile() raises the same error. If
139 # it doesn't, assume we're on XP or below and the user running the test
140 # has administrative privileges, and proceed with the test as normal.
141 if sys.platform == 'win32':
142 name = '\\python_test_os_test_tmpfile.txt'
143 if os.path.exists(name):
144 os.remove(name)
145 try:
146 fp = open(name, 'w')
147 except IOError as first:
148 # open() failed, assert tmpfile() fails in the same way.
149 # Although open() raises an IOError and os.tmpfile() raises an
150 # OSError(), 'args' will be (13, 'Permission denied') in both
151 # cases.
152 try:
153 fp = os.tmpfile()
154 except OSError as second:
155 self.assertEqual(first.args, second.args)
156 else:
157 self.fail("expected os.tmpfile() to raise OSError")
158 return
159 else:
160 # open() worked, therefore, tmpfile() should work. Close our
161 # dummy file and proceed with the test as normal.
162 fp.close()
163 os.remove(name)
164
165 fp = os.tmpfile()
166 fp.write("foobar")
167 fp.seek(0,0)
168 s = fp.read()
169 fp.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000170 self.assertTrue(s == "foobar")
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000171
172 def test_tmpnam(self):
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000173 if not hasattr(os, "tmpnam"):
174 return
175 warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning,
176 r"test_os$")
177 name = os.tmpnam()
178 if sys.platform in ("win32",):
179 # The Windows tmpnam() seems useless. From the MS docs:
180 #
181 # The character string that tmpnam creates consists of
182 # the path prefix, defined by the entry P_tmpdir in the
183 # file STDIO.H, followed by a sequence consisting of the
184 # digit characters '0' through '9'; the numerical value
185 # of this string is in the range 1 - 65,535. Changing the
186 # definitions of L_tmpnam or P_tmpdir in STDIO.H does not
187 # change the operation of tmpnam.
188 #
189 # The really bizarre part is that, at least under MSVC6,
190 # P_tmpdir is "\\". That is, the path returned refers to
191 # the root of the current drive. That's a terrible place to
192 # put temp files, and, depending on privileges, the user
193 # may not even be able to open a file in the root directory.
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000194 self.assertFalse(os.path.exists(name),
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000195 "file already exists for temporary file")
196 else:
197 self.check_tempfile(name)
198
Amaury Forgeot d'Arce2e36ba2008-08-01 00:14:22 +0000199 def fdopen_helper(self, *args):
200 fd = os.open(support.TESTFN, os.O_RDONLY)
201 fp2 = os.fdopen(fd, *args)
202 fp2.close()
203
204 def test_fdopen(self):
205 self.fdopen_helper()
206 self.fdopen_helper('r')
207 self.fdopen_helper('r', 100)
208
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000209# Test attributes on return values from os.*stat* family.
210class StatAttributeTests(unittest.TestCase):
211 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000212 os.mkdir(support.TESTFN)
213 self.fname = os.path.join(support.TESTFN, "f1")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000214 f = open(self.fname, 'wb')
Guido van Rossum26d95c32007-08-27 23:18:54 +0000215 f.write(b"ABC")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000216 f.close()
Tim Peterse0c446b2001-10-18 21:57:37 +0000217
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000218 def tearDown(self):
219 os.unlink(self.fname)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000220 os.rmdir(support.TESTFN)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000221
Antoine Pitrou38425292010-09-21 18:19:07 +0000222 def check_stat_attributes(self, fname):
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000223 if not hasattr(os, "stat"):
224 return
225
226 import stat
Antoine Pitrou38425292010-09-21 18:19:07 +0000227 result = os.stat(fname)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000228
229 # Make sure direct access works
230 self.assertEquals(result[stat.ST_SIZE], 3)
231 self.assertEquals(result.st_size, 3)
232
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000233 # Make sure all the attributes are there
234 members = dir(result)
235 for name in dir(stat):
236 if name[:3] == 'ST_':
237 attr = name.lower()
Martin v. Löwis4d394df2005-01-23 09:19:22 +0000238 if name.endswith("TIME"):
239 def trunc(x): return int(x)
240 else:
241 def trunc(x): return x
242 self.assertEquals(trunc(getattr(result, attr)),
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000243 result[getattr(stat, name)])
Benjamin Peterson577473f2010-01-19 00:09:57 +0000244 self.assertIn(attr, members)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000245
246 try:
247 result[200]
248 self.fail("No exception thrown")
249 except IndexError:
250 pass
251
252 # Make sure that assignment fails
253 try:
254 result.st_mode = 1
255 self.fail("No exception thrown")
Collin Winter42dae6a2007-03-28 21:44:53 +0000256 except AttributeError:
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000257 pass
258
259 try:
260 result.st_rdev = 1
261 self.fail("No exception thrown")
Guido van Rossum1fff8782001-10-18 21:19:31 +0000262 except (AttributeError, TypeError):
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000263 pass
264
265 try:
266 result.parrot = 1
267 self.fail("No exception thrown")
268 except AttributeError:
269 pass
270
271 # Use the stat_result constructor with a too-short tuple.
272 try:
273 result2 = os.stat_result((10,))
274 self.fail("No exception thrown")
275 except TypeError:
276 pass
277
278 # Use the constructr with a too-long tuple.
279 try:
280 result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
281 except TypeError:
282 pass
283
Antoine Pitrou38425292010-09-21 18:19:07 +0000284 def test_stat_attributes(self):
285 self.check_stat_attributes(self.fname)
286
287 def test_stat_attributes_bytes(self):
288 try:
289 fname = self.fname.encode(sys.getfilesystemencoding())
290 except UnicodeEncodeError:
291 self.skipTest("cannot encode %a for the filesystem" % self.fname)
292 self.check_stat_attributes(fname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000293
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000294 def test_statvfs_attributes(self):
295 if not hasattr(os, "statvfs"):
296 return
297
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000298 try:
299 result = os.statvfs(self.fname)
Guido van Rossumb940e112007-01-10 16:19:56 +0000300 except OSError as e:
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000301 # On AtheOS, glibc always returns ENOSYS
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000302 if e.errno == errno.ENOSYS:
303 return
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000304
305 # Make sure direct access works
Brett Cannoncfaf10c2008-05-16 00:45:35 +0000306 self.assertEquals(result.f_bfree, result[3])
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000307
Brett Cannoncfaf10c2008-05-16 00:45:35 +0000308 # Make sure all the attributes are there.
309 members = ('bsize', 'frsize', 'blocks', 'bfree', 'bavail', 'files',
310 'ffree', 'favail', 'flag', 'namemax')
311 for value, member in enumerate(members):
312 self.assertEquals(getattr(result, 'f_' + member), result[value])
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000313
314 # Make sure that assignment really fails
315 try:
316 result.f_bfree = 1
317 self.fail("No exception thrown")
Collin Winter42dae6a2007-03-28 21:44:53 +0000318 except AttributeError:
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000319 pass
320
321 try:
322 result.parrot = 1
323 self.fail("No exception thrown")
324 except AttributeError:
325 pass
326
327 # Use the constructor with a too-short tuple.
328 try:
329 result2 = os.statvfs_result((10,))
330 self.fail("No exception thrown")
331 except TypeError:
332 pass
333
334 # Use the constructr with a too-long tuple.
335 try:
336 result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
337 except TypeError:
338 pass
Fred Drake38c2ef02001-07-17 20:52:51 +0000339
Thomas Wouters89f507f2006-12-13 04:49:30 +0000340 def test_utime_dir(self):
341 delta = 1000000
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000342 st = os.stat(support.TESTFN)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000343 # round to int, because some systems may support sub-second
344 # time stamps in stat, but not in utime.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000345 os.utime(support.TESTFN, (st.st_atime, int(st.st_mtime-delta)))
346 st2 = os.stat(support.TESTFN)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000347 self.assertEquals(st2.st_mtime, int(st.st_mtime-delta))
348
349 # Restrict test to Win32, since there is no guarantee other
350 # systems support centiseconds
351 if sys.platform == 'win32':
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000352 def get_file_system(path):
Hirokazu Yamamoto5ef6d182008-08-20 04:17:24 +0000353 root = os.path.splitdrive(os.path.abspath(path))[0] + '\\'
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000354 import ctypes
Hirokazu Yamamotoca765d52008-08-20 16:18:19 +0000355 kernel32 = ctypes.windll.kernel32
Hirokazu Yamamoto5ef6d182008-08-20 04:17:24 +0000356 buf = ctypes.create_unicode_buffer("", 100)
Hirokazu Yamamotoca765d52008-08-20 16:18:19 +0000357 if kernel32.GetVolumeInformationW(root, None, 0, None, None, None, buf, len(buf)):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000358 return buf.value
359
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000360 if get_file_system(support.TESTFN) == "NTFS":
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000361 def test_1565150(self):
362 t1 = 1159195039.25
363 os.utime(self.fname, (t1, t1))
364 self.assertEquals(os.stat(self.fname).st_mtime, t1)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000365
Guido van Rossumd8faa362007-04-27 19:54:29 +0000366 def test_1686475(self):
367 # Verify that an open file can be stat'ed
368 try:
369 os.stat(r"c:\pagefile.sys")
370 except WindowsError as e:
Benjamin Petersonc4fe6f32008-08-19 18:57:56 +0000371 if e.errno == 2: # file does not exist; cannot run test
Guido van Rossumd8faa362007-04-27 19:54:29 +0000372 return
373 self.fail("Could not stat pagefile.sys")
374
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000375from test import mapping_tests
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000376
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000377class EnvironTests(mapping_tests.BasicTestMappingProtocol):
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000378 """check that os.environ object conform to mapping protocol"""
Walter Dörwald118f9312004-06-02 18:42:25 +0000379 type2test = None
Christian Heimes90333392007-11-01 19:08:42 +0000380
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000381 def setUp(self):
382 self.__save = dict(os.environ)
Victor Stinnerb745a742010-05-18 17:17:23 +0000383 if os.supports_bytes_environ:
Victor Stinner208d28c2010-05-07 00:54:14 +0000384 self.__saveb = dict(os.environb)
Christian Heimes90333392007-11-01 19:08:42 +0000385 for key, value in self._reference().items():
386 os.environ[key] = value
387
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000388 def tearDown(self):
389 os.environ.clear()
390 os.environ.update(self.__save)
Victor Stinnerb745a742010-05-18 17:17:23 +0000391 if os.supports_bytes_environ:
Victor Stinner208d28c2010-05-07 00:54:14 +0000392 os.environb.clear()
393 os.environb.update(self.__saveb)
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000394
Christian Heimes90333392007-11-01 19:08:42 +0000395 def _reference(self):
396 return {"KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3"}
397
398 def _empty_mapping(self):
399 os.environ.clear()
400 return os.environ
401
Martin v. Löwis1d11de62005-01-29 13:29:23 +0000402 # Bug 1110478
Martin v. Löwis5510f652005-02-17 21:23:20 +0000403 def test_update2(self):
Christian Heimes90333392007-11-01 19:08:42 +0000404 os.environ.clear()
Martin v. Löwis1d11de62005-01-29 13:29:23 +0000405 if os.path.exists("/bin/sh"):
406 os.environ.update(HELLO="World")
407 value = os.popen("/bin/sh -c 'echo $HELLO'").read().strip()
408 self.assertEquals(value, "World")
409
Christian Heimes1a13d592007-11-08 14:16:55 +0000410 def test_os_popen_iter(self):
411 if os.path.exists("/bin/sh"):
412 popen = os.popen("/bin/sh -c 'echo \"line1\nline2\nline3\"'")
413 it = iter(popen)
414 self.assertEquals(next(it), "line1\n")
415 self.assertEquals(next(it), "line2\n")
416 self.assertEquals(next(it), "line3\n")
417 self.assertRaises(StopIteration, next, it)
418
Guido van Rossum67aca9e2007-06-13 21:51:27 +0000419 # Verify environ keys and values from the OS are of the
420 # correct str type.
421 def test_keyvalue_types(self):
422 for key, val in os.environ.items():
423 self.assertEquals(type(key), str)
424 self.assertEquals(type(val), str)
425
Christian Heimes90333392007-11-01 19:08:42 +0000426 def test_items(self):
427 for key, value in self._reference().items():
428 self.assertEqual(os.environ.get(key), value)
429
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000430 # Issue 7310
431 def test___repr__(self):
432 """Check that the repr() of os.environ looks like environ({...})."""
433 env = os.environ
Victor Stinner96f0de92010-07-29 00:29:00 +0000434 self.assertEqual(repr(env), 'environ({{{}}})'.format(', '.join(
435 '{!r}: {!r}'.format(key, value)
436 for key, value in env.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000437
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000438 def test_get_exec_path(self):
439 defpath_list = os.defpath.split(os.pathsep)
440 test_path = ['/monty', '/python', '', '/flying/circus']
441 test_env = {'PATH': os.pathsep.join(test_path)}
442
443 saved_environ = os.environ
444 try:
445 os.environ = dict(test_env)
446 # Test that defaulting to os.environ works.
447 self.assertSequenceEqual(test_path, os.get_exec_path())
448 self.assertSequenceEqual(test_path, os.get_exec_path(env=None))
449 finally:
450 os.environ = saved_environ
451
452 # No PATH environment variable
453 self.assertSequenceEqual(defpath_list, os.get_exec_path({}))
454 # Empty PATH environment variable
455 self.assertSequenceEqual(('',), os.get_exec_path({'PATH':''}))
456 # Supplied PATH environment variable
457 self.assertSequenceEqual(test_path, os.get_exec_path(test_env))
458
Victor Stinnerb745a742010-05-18 17:17:23 +0000459 if os.supports_bytes_environ:
460 # env cannot contain 'PATH' and b'PATH' keys
Victor Stinner38430e22010-08-19 17:10:18 +0000461 try:
462 mixed_env = {'PATH': '1', b'PATH': b'2'}
463 except BytesWarning:
464 pass
465 else:
466 self.assertRaises(ValueError, os.get_exec_path, mixed_env)
Victor Stinnerb745a742010-05-18 17:17:23 +0000467
468 # bytes key and/or value
469 self.assertSequenceEqual(os.get_exec_path({b'PATH': b'abc'}),
470 ['abc'])
471 self.assertSequenceEqual(os.get_exec_path({b'PATH': 'abc'}),
472 ['abc'])
473 self.assertSequenceEqual(os.get_exec_path({'PATH': b'abc'}),
474 ['abc'])
475
476 @unittest.skipUnless(os.supports_bytes_environ,
477 "os.environb required for this test.")
Victor Stinner84ae1182010-05-06 22:05:07 +0000478 def test_environb(self):
479 # os.environ -> os.environb
480 value = 'euro\u20ac'
481 try:
Benjamin Peterson180799d2010-05-06 22:25:42 +0000482 value_bytes = value.encode(sys.getfilesystemencoding(),
483 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000484 except UnicodeEncodeError:
Benjamin Peterson180799d2010-05-06 22:25:42 +0000485 msg = "U+20AC character is not encodable to %s" % (
486 sys.getfilesystemencoding(),)
Benjamin Peterson932d3f42010-05-06 22:26:31 +0000487 self.skipTest(msg)
Victor Stinner84ae1182010-05-06 22:05:07 +0000488 os.environ['unicode'] = value
489 self.assertEquals(os.environ['unicode'], value)
490 self.assertEquals(os.environb[b'unicode'], value_bytes)
491
492 # os.environb -> os.environ
493 value = b'\xff'
494 os.environb[b'bytes'] = value
495 self.assertEquals(os.environb[b'bytes'], value)
496 value_str = value.decode(sys.getfilesystemencoding(), 'surrogateescape')
497 self.assertEquals(os.environ['bytes'], value_str)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000498
Tim Petersc4e09402003-04-25 07:11:48 +0000499class WalkTests(unittest.TestCase):
500 """Tests for os.walk()."""
501
502 def test_traversal(self):
503 import os
504 from os.path import join
505
506 # Build:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000507 # TESTFN/
508 # TEST1/ a file kid and two directory kids
Tim Petersc4e09402003-04-25 07:11:48 +0000509 # tmp1
510 # SUB1/ a file kid and a directory kid
Guido van Rossumd8faa362007-04-27 19:54:29 +0000511 # tmp2
512 # SUB11/ no kids
513 # SUB2/ a file kid and a dirsymlink kid
514 # tmp3
515 # link/ a symlink to TESTFN.2
516 # TEST2/
517 # tmp4 a lone file
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000518 walk_path = join(support.TESTFN, "TEST1")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000519 sub1_path = join(walk_path, "SUB1")
Tim Petersc4e09402003-04-25 07:11:48 +0000520 sub11_path = join(sub1_path, "SUB11")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000521 sub2_path = join(walk_path, "SUB2")
522 tmp1_path = join(walk_path, "tmp1")
Tim Petersc4e09402003-04-25 07:11:48 +0000523 tmp2_path = join(sub1_path, "tmp2")
524 tmp3_path = join(sub2_path, "tmp3")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000525 link_path = join(sub2_path, "link")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000526 t2_path = join(support.TESTFN, "TEST2")
527 tmp4_path = join(support.TESTFN, "TEST2", "tmp4")
Tim Petersc4e09402003-04-25 07:11:48 +0000528
529 # Create stuff.
530 os.makedirs(sub11_path)
531 os.makedirs(sub2_path)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000532 os.makedirs(t2_path)
533 for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path:
Alex Martelli01c77c62006-08-24 02:58:11 +0000534 f = open(path, "w")
Tim Petersc4e09402003-04-25 07:11:48 +0000535 f.write("I'm " + path + " and proud of it. Blame test_os.\n")
536 f.close()
Brian Curtind40e6f72010-07-08 21:39:08 +0000537 if support.can_symlink():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000538 os.symlink(os.path.abspath(t2_path), link_path)
539 sub2_tree = (sub2_path, ["link"], ["tmp3"])
540 else:
541 sub2_tree = (sub2_path, [], ["tmp3"])
Tim Petersc4e09402003-04-25 07:11:48 +0000542
543 # Walk top-down.
Guido van Rossumd8faa362007-04-27 19:54:29 +0000544 all = list(os.walk(walk_path))
Tim Petersc4e09402003-04-25 07:11:48 +0000545 self.assertEqual(len(all), 4)
546 # We can't know which order SUB1 and SUB2 will appear in.
547 # Not flipped: TESTFN, SUB1, SUB11, SUB2
548 # flipped: TESTFN, SUB2, SUB1, SUB11
549 flipped = all[0][1][0] != "SUB1"
550 all[0][1].sort()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000551 self.assertEqual(all[0], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
Tim Petersc4e09402003-04-25 07:11:48 +0000552 self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"]))
553 self.assertEqual(all[2 + flipped], (sub11_path, [], []))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000554 self.assertEqual(all[3 - 2 * flipped], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000555
556 # Prune the search.
557 all = []
Guido van Rossumd8faa362007-04-27 19:54:29 +0000558 for root, dirs, files in os.walk(walk_path):
Tim Petersc4e09402003-04-25 07:11:48 +0000559 all.append((root, dirs, files))
560 # Don't descend into SUB1.
561 if 'SUB1' in dirs:
562 # Note that this also mutates the dirs we appended to all!
563 dirs.remove('SUB1')
564 self.assertEqual(len(all), 2)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000565 self.assertEqual(all[0], (walk_path, ["SUB2"], ["tmp1"]))
566 self.assertEqual(all[1], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000567
568 # Walk bottom-up.
Guido van Rossumd8faa362007-04-27 19:54:29 +0000569 all = list(os.walk(walk_path, topdown=False))
Tim Petersc4e09402003-04-25 07:11:48 +0000570 self.assertEqual(len(all), 4)
571 # We can't know which order SUB1 and SUB2 will appear in.
572 # Not flipped: SUB11, SUB1, SUB2, TESTFN
573 # flipped: SUB2, SUB11, SUB1, TESTFN
574 flipped = all[3][1][0] != "SUB1"
575 all[3][1].sort()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000576 self.assertEqual(all[3], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
Tim Petersc4e09402003-04-25 07:11:48 +0000577 self.assertEqual(all[flipped], (sub11_path, [], []))
578 self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"]))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000579 self.assertEqual(all[2 - 2 * flipped], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000580
Brian Curtind40e6f72010-07-08 21:39:08 +0000581 if support.can_symlink():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000582 # Walk, following symlinks.
583 for root, dirs, files in os.walk(walk_path, followlinks=True):
584 if root == link_path:
585 self.assertEqual(dirs, [])
586 self.assertEqual(files, ["tmp4"])
587 break
588 else:
589 self.fail("Didn't follow symlink with followlinks=True")
590
591 def tearDown(self):
Tim Petersc4e09402003-04-25 07:11:48 +0000592 # Tear everything down. This is a decent use for bottom-up on
593 # Windows, which doesn't have a recursive delete command. The
594 # (not so) subtlety is that rmdir will fail unless the dir's
595 # kids are removed first, so bottom up is essential.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000596 for root, dirs, files in os.walk(support.TESTFN, topdown=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000597 for name in files:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000598 os.remove(os.path.join(root, name))
Tim Petersc4e09402003-04-25 07:11:48 +0000599 for name in dirs:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000600 dirname = os.path.join(root, name)
601 if not os.path.islink(dirname):
602 os.rmdir(dirname)
603 else:
604 os.remove(dirname)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000605 os.rmdir(support.TESTFN)
Tim Petersc4e09402003-04-25 07:11:48 +0000606
Guido van Rossume7ba4952007-06-06 23:52:48 +0000607class MakedirTests(unittest.TestCase):
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000608 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000609 os.mkdir(support.TESTFN)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000610
611 def test_makedir(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000612 base = support.TESTFN
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000613 path = os.path.join(base, 'dir1', 'dir2', 'dir3')
614 os.makedirs(path) # Should work
615 path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4')
616 os.makedirs(path)
617
618 # Try paths with a '.' in them
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000619 self.assertRaises(OSError, os.makedirs, os.curdir)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000620 path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir)
621 os.makedirs(path)
622 path = os.path.join(base, 'dir1', os.curdir, 'dir2', 'dir3', 'dir4',
623 'dir5', 'dir6')
624 os.makedirs(path)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000625
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000626 def tearDown(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000627 path = os.path.join(support.TESTFN, 'dir1', 'dir2', 'dir3',
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000628 'dir4', 'dir5', 'dir6')
629 # If the tests failed, the bottom-most directory ('../dir6')
630 # may not have been created, so we look for the outermost directory
631 # that exists.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000632 while not os.path.exists(path) and path != support.TESTFN:
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000633 path = os.path.dirname(path)
634
635 os.removedirs(path)
636
Guido van Rossume7ba4952007-06-06 23:52:48 +0000637class DevNullTests(unittest.TestCase):
Martin v. Löwisbdec50f2004-06-08 08:29:33 +0000638 def test_devnull(self):
Alex Martelli01c77c62006-08-24 02:58:11 +0000639 f = open(os.devnull, 'w')
Martin v. Löwisbdec50f2004-06-08 08:29:33 +0000640 f.write('hello')
641 f.close()
Alex Martelli01c77c62006-08-24 02:58:11 +0000642 f = open(os.devnull, 'r')
Tim Peters4182cfd2004-06-08 20:34:34 +0000643 self.assertEqual(f.read(), '')
Martin v. Löwisbdec50f2004-06-08 08:29:33 +0000644 f.close()
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000645
Guido van Rossume7ba4952007-06-06 23:52:48 +0000646class URandomTests(unittest.TestCase):
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000647 def test_urandom(self):
648 try:
649 self.assertEqual(len(os.urandom(1)), 1)
650 self.assertEqual(len(os.urandom(10)), 10)
651 self.assertEqual(len(os.urandom(100)), 100)
652 self.assertEqual(len(os.urandom(1000)), 1000)
653 except NotImplementedError:
654 pass
655
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000656@contextlib.contextmanager
657def _execvpe_mockup(defpath=None):
658 """
659 Stubs out execv and execve functions when used as context manager.
660 Records exec calls. The mock execv and execve functions always raise an
661 exception as they would normally never return.
662 """
663 # A list of tuples containing (function name, first arg, args)
664 # of calls to execv or execve that have been made.
665 calls = []
666
667 def mock_execv(name, *args):
668 calls.append(('execv', name, args))
669 raise RuntimeError("execv called")
670
671 def mock_execve(name, *args):
672 calls.append(('execve', name, args))
673 raise OSError(errno.ENOTDIR, "execve called")
674
675 try:
676 orig_execv = os.execv
677 orig_execve = os.execve
678 orig_defpath = os.defpath
679 os.execv = mock_execv
680 os.execve = mock_execve
681 if defpath is not None:
682 os.defpath = defpath
683 yield calls
684 finally:
685 os.execv = orig_execv
686 os.execve = orig_execve
687 os.defpath = orig_defpath
688
Guido van Rossume7ba4952007-06-06 23:52:48 +0000689class ExecTests(unittest.TestCase):
Mark Dickinson7cf03892010-04-16 13:45:35 +0000690 @unittest.skipIf(USING_LINUXTHREADS,
691 "avoid triggering a linuxthreads bug: see issue #4970")
Guido van Rossume7ba4952007-06-06 23:52:48 +0000692 def test_execvpe_with_bad_program(self):
Mark Dickinson7cf03892010-04-16 13:45:35 +0000693 self.assertRaises(OSError, os.execvpe, 'no such app-',
694 ['no such app-'], None)
Guido van Rossume7ba4952007-06-06 23:52:48 +0000695
Thomas Heller6790d602007-08-30 17:15:14 +0000696 def test_execvpe_with_bad_arglist(self):
697 self.assertRaises(ValueError, os.execvpe, 'notepad', [], None)
698
Gregory P. Smith4ae37772010-05-08 18:05:46 +0000699 @unittest.skipUnless(hasattr(os, '_execvpe'),
700 "No internal os._execvpe function to test.")
Victor Stinnerb745a742010-05-18 17:17:23 +0000701 def _test_internal_execvpe(self, test_type):
702 program_path = os.sep + 'absolutepath'
703 if test_type is bytes:
704 program = b'executable'
705 fullpath = os.path.join(os.fsencode(program_path), program)
706 native_fullpath = fullpath
707 arguments = [b'progname', 'arg1', 'arg2']
708 else:
709 program = 'executable'
710 arguments = ['progname', 'arg1', 'arg2']
711 fullpath = os.path.join(program_path, program)
712 if os.name != "nt":
713 native_fullpath = os.fsencode(fullpath)
714 else:
715 native_fullpath = fullpath
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000716 env = {'spam': 'beans'}
717
Victor Stinnerb745a742010-05-18 17:17:23 +0000718 # test os._execvpe() with an absolute path
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000719 with _execvpe_mockup() as calls:
Victor Stinnerb745a742010-05-18 17:17:23 +0000720 self.assertRaises(RuntimeError,
721 os._execvpe, fullpath, arguments)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000722 self.assertEqual(len(calls), 1)
723 self.assertEqual(calls[0], ('execv', fullpath, (arguments,)))
724
Victor Stinnerb745a742010-05-18 17:17:23 +0000725 # test os._execvpe() with a relative path:
726 # os.get_exec_path() returns defpath
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000727 with _execvpe_mockup(defpath=program_path) as calls:
Victor Stinnerb745a742010-05-18 17:17:23 +0000728 self.assertRaises(OSError,
729 os._execvpe, program, arguments, env=env)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000730 self.assertEqual(len(calls), 1)
Victor Stinnerb745a742010-05-18 17:17:23 +0000731 self.assertSequenceEqual(calls[0],
732 ('execve', native_fullpath, (arguments, env)))
733
734 # test os._execvpe() with a relative path:
735 # os.get_exec_path() reads the 'PATH' variable
736 with _execvpe_mockup() as calls:
737 env_path = env.copy()
Victor Stinner38430e22010-08-19 17:10:18 +0000738 if test_type is bytes:
739 env_path[b'PATH'] = program_path
740 else:
741 env_path['PATH'] = program_path
Victor Stinnerb745a742010-05-18 17:17:23 +0000742 self.assertRaises(OSError,
743 os._execvpe, program, arguments, env=env_path)
744 self.assertEqual(len(calls), 1)
745 self.assertSequenceEqual(calls[0],
746 ('execve', native_fullpath, (arguments, env_path)))
747
748 def test_internal_execvpe_str(self):
749 self._test_internal_execvpe(str)
750 if os.name != "nt":
751 self._test_internal_execvpe(bytes)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000752
Gregory P. Smith4ae37772010-05-08 18:05:46 +0000753
Thomas Wouters477c8d52006-05-27 19:21:47 +0000754class Win32ErrorTests(unittest.TestCase):
755 def test_rename(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000756 self.assertRaises(WindowsError, os.rename, support.TESTFN, support.TESTFN+".bak")
Thomas Wouters477c8d52006-05-27 19:21:47 +0000757
758 def test_remove(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000759 self.assertRaises(WindowsError, os.remove, support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000760
761 def test_chdir(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000762 self.assertRaises(WindowsError, os.chdir, support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000763
764 def test_mkdir(self):
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000765 f = open(support.TESTFN, "w")
Benjamin Petersonf91df042009-02-13 02:50:59 +0000766 try:
767 self.assertRaises(WindowsError, os.mkdir, support.TESTFN)
768 finally:
769 f.close()
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000770 os.unlink(support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000771
772 def test_utime(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000773 self.assertRaises(WindowsError, os.utime, support.TESTFN, None)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000774
Thomas Wouters477c8d52006-05-27 19:21:47 +0000775 def test_chmod(self):
Benjamin Petersonf91df042009-02-13 02:50:59 +0000776 self.assertRaises(WindowsError, os.chmod, support.TESTFN, 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000777
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000778class TestInvalidFD(unittest.TestCase):
Benjamin Peterson05e782f2009-01-19 15:15:02 +0000779 singles = ["fchdir", "dup", "fdopen", "fdatasync", "fstat",
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000780 "fstatvfs", "fsync", "tcgetpgrp", "ttyname"]
781 #singles.append("close")
782 #We omit close because it doesn'r raise an exception on some platforms
783 def get_single(f):
784 def helper(self):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000785 if hasattr(os, f):
786 self.check(getattr(os, f))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000787 return helper
788 for f in singles:
789 locals()["test_"+f] = get_single(f)
790
Benjamin Peterson7522c742009-01-19 21:00:09 +0000791 def check(self, f, *args):
Benjamin Peterson5c6d7872009-02-06 02:40:07 +0000792 try:
793 f(support.make_bad_fd(), *args)
794 except OSError as e:
795 self.assertEqual(e.errno, errno.EBADF)
796 else:
797 self.fail("%r didn't raise a OSError with a bad file descriptor"
798 % f)
Benjamin Peterson7522c742009-01-19 21:00:09 +0000799
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000800 def test_isatty(self):
801 if hasattr(os, "isatty"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000802 self.assertEqual(os.isatty(support.make_bad_fd()), False)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000803
804 def test_closerange(self):
805 if hasattr(os, "closerange"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000806 fd = support.make_bad_fd()
R. David Murray630cc482009-07-22 15:20:27 +0000807 # Make sure none of the descriptors we are about to close are
808 # currently valid (issue 6542).
809 for i in range(10):
810 try: os.fstat(fd+i)
811 except OSError:
812 pass
813 else:
814 break
815 if i < 2:
816 raise unittest.SkipTest(
817 "Unable to acquire a range of invalid file descriptors")
818 self.assertEqual(os.closerange(fd, fd + i-1), None)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000819
820 def test_dup2(self):
821 if hasattr(os, "dup2"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000822 self.check(os.dup2, 20)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000823
824 def test_fchmod(self):
825 if hasattr(os, "fchmod"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000826 self.check(os.fchmod, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000827
828 def test_fchown(self):
829 if hasattr(os, "fchown"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000830 self.check(os.fchown, -1, -1)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000831
832 def test_fpathconf(self):
833 if hasattr(os, "fpathconf"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000834 self.check(os.fpathconf, "PC_NAME_MAX")
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000835
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000836 def test_ftruncate(self):
837 if hasattr(os, "ftruncate"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000838 self.check(os.ftruncate, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000839
840 def test_lseek(self):
841 if hasattr(os, "lseek"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000842 self.check(os.lseek, 0, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000843
844 def test_read(self):
845 if hasattr(os, "read"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000846 self.check(os.read, 1)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000847
848 def test_tcsetpgrpt(self):
849 if hasattr(os, "tcsetpgrp"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000850 self.check(os.tcsetpgrp, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000851
852 def test_write(self):
853 if hasattr(os, "write"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000854 self.check(os.write, b" ")
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000855
Thomas Wouters477c8d52006-05-27 19:21:47 +0000856if sys.platform != 'win32':
857 class Win32ErrorTests(unittest.TestCase):
858 pass
859
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000860 class PosixUidGidTests(unittest.TestCase):
861 if hasattr(os, 'setuid'):
862 def test_setuid(self):
863 if os.getuid() != 0:
864 self.assertRaises(os.error, os.setuid, 0)
865 self.assertRaises(OverflowError, os.setuid, 1<<32)
866
867 if hasattr(os, 'setgid'):
868 def test_setgid(self):
869 if os.getuid() != 0:
870 self.assertRaises(os.error, os.setgid, 0)
871 self.assertRaises(OverflowError, os.setgid, 1<<32)
872
873 if hasattr(os, 'seteuid'):
874 def test_seteuid(self):
875 if os.getuid() != 0:
876 self.assertRaises(os.error, os.seteuid, 0)
877 self.assertRaises(OverflowError, os.seteuid, 1<<32)
878
879 if hasattr(os, 'setegid'):
880 def test_setegid(self):
881 if os.getuid() != 0:
882 self.assertRaises(os.error, os.setegid, 0)
883 self.assertRaises(OverflowError, os.setegid, 1<<32)
884
885 if hasattr(os, 'setreuid'):
886 def test_setreuid(self):
887 if os.getuid() != 0:
888 self.assertRaises(os.error, os.setreuid, 0, 0)
889 self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
890 self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000891
892 def test_setreuid_neg1(self):
893 # Needs to accept -1. We run this in a subprocess to avoid
894 # altering the test runner's process state (issue8045).
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000895 subprocess.check_call([
896 sys.executable, '-c',
897 'import os,sys;os.setreuid(-1,-1);sys.exit(0)'])
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000898
899 if hasattr(os, 'setregid'):
900 def test_setregid(self):
901 if os.getuid() != 0:
902 self.assertRaises(os.error, os.setregid, 0, 0)
903 self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
904 self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000905
906 def test_setregid_neg1(self):
907 # Needs to accept -1. We run this in a subprocess to avoid
908 # altering the test runner's process state (issue8045).
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000909 subprocess.check_call([
910 sys.executable, '-c',
911 'import os,sys;os.setregid(-1,-1);sys.exit(0)'])
Martin v. Löwis011e8422009-05-05 04:43:17 +0000912
913 class Pep383Tests(unittest.TestCase):
Martin v. Löwis011e8422009-05-05 04:43:17 +0000914 def setUp(self):
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000915 if support.TESTFN_UNENCODABLE:
916 self.dir = support.TESTFN_UNENCODABLE
917 else:
918 self.dir = support.TESTFN
919 self.bdir = os.fsencode(self.dir)
920
921 bytesfn = []
922 def add_filename(fn):
923 try:
924 fn = os.fsencode(fn)
925 except UnicodeEncodeError:
926 return
927 bytesfn.append(fn)
928 add_filename(support.TESTFN_UNICODE)
929 if support.TESTFN_UNENCODABLE:
930 add_filename(support.TESTFN_UNENCODABLE)
931 if not bytesfn:
932 self.skipTest("couldn't create any non-ascii filename")
933
934 self.unicodefn = set()
Martin v. Löwis011e8422009-05-05 04:43:17 +0000935 os.mkdir(self.dir)
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000936 try:
937 for fn in bytesfn:
938 f = open(os.path.join(self.bdir, fn), "w")
939 f.close()
Victor Stinnere8d51452010-08-19 01:05:19 +0000940 fn = os.fsdecode(fn)
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000941 if fn in self.unicodefn:
942 raise ValueError("duplicate filename")
943 self.unicodefn.add(fn)
944 except:
945 shutil.rmtree(self.dir)
946 raise
Martin v. Löwis011e8422009-05-05 04:43:17 +0000947
948 def tearDown(self):
949 shutil.rmtree(self.dir)
Martin v. Löwis011e8422009-05-05 04:43:17 +0000950
951 def test_listdir(self):
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000952 expected = self.unicodefn
953 found = set(os.listdir(self.dir))
Martin v. Löwis011e8422009-05-05 04:43:17 +0000954 self.assertEquals(found, expected)
955
956 def test_open(self):
957 for fn in self.unicodefn:
958 f = open(os.path.join(self.dir, fn))
959 f.close()
960
961 def test_stat(self):
962 for fn in self.unicodefn:
963 os.stat(os.path.join(self.dir, fn))
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000964else:
965 class PosixUidGidTests(unittest.TestCase):
966 pass
Martin v. Löwis011e8422009-05-05 04:43:17 +0000967 class Pep383Tests(unittest.TestCase):
968 pass
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000969
Brian Curtineb24d742010-04-12 17:16:38 +0000970@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
971class Win32KillTests(unittest.TestCase):
Brian Curtinc3acbc32010-05-28 16:08:40 +0000972 def _kill(self, sig):
973 # Start sys.executable as a subprocess and communicate from the
974 # subprocess to the parent that the interpreter is ready. When it
975 # becomes ready, send *sig* via os.kill to the subprocess and check
976 # that the return code is equal to *sig*.
977 import ctypes
978 from ctypes import wintypes
979 import msvcrt
980
981 # Since we can't access the contents of the process' stdout until the
982 # process has exited, use PeekNamedPipe to see what's inside stdout
983 # without waiting. This is done so we can tell that the interpreter
984 # is started and running at a point where it could handle a signal.
985 PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe
986 PeekNamedPipe.restype = wintypes.BOOL
987 PeekNamedPipe.argtypes = (wintypes.HANDLE, # Pipe handle
988 ctypes.POINTER(ctypes.c_char), # stdout buf
989 wintypes.DWORD, # Buffer size
990 ctypes.POINTER(wintypes.DWORD), # bytes read
991 ctypes.POINTER(wintypes.DWORD), # bytes avail
992 ctypes.POINTER(wintypes.DWORD)) # bytes left
993 msg = "running"
994 proc = subprocess.Popen([sys.executable, "-c",
995 "import sys;"
996 "sys.stdout.write('{}');"
997 "sys.stdout.flush();"
998 "input()".format(msg)],
999 stdout=subprocess.PIPE,
1000 stderr=subprocess.PIPE,
1001 stdin=subprocess.PIPE)
1002
1003 count, max = 0, 100
1004 while count < max and proc.poll() is None:
1005 # Create a string buffer to store the result of stdout from the pipe
1006 buf = ctypes.create_string_buffer(len(msg))
1007 # Obtain the text currently in proc.stdout
1008 # Bytes read/avail/left are left as NULL and unused
1009 rslt = PeekNamedPipe(msvcrt.get_osfhandle(proc.stdout.fileno()),
1010 buf, ctypes.sizeof(buf), None, None, None)
1011 self.assertNotEqual(rslt, 0, "PeekNamedPipe failed")
1012 if buf.value:
1013 self.assertEqual(msg, buf.value.decode())
1014 break
1015 time.sleep(0.1)
1016 count += 1
1017 else:
1018 self.fail("Did not receive communication from the subprocess")
1019
Brian Curtineb24d742010-04-12 17:16:38 +00001020 os.kill(proc.pid, sig)
1021 self.assertEqual(proc.wait(), sig)
1022
1023 def test_kill_sigterm(self):
1024 # SIGTERM doesn't mean anything special, but make sure it works
Brian Curtinc3acbc32010-05-28 16:08:40 +00001025 self._kill(signal.SIGTERM)
Brian Curtineb24d742010-04-12 17:16:38 +00001026
1027 def test_kill_int(self):
1028 # os.kill on Windows can take an int which gets set as the exit code
Brian Curtinc3acbc32010-05-28 16:08:40 +00001029 self._kill(100)
Brian Curtineb24d742010-04-12 17:16:38 +00001030
1031 def _kill_with_event(self, event, name):
1032 # Run a script which has console control handling enabled.
1033 proc = subprocess.Popen([sys.executable,
1034 os.path.join(os.path.dirname(__file__),
1035 "win_console_handler.py")],
1036 creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
1037 # Let the interpreter startup before we send signals. See #3137.
1038 time.sleep(0.5)
1039 os.kill(proc.pid, event)
1040 # proc.send_signal(event) could also be done here.
1041 # Allow time for the signal to be passed and the process to exit.
1042 time.sleep(0.5)
1043 if not proc.poll():
1044 # Forcefully kill the process if we weren't able to signal it.
1045 os.kill(proc.pid, signal.SIGINT)
1046 self.fail("subprocess did not stop on {}".format(name))
1047
1048 @unittest.skip("subprocesses aren't inheriting CTRL+C property")
1049 def test_CTRL_C_EVENT(self):
1050 from ctypes import wintypes
1051 import ctypes
1052
1053 # Make a NULL value by creating a pointer with no argument.
1054 NULL = ctypes.POINTER(ctypes.c_int)()
1055 SetConsoleCtrlHandler = ctypes.windll.kernel32.SetConsoleCtrlHandler
1056 SetConsoleCtrlHandler.argtypes = (ctypes.POINTER(ctypes.c_int),
1057 wintypes.BOOL)
1058 SetConsoleCtrlHandler.restype = wintypes.BOOL
1059
1060 # Calling this with NULL and FALSE causes the calling process to
1061 # handle CTRL+C, rather than ignore it. This property is inherited
1062 # by subprocesses.
1063 SetConsoleCtrlHandler(NULL, 0)
1064
1065 self._kill_with_event(signal.CTRL_C_EVENT, "CTRL_C_EVENT")
1066
1067 def test_CTRL_BREAK_EVENT(self):
1068 self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT")
1069
1070
Brian Curtind40e6f72010-07-08 21:39:08 +00001071def skipUnlessWindows6(test):
Brian Curtin74e45612010-07-09 15:58:59 +00001072 if (hasattr(sys, 'getwindowsversion')
1073 and sys.getwindowsversion().major >= 6):
Brian Curtind40e6f72010-07-08 21:39:08 +00001074 return test
1075 return unittest.skip("Requires Windows Vista or later")(test)
1076
1077@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
1078@support.skip_unless_symlink
1079class Win32SymlinkTests(unittest.TestCase):
1080 filelink = 'filelinktest'
1081 filelink_target = os.path.abspath(__file__)
1082 dirlink = 'dirlinktest'
1083 dirlink_target = os.path.dirname(filelink_target)
1084 missing_link = 'missing link'
1085
1086 def setUp(self):
1087 assert os.path.exists(self.dirlink_target)
1088 assert os.path.exists(self.filelink_target)
1089 assert not os.path.exists(self.dirlink)
1090 assert not os.path.exists(self.filelink)
1091 assert not os.path.exists(self.missing_link)
1092
1093 def tearDown(self):
1094 if os.path.exists(self.filelink):
1095 os.remove(self.filelink)
1096 if os.path.exists(self.dirlink):
1097 os.rmdir(self.dirlink)
1098 if os.path.lexists(self.missing_link):
1099 os.remove(self.missing_link)
1100
1101 def test_directory_link(self):
1102 os.symlink(self.dirlink_target, self.dirlink)
1103 self.assertTrue(os.path.exists(self.dirlink))
1104 self.assertTrue(os.path.isdir(self.dirlink))
1105 self.assertTrue(os.path.islink(self.dirlink))
1106 self.check_stat(self.dirlink, self.dirlink_target)
1107
1108 def test_file_link(self):
1109 os.symlink(self.filelink_target, self.filelink)
1110 self.assertTrue(os.path.exists(self.filelink))
1111 self.assertTrue(os.path.isfile(self.filelink))
1112 self.assertTrue(os.path.islink(self.filelink))
1113 self.check_stat(self.filelink, self.filelink_target)
1114
1115 def _create_missing_dir_link(self):
1116 'Create a "directory" link to a non-existent target'
1117 linkname = self.missing_link
1118 if os.path.lexists(linkname):
1119 os.remove(linkname)
1120 target = r'c:\\target does not exist.29r3c740'
1121 assert not os.path.exists(target)
1122 target_is_dir = True
1123 os.symlink(target, linkname, target_is_dir)
1124
1125 def test_remove_directory_link_to_missing_target(self):
1126 self._create_missing_dir_link()
1127 # For compatibility with Unix, os.remove will check the
1128 # directory status and call RemoveDirectory if the symlink
1129 # was created with target_is_dir==True.
1130 os.remove(self.missing_link)
1131
1132 @unittest.skip("currently fails; consider for improvement")
1133 def test_isdir_on_directory_link_to_missing_target(self):
1134 self._create_missing_dir_link()
1135 # consider having isdir return true for directory links
1136 self.assertTrue(os.path.isdir(self.missing_link))
1137
1138 @unittest.skip("currently fails; consider for improvement")
1139 def test_rmdir_on_directory_link_to_missing_target(self):
1140 self._create_missing_dir_link()
1141 # consider allowing rmdir to remove directory links
1142 os.rmdir(self.missing_link)
1143
1144 def check_stat(self, link, target):
1145 self.assertEqual(os.stat(link), os.stat(target))
1146 self.assertNotEqual(os.lstat(link), os.stat(link))
1147
1148
Victor Stinnere8d51452010-08-19 01:05:19 +00001149class FSEncodingTests(unittest.TestCase):
1150 def test_nop(self):
1151 self.assertEquals(os.fsencode(b'abc\xff'), b'abc\xff')
1152 self.assertEquals(os.fsdecode('abc\u0141'), 'abc\u0141')
Benjamin Peterson31191a92010-05-09 03:22:58 +00001153
Victor Stinnere8d51452010-08-19 01:05:19 +00001154 def test_identity(self):
1155 # assert fsdecode(fsencode(x)) == x
1156 for fn in ('unicode\u0141', 'latin\xe9', 'ascii'):
1157 try:
1158 bytesfn = os.fsencode(fn)
1159 except UnicodeEncodeError:
1160 continue
1161 self.assertEquals(os.fsdecode(bytesfn), fn)
1162
1163 def get_output(self, fs_encoding, func):
1164 env = os.environ.copy()
1165 env['PYTHONIOENCODING'] = 'utf-8'
1166 env['PYTHONFSENCODING'] = fs_encoding
1167 code = 'import os; print(%s, end="")' % func
1168 process = subprocess.Popen(
1169 [sys.executable, "-c", code],
1170 stdout=subprocess.PIPE, env=env)
1171 stdout, stderr = process.communicate()
1172 self.assertEqual(process.returncode, 0)
1173 return stdout.decode('utf-8')
1174
Victor Stinner114b7242010-08-19 17:22:57 +00001175 @unittest.skipIf(sys.platform in ('win32', 'darwin'),
1176 'PYTHONFSENCODING is ignored on Windows and Mac OS X')
Victor Stinnere8d51452010-08-19 01:05:19 +00001177 def test_encodings(self):
1178 def check(encoding, bytesfn, unicodefn):
1179 encoded = self.get_output(encoding, 'repr(os.fsencode(%a))' % unicodefn)
1180 self.assertEqual(encoded, repr(bytesfn))
1181
1182 decoded = self.get_output(encoding, 'repr(os.fsdecode(%a))' % bytesfn)
1183 self.assertEqual(decoded, repr(unicodefn))
1184
Victor Stinnere8d51452010-08-19 01:05:19 +00001185 check('utf-8', b'\xc3\xa9\x80', '\xe9\udc80')
Victor Stinnerc44abb12010-08-20 16:52:14 +00001186
1187 # Raise SkipTest() if sys.executable is not encodable to ascii
1188 support.workaroundIssue8611()
1189
1190 check('ascii', b'abc\xff', 'abc\udcff')
1191 check('iso-8859-15', b'\xef\xa4', '\xef\u20ac')
Victor Stinnerbf9bcab2010-05-09 03:15:33 +00001192
1193
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00001194class PidTests(unittest.TestCase):
1195 @unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid")
1196 def test_getppid(self):
1197 p = subprocess.Popen([sys.executable, '-c',
1198 'import os; print(os.getppid())'],
1199 stdout=subprocess.PIPE)
1200 stdout, _ = p.communicate()
1201 # We are the parent of our subprocess
1202 self.assertEqual(int(stdout), os.getpid())
1203
1204
Brian Curtin0151b8e2010-09-24 13:43:43 +00001205# The introduction of this TestCase caused at least two different errors on
1206# *nix buildbots. Temporarily skip this to let the buildbots move along.
1207@unittest.skip("Skip due to platform/environment differences on *NIX buildbots")
Brian Curtine8e4b3b2010-09-23 20:04:14 +00001208@unittest.skipUnless(hasattr(os, 'getlogin'), "test needs os.getlogin")
1209class LoginTests(unittest.TestCase):
1210 def test_getlogin(self):
1211 user_name = os.getlogin()
1212 self.assertNotEqual(len(user_name), 0)
1213
1214
Fred Drake2e2be372001-09-20 21:33:42 +00001215def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001216 support.run_unittest(
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001217 FileTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001218 StatAttributeTests,
1219 EnvironTests,
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001220 WalkTests,
1221 MakedirTests,
Martin v. Löwisbdec50f2004-06-08 08:29:33 +00001222 DevNullTests,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001223 URandomTests,
Guido van Rossume7ba4952007-06-06 23:52:48 +00001224 ExecTests,
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001225 Win32ErrorTests,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001226 TestInvalidFD,
Martin v. Löwis011e8422009-05-05 04:43:17 +00001227 PosixUidGidTests,
Brian Curtineb24d742010-04-12 17:16:38 +00001228 Pep383Tests,
Victor Stinnerbf9bcab2010-05-09 03:15:33 +00001229 Win32KillTests,
Brian Curtind40e6f72010-07-08 21:39:08 +00001230 Win32SymlinkTests,
Victor Stinnere8d51452010-08-19 01:05:19 +00001231 FSEncodingTests,
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00001232 PidTests,
Brian Curtine8e4b3b2010-09-23 20:04:14 +00001233 LoginTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001234 )
Fred Drake2e2be372001-09-20 21:33:42 +00001235
1236if __name__ == "__main__":
1237 test_main()