blob: e413e1facc495408a046000bbaab93d2c5748f77 [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:
464 mixed_env = {'PATH': '1', b'PATH': b'2'}
465 except BytesWarning:
466 pass
467 else:
468 self.assertRaises(ValueError, os.get_exec_path, mixed_env)
Victor Stinnerb745a742010-05-18 17:17:23 +0000469
470 # bytes key and/or value
471 self.assertSequenceEqual(os.get_exec_path({b'PATH': b'abc'}),
472 ['abc'])
473 self.assertSequenceEqual(os.get_exec_path({b'PATH': 'abc'}),
474 ['abc'])
475 self.assertSequenceEqual(os.get_exec_path({'PATH': b'abc'}),
476 ['abc'])
477
478 @unittest.skipUnless(os.supports_bytes_environ,
479 "os.environb required for this test.")
Victor Stinner84ae1182010-05-06 22:05:07 +0000480 def test_environb(self):
481 # os.environ -> os.environb
482 value = 'euro\u20ac'
483 try:
Benjamin Peterson180799d2010-05-06 22:25:42 +0000484 value_bytes = value.encode(sys.getfilesystemencoding(),
485 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000486 except UnicodeEncodeError:
Benjamin Peterson180799d2010-05-06 22:25:42 +0000487 msg = "U+20AC character is not encodable to %s" % (
488 sys.getfilesystemencoding(),)
Benjamin Peterson932d3f42010-05-06 22:26:31 +0000489 self.skipTest(msg)
Victor Stinner84ae1182010-05-06 22:05:07 +0000490 os.environ['unicode'] = value
491 self.assertEquals(os.environ['unicode'], value)
492 self.assertEquals(os.environb[b'unicode'], value_bytes)
493
494 # os.environb -> os.environ
495 value = b'\xff'
496 os.environb[b'bytes'] = value
497 self.assertEquals(os.environb[b'bytes'], value)
498 value_str = value.decode(sys.getfilesystemencoding(), 'surrogateescape')
499 self.assertEquals(os.environ['bytes'], value_str)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000500
Tim Petersc4e09402003-04-25 07:11:48 +0000501class WalkTests(unittest.TestCase):
502 """Tests for os.walk()."""
503
504 def test_traversal(self):
505 import os
506 from os.path import join
507
508 # Build:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000509 # TESTFN/
510 # TEST1/ a file kid and two directory kids
Tim Petersc4e09402003-04-25 07:11:48 +0000511 # tmp1
512 # SUB1/ a file kid and a directory kid
Guido van Rossumd8faa362007-04-27 19:54:29 +0000513 # tmp2
514 # SUB11/ no kids
515 # SUB2/ a file kid and a dirsymlink kid
516 # tmp3
517 # link/ a symlink to TESTFN.2
518 # TEST2/
519 # tmp4 a lone file
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000520 walk_path = join(support.TESTFN, "TEST1")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000521 sub1_path = join(walk_path, "SUB1")
Tim Petersc4e09402003-04-25 07:11:48 +0000522 sub11_path = join(sub1_path, "SUB11")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000523 sub2_path = join(walk_path, "SUB2")
524 tmp1_path = join(walk_path, "tmp1")
Tim Petersc4e09402003-04-25 07:11:48 +0000525 tmp2_path = join(sub1_path, "tmp2")
526 tmp3_path = join(sub2_path, "tmp3")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000527 link_path = join(sub2_path, "link")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000528 t2_path = join(support.TESTFN, "TEST2")
529 tmp4_path = join(support.TESTFN, "TEST2", "tmp4")
Tim Petersc4e09402003-04-25 07:11:48 +0000530
531 # Create stuff.
532 os.makedirs(sub11_path)
533 os.makedirs(sub2_path)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000534 os.makedirs(t2_path)
535 for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path:
Alex Martelli01c77c62006-08-24 02:58:11 +0000536 f = open(path, "w")
Tim Petersc4e09402003-04-25 07:11:48 +0000537 f.write("I'm " + path + " and proud of it. Blame test_os.\n")
538 f.close()
Brian Curtind40e6f72010-07-08 21:39:08 +0000539 if support.can_symlink():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000540 os.symlink(os.path.abspath(t2_path), link_path)
541 sub2_tree = (sub2_path, ["link"], ["tmp3"])
542 else:
543 sub2_tree = (sub2_path, [], ["tmp3"])
Tim Petersc4e09402003-04-25 07:11:48 +0000544
545 # Walk top-down.
Guido van Rossumd8faa362007-04-27 19:54:29 +0000546 all = list(os.walk(walk_path))
Tim Petersc4e09402003-04-25 07:11:48 +0000547 self.assertEqual(len(all), 4)
548 # We can't know which order SUB1 and SUB2 will appear in.
549 # Not flipped: TESTFN, SUB1, SUB11, SUB2
550 # flipped: TESTFN, SUB2, SUB1, SUB11
551 flipped = all[0][1][0] != "SUB1"
552 all[0][1].sort()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000553 self.assertEqual(all[0], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
Tim Petersc4e09402003-04-25 07:11:48 +0000554 self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"]))
555 self.assertEqual(all[2 + flipped], (sub11_path, [], []))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000556 self.assertEqual(all[3 - 2 * flipped], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000557
558 # Prune the search.
559 all = []
Guido van Rossumd8faa362007-04-27 19:54:29 +0000560 for root, dirs, files in os.walk(walk_path):
Tim Petersc4e09402003-04-25 07:11:48 +0000561 all.append((root, dirs, files))
562 # Don't descend into SUB1.
563 if 'SUB1' in dirs:
564 # Note that this also mutates the dirs we appended to all!
565 dirs.remove('SUB1')
566 self.assertEqual(len(all), 2)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000567 self.assertEqual(all[0], (walk_path, ["SUB2"], ["tmp1"]))
568 self.assertEqual(all[1], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000569
570 # Walk bottom-up.
Guido van Rossumd8faa362007-04-27 19:54:29 +0000571 all = list(os.walk(walk_path, topdown=False))
Tim Petersc4e09402003-04-25 07:11:48 +0000572 self.assertEqual(len(all), 4)
573 # We can't know which order SUB1 and SUB2 will appear in.
574 # Not flipped: SUB11, SUB1, SUB2, TESTFN
575 # flipped: SUB2, SUB11, SUB1, TESTFN
576 flipped = all[3][1][0] != "SUB1"
577 all[3][1].sort()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000578 self.assertEqual(all[3], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
Tim Petersc4e09402003-04-25 07:11:48 +0000579 self.assertEqual(all[flipped], (sub11_path, [], []))
580 self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"]))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000581 self.assertEqual(all[2 - 2 * flipped], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000582
Brian Curtind40e6f72010-07-08 21:39:08 +0000583 if support.can_symlink():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000584 # Walk, following symlinks.
585 for root, dirs, files in os.walk(walk_path, followlinks=True):
586 if root == link_path:
587 self.assertEqual(dirs, [])
588 self.assertEqual(files, ["tmp4"])
589 break
590 else:
591 self.fail("Didn't follow symlink with followlinks=True")
592
593 def tearDown(self):
Tim Petersc4e09402003-04-25 07:11:48 +0000594 # Tear everything down. This is a decent use for bottom-up on
595 # Windows, which doesn't have a recursive delete command. The
596 # (not so) subtlety is that rmdir will fail unless the dir's
597 # kids are removed first, so bottom up is essential.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000598 for root, dirs, files in os.walk(support.TESTFN, topdown=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000599 for name in files:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000600 os.remove(os.path.join(root, name))
Tim Petersc4e09402003-04-25 07:11:48 +0000601 for name in dirs:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000602 dirname = os.path.join(root, name)
603 if not os.path.islink(dirname):
604 os.rmdir(dirname)
605 else:
606 os.remove(dirname)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000607 os.rmdir(support.TESTFN)
Tim Petersc4e09402003-04-25 07:11:48 +0000608
Guido van Rossume7ba4952007-06-06 23:52:48 +0000609class MakedirTests(unittest.TestCase):
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000610 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000611 os.mkdir(support.TESTFN)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000612
613 def test_makedir(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000614 base = support.TESTFN
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000615 path = os.path.join(base, 'dir1', 'dir2', 'dir3')
616 os.makedirs(path) # Should work
617 path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4')
618 os.makedirs(path)
619
620 # Try paths with a '.' in them
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000621 self.assertRaises(OSError, os.makedirs, os.curdir)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000622 path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir)
623 os.makedirs(path)
624 path = os.path.join(base, 'dir1', os.curdir, 'dir2', 'dir3', 'dir4',
625 'dir5', 'dir6')
626 os.makedirs(path)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000627
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000628 def tearDown(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000629 path = os.path.join(support.TESTFN, 'dir1', 'dir2', 'dir3',
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000630 'dir4', 'dir5', 'dir6')
631 # If the tests failed, the bottom-most directory ('../dir6')
632 # may not have been created, so we look for the outermost directory
633 # that exists.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000634 while not os.path.exists(path) and path != support.TESTFN:
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000635 path = os.path.dirname(path)
636
637 os.removedirs(path)
638
Guido van Rossume7ba4952007-06-06 23:52:48 +0000639class DevNullTests(unittest.TestCase):
Martin v. Löwisbdec50f2004-06-08 08:29:33 +0000640 def test_devnull(self):
Alex Martelli01c77c62006-08-24 02:58:11 +0000641 f = open(os.devnull, 'w')
Martin v. Löwisbdec50f2004-06-08 08:29:33 +0000642 f.write('hello')
643 f.close()
Alex Martelli01c77c62006-08-24 02:58:11 +0000644 f = open(os.devnull, 'r')
Tim Peters4182cfd2004-06-08 20:34:34 +0000645 self.assertEqual(f.read(), '')
Martin v. Löwisbdec50f2004-06-08 08:29:33 +0000646 f.close()
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000647
Guido van Rossume7ba4952007-06-06 23:52:48 +0000648class URandomTests(unittest.TestCase):
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000649 def test_urandom(self):
650 try:
651 self.assertEqual(len(os.urandom(1)), 1)
652 self.assertEqual(len(os.urandom(10)), 10)
653 self.assertEqual(len(os.urandom(100)), 100)
654 self.assertEqual(len(os.urandom(1000)), 1000)
655 except NotImplementedError:
656 pass
657
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000658@contextlib.contextmanager
659def _execvpe_mockup(defpath=None):
660 """
661 Stubs out execv and execve functions when used as context manager.
662 Records exec calls. The mock execv and execve functions always raise an
663 exception as they would normally never return.
664 """
665 # A list of tuples containing (function name, first arg, args)
666 # of calls to execv or execve that have been made.
667 calls = []
668
669 def mock_execv(name, *args):
670 calls.append(('execv', name, args))
671 raise RuntimeError("execv called")
672
673 def mock_execve(name, *args):
674 calls.append(('execve', name, args))
675 raise OSError(errno.ENOTDIR, "execve called")
676
677 try:
678 orig_execv = os.execv
679 orig_execve = os.execve
680 orig_defpath = os.defpath
681 os.execv = mock_execv
682 os.execve = mock_execve
683 if defpath is not None:
684 os.defpath = defpath
685 yield calls
686 finally:
687 os.execv = orig_execv
688 os.execve = orig_execve
689 os.defpath = orig_defpath
690
Guido van Rossume7ba4952007-06-06 23:52:48 +0000691class ExecTests(unittest.TestCase):
Mark Dickinson7cf03892010-04-16 13:45:35 +0000692 @unittest.skipIf(USING_LINUXTHREADS,
693 "avoid triggering a linuxthreads bug: see issue #4970")
Guido van Rossume7ba4952007-06-06 23:52:48 +0000694 def test_execvpe_with_bad_program(self):
Mark Dickinson7cf03892010-04-16 13:45:35 +0000695 self.assertRaises(OSError, os.execvpe, 'no such app-',
696 ['no such app-'], None)
Guido van Rossume7ba4952007-06-06 23:52:48 +0000697
Thomas Heller6790d602007-08-30 17:15:14 +0000698 def test_execvpe_with_bad_arglist(self):
699 self.assertRaises(ValueError, os.execvpe, 'notepad', [], None)
700
Gregory P. Smith4ae37772010-05-08 18:05:46 +0000701 @unittest.skipUnless(hasattr(os, '_execvpe'),
702 "No internal os._execvpe function to test.")
Victor Stinnerb745a742010-05-18 17:17:23 +0000703 def _test_internal_execvpe(self, test_type):
704 program_path = os.sep + 'absolutepath'
705 if test_type is bytes:
706 program = b'executable'
707 fullpath = os.path.join(os.fsencode(program_path), program)
708 native_fullpath = fullpath
709 arguments = [b'progname', 'arg1', 'arg2']
710 else:
711 program = 'executable'
712 arguments = ['progname', 'arg1', 'arg2']
713 fullpath = os.path.join(program_path, program)
714 if os.name != "nt":
715 native_fullpath = os.fsencode(fullpath)
716 else:
717 native_fullpath = fullpath
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000718 env = {'spam': 'beans'}
719
Victor Stinnerb745a742010-05-18 17:17:23 +0000720 # test os._execvpe() with an absolute path
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000721 with _execvpe_mockup() as calls:
Victor Stinnerb745a742010-05-18 17:17:23 +0000722 self.assertRaises(RuntimeError,
723 os._execvpe, fullpath, arguments)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000724 self.assertEqual(len(calls), 1)
725 self.assertEqual(calls[0], ('execv', fullpath, (arguments,)))
726
Victor Stinnerb745a742010-05-18 17:17:23 +0000727 # test os._execvpe() with a relative path:
728 # os.get_exec_path() returns defpath
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000729 with _execvpe_mockup(defpath=program_path) as calls:
Victor Stinnerb745a742010-05-18 17:17:23 +0000730 self.assertRaises(OSError,
731 os._execvpe, program, arguments, env=env)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000732 self.assertEqual(len(calls), 1)
Victor Stinnerb745a742010-05-18 17:17:23 +0000733 self.assertSequenceEqual(calls[0],
734 ('execve', native_fullpath, (arguments, env)))
735
736 # test os._execvpe() with a relative path:
737 # os.get_exec_path() reads the 'PATH' variable
738 with _execvpe_mockup() as calls:
739 env_path = env.copy()
Victor Stinner38430e22010-08-19 17:10:18 +0000740 if test_type is bytes:
741 env_path[b'PATH'] = program_path
742 else:
743 env_path['PATH'] = program_path
Victor Stinnerb745a742010-05-18 17:17:23 +0000744 self.assertRaises(OSError,
745 os._execvpe, program, arguments, env=env_path)
746 self.assertEqual(len(calls), 1)
747 self.assertSequenceEqual(calls[0],
748 ('execve', native_fullpath, (arguments, env_path)))
749
750 def test_internal_execvpe_str(self):
751 self._test_internal_execvpe(str)
752 if os.name != "nt":
753 self._test_internal_execvpe(bytes)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000754
Gregory P. Smith4ae37772010-05-08 18:05:46 +0000755
Thomas Wouters477c8d52006-05-27 19:21:47 +0000756class Win32ErrorTests(unittest.TestCase):
757 def test_rename(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000758 self.assertRaises(WindowsError, os.rename, support.TESTFN, support.TESTFN+".bak")
Thomas Wouters477c8d52006-05-27 19:21:47 +0000759
760 def test_remove(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000761 self.assertRaises(WindowsError, os.remove, support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000762
763 def test_chdir(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000764 self.assertRaises(WindowsError, os.chdir, support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000765
766 def test_mkdir(self):
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000767 f = open(support.TESTFN, "w")
Benjamin Petersonf91df042009-02-13 02:50:59 +0000768 try:
769 self.assertRaises(WindowsError, os.mkdir, support.TESTFN)
770 finally:
771 f.close()
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000772 os.unlink(support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000773
774 def test_utime(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000775 self.assertRaises(WindowsError, os.utime, support.TESTFN, None)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000776
Thomas Wouters477c8d52006-05-27 19:21:47 +0000777 def test_chmod(self):
Benjamin Petersonf91df042009-02-13 02:50:59 +0000778 self.assertRaises(WindowsError, os.chmod, support.TESTFN, 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000779
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000780class TestInvalidFD(unittest.TestCase):
Benjamin Peterson05e782f2009-01-19 15:15:02 +0000781 singles = ["fchdir", "dup", "fdopen", "fdatasync", "fstat",
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000782 "fstatvfs", "fsync", "tcgetpgrp", "ttyname"]
783 #singles.append("close")
784 #We omit close because it doesn'r raise an exception on some platforms
785 def get_single(f):
786 def helper(self):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000787 if hasattr(os, f):
788 self.check(getattr(os, f))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000789 return helper
790 for f in singles:
791 locals()["test_"+f] = get_single(f)
792
Benjamin Peterson7522c742009-01-19 21:00:09 +0000793 def check(self, f, *args):
Benjamin Peterson5c6d7872009-02-06 02:40:07 +0000794 try:
795 f(support.make_bad_fd(), *args)
796 except OSError as e:
797 self.assertEqual(e.errno, errno.EBADF)
798 else:
799 self.fail("%r didn't raise a OSError with a bad file descriptor"
800 % f)
Benjamin Peterson7522c742009-01-19 21:00:09 +0000801
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000802 def test_isatty(self):
803 if hasattr(os, "isatty"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000804 self.assertEqual(os.isatty(support.make_bad_fd()), False)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000805
806 def test_closerange(self):
807 if hasattr(os, "closerange"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000808 fd = support.make_bad_fd()
R. David Murray630cc482009-07-22 15:20:27 +0000809 # Make sure none of the descriptors we are about to close are
810 # currently valid (issue 6542).
811 for i in range(10):
812 try: os.fstat(fd+i)
813 except OSError:
814 pass
815 else:
816 break
817 if i < 2:
818 raise unittest.SkipTest(
819 "Unable to acquire a range of invalid file descriptors")
820 self.assertEqual(os.closerange(fd, fd + i-1), None)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000821
822 def test_dup2(self):
823 if hasattr(os, "dup2"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000824 self.check(os.dup2, 20)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000825
826 def test_fchmod(self):
827 if hasattr(os, "fchmod"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000828 self.check(os.fchmod, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000829
830 def test_fchown(self):
831 if hasattr(os, "fchown"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000832 self.check(os.fchown, -1, -1)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000833
834 def test_fpathconf(self):
835 if hasattr(os, "fpathconf"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000836 self.check(os.fpathconf, "PC_NAME_MAX")
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000837
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000838 def test_ftruncate(self):
839 if hasattr(os, "ftruncate"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000840 self.check(os.ftruncate, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000841
842 def test_lseek(self):
843 if hasattr(os, "lseek"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000844 self.check(os.lseek, 0, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000845
846 def test_read(self):
847 if hasattr(os, "read"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000848 self.check(os.read, 1)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000849
850 def test_tcsetpgrpt(self):
851 if hasattr(os, "tcsetpgrp"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000852 self.check(os.tcsetpgrp, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000853
854 def test_write(self):
855 if hasattr(os, "write"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000856 self.check(os.write, b" ")
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000857
Thomas Wouters477c8d52006-05-27 19:21:47 +0000858if sys.platform != 'win32':
859 class Win32ErrorTests(unittest.TestCase):
860 pass
861
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000862 class PosixUidGidTests(unittest.TestCase):
863 if hasattr(os, 'setuid'):
864 def test_setuid(self):
865 if os.getuid() != 0:
866 self.assertRaises(os.error, os.setuid, 0)
867 self.assertRaises(OverflowError, os.setuid, 1<<32)
868
869 if hasattr(os, 'setgid'):
870 def test_setgid(self):
871 if os.getuid() != 0:
872 self.assertRaises(os.error, os.setgid, 0)
873 self.assertRaises(OverflowError, os.setgid, 1<<32)
874
875 if hasattr(os, 'seteuid'):
876 def test_seteuid(self):
877 if os.getuid() != 0:
878 self.assertRaises(os.error, os.seteuid, 0)
879 self.assertRaises(OverflowError, os.seteuid, 1<<32)
880
881 if hasattr(os, 'setegid'):
882 def test_setegid(self):
883 if os.getuid() != 0:
884 self.assertRaises(os.error, os.setegid, 0)
885 self.assertRaises(OverflowError, os.setegid, 1<<32)
886
887 if hasattr(os, 'setreuid'):
888 def test_setreuid(self):
889 if os.getuid() != 0:
890 self.assertRaises(os.error, os.setreuid, 0, 0)
891 self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
892 self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000893
894 def test_setreuid_neg1(self):
895 # Needs to accept -1. We run this in a subprocess to avoid
896 # altering the test runner's process state (issue8045).
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000897 subprocess.check_call([
898 sys.executable, '-c',
899 'import os,sys;os.setreuid(-1,-1);sys.exit(0)'])
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000900
901 if hasattr(os, 'setregid'):
902 def test_setregid(self):
903 if os.getuid() != 0:
904 self.assertRaises(os.error, os.setregid, 0, 0)
905 self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
906 self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000907
908 def test_setregid_neg1(self):
909 # Needs to accept -1. We run this in a subprocess to avoid
910 # altering the test runner's process state (issue8045).
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000911 subprocess.check_call([
912 sys.executable, '-c',
913 'import os,sys;os.setregid(-1,-1);sys.exit(0)'])
Martin v. Löwis011e8422009-05-05 04:43:17 +0000914
915 class Pep383Tests(unittest.TestCase):
Martin v. Löwis011e8422009-05-05 04:43:17 +0000916 def setUp(self):
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000917 if support.TESTFN_UNENCODABLE:
918 self.dir = support.TESTFN_UNENCODABLE
919 else:
920 self.dir = support.TESTFN
921 self.bdir = os.fsencode(self.dir)
922
923 bytesfn = []
924 def add_filename(fn):
925 try:
926 fn = os.fsencode(fn)
927 except UnicodeEncodeError:
928 return
929 bytesfn.append(fn)
930 add_filename(support.TESTFN_UNICODE)
931 if support.TESTFN_UNENCODABLE:
932 add_filename(support.TESTFN_UNENCODABLE)
933 if not bytesfn:
934 self.skipTest("couldn't create any non-ascii filename")
935
936 self.unicodefn = set()
Martin v. Löwis011e8422009-05-05 04:43:17 +0000937 os.mkdir(self.dir)
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000938 try:
939 for fn in bytesfn:
940 f = open(os.path.join(self.bdir, fn), "w")
941 f.close()
Victor Stinnere8d51452010-08-19 01:05:19 +0000942 fn = os.fsdecode(fn)
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000943 if fn in self.unicodefn:
944 raise ValueError("duplicate filename")
945 self.unicodefn.add(fn)
946 except:
947 shutil.rmtree(self.dir)
948 raise
Martin v. Löwis011e8422009-05-05 04:43:17 +0000949
950 def tearDown(self):
951 shutil.rmtree(self.dir)
Martin v. Löwis011e8422009-05-05 04:43:17 +0000952
953 def test_listdir(self):
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000954 expected = self.unicodefn
955 found = set(os.listdir(self.dir))
Martin v. Löwis011e8422009-05-05 04:43:17 +0000956 self.assertEquals(found, expected)
957
958 def test_open(self):
959 for fn in self.unicodefn:
960 f = open(os.path.join(self.dir, fn))
961 f.close()
962
963 def test_stat(self):
964 for fn in self.unicodefn:
965 os.stat(os.path.join(self.dir, fn))
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000966else:
967 class PosixUidGidTests(unittest.TestCase):
968 pass
Martin v. Löwis011e8422009-05-05 04:43:17 +0000969 class Pep383Tests(unittest.TestCase):
970 pass
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000971
Brian Curtineb24d742010-04-12 17:16:38 +0000972@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
973class Win32KillTests(unittest.TestCase):
Brian Curtinc3acbc32010-05-28 16:08:40 +0000974 def _kill(self, sig):
975 # Start sys.executable as a subprocess and communicate from the
976 # subprocess to the parent that the interpreter is ready. When it
977 # becomes ready, send *sig* via os.kill to the subprocess and check
978 # that the return code is equal to *sig*.
979 import ctypes
980 from ctypes import wintypes
981 import msvcrt
982
983 # Since we can't access the contents of the process' stdout until the
984 # process has exited, use PeekNamedPipe to see what's inside stdout
985 # without waiting. This is done so we can tell that the interpreter
986 # is started and running at a point where it could handle a signal.
987 PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe
988 PeekNamedPipe.restype = wintypes.BOOL
989 PeekNamedPipe.argtypes = (wintypes.HANDLE, # Pipe handle
990 ctypes.POINTER(ctypes.c_char), # stdout buf
991 wintypes.DWORD, # Buffer size
992 ctypes.POINTER(wintypes.DWORD), # bytes read
993 ctypes.POINTER(wintypes.DWORD), # bytes avail
994 ctypes.POINTER(wintypes.DWORD)) # bytes left
995 msg = "running"
996 proc = subprocess.Popen([sys.executable, "-c",
997 "import sys;"
998 "sys.stdout.write('{}');"
999 "sys.stdout.flush();"
1000 "input()".format(msg)],
1001 stdout=subprocess.PIPE,
1002 stderr=subprocess.PIPE,
1003 stdin=subprocess.PIPE)
1004
1005 count, max = 0, 100
1006 while count < max and proc.poll() is None:
1007 # Create a string buffer to store the result of stdout from the pipe
1008 buf = ctypes.create_string_buffer(len(msg))
1009 # Obtain the text currently in proc.stdout
1010 # Bytes read/avail/left are left as NULL and unused
1011 rslt = PeekNamedPipe(msvcrt.get_osfhandle(proc.stdout.fileno()),
1012 buf, ctypes.sizeof(buf), None, None, None)
1013 self.assertNotEqual(rslt, 0, "PeekNamedPipe failed")
1014 if buf.value:
1015 self.assertEqual(msg, buf.value.decode())
1016 break
1017 time.sleep(0.1)
1018 count += 1
1019 else:
1020 self.fail("Did not receive communication from the subprocess")
1021
Brian Curtineb24d742010-04-12 17:16:38 +00001022 os.kill(proc.pid, sig)
1023 self.assertEqual(proc.wait(), sig)
1024
1025 def test_kill_sigterm(self):
1026 # SIGTERM doesn't mean anything special, but make sure it works
Brian Curtinc3acbc32010-05-28 16:08:40 +00001027 self._kill(signal.SIGTERM)
Brian Curtineb24d742010-04-12 17:16:38 +00001028
1029 def test_kill_int(self):
1030 # os.kill on Windows can take an int which gets set as the exit code
Brian Curtinc3acbc32010-05-28 16:08:40 +00001031 self._kill(100)
Brian Curtineb24d742010-04-12 17:16:38 +00001032
1033 def _kill_with_event(self, event, name):
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001034 tagname = "test_os_%s" % uuid.uuid1()
1035 m = mmap.mmap(-1, 1, tagname)
1036 m[0] = 0
Brian Curtineb24d742010-04-12 17:16:38 +00001037 # Run a script which has console control handling enabled.
1038 proc = subprocess.Popen([sys.executable,
1039 os.path.join(os.path.dirname(__file__),
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001040 "win_console_handler.py"), tagname],
Brian Curtineb24d742010-04-12 17:16:38 +00001041 creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
1042 # Let the interpreter startup before we send signals. See #3137.
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001043 count, max = 0, 20
1044 while count < max and proc.poll() is None:
Brian Curtinf668df52010-10-15 14:21:06 +00001045 if m[0] == 1:
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001046 break
1047 time.sleep(0.5)
1048 count += 1
1049 else:
1050 self.fail("Subprocess didn't finish initialization")
Brian Curtineb24d742010-04-12 17:16:38 +00001051 os.kill(proc.pid, event)
1052 # proc.send_signal(event) could also be done here.
1053 # Allow time for the signal to be passed and the process to exit.
1054 time.sleep(0.5)
1055 if not proc.poll():
1056 # Forcefully kill the process if we weren't able to signal it.
1057 os.kill(proc.pid, signal.SIGINT)
1058 self.fail("subprocess did not stop on {}".format(name))
1059
1060 @unittest.skip("subprocesses aren't inheriting CTRL+C property")
1061 def test_CTRL_C_EVENT(self):
1062 from ctypes import wintypes
1063 import ctypes
1064
1065 # Make a NULL value by creating a pointer with no argument.
1066 NULL = ctypes.POINTER(ctypes.c_int)()
1067 SetConsoleCtrlHandler = ctypes.windll.kernel32.SetConsoleCtrlHandler
1068 SetConsoleCtrlHandler.argtypes = (ctypes.POINTER(ctypes.c_int),
1069 wintypes.BOOL)
1070 SetConsoleCtrlHandler.restype = wintypes.BOOL
1071
1072 # Calling this with NULL and FALSE causes the calling process to
1073 # handle CTRL+C, rather than ignore it. This property is inherited
1074 # by subprocesses.
1075 SetConsoleCtrlHandler(NULL, 0)
1076
1077 self._kill_with_event(signal.CTRL_C_EVENT, "CTRL_C_EVENT")
1078
1079 def test_CTRL_BREAK_EVENT(self):
1080 self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT")
1081
1082
Brian Curtind40e6f72010-07-08 21:39:08 +00001083def skipUnlessWindows6(test):
Brian Curtin74e45612010-07-09 15:58:59 +00001084 if (hasattr(sys, 'getwindowsversion')
1085 and sys.getwindowsversion().major >= 6):
Brian Curtind40e6f72010-07-08 21:39:08 +00001086 return test
1087 return unittest.skip("Requires Windows Vista or later")(test)
1088
1089@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
1090@support.skip_unless_symlink
1091class Win32SymlinkTests(unittest.TestCase):
1092 filelink = 'filelinktest'
1093 filelink_target = os.path.abspath(__file__)
1094 dirlink = 'dirlinktest'
1095 dirlink_target = os.path.dirname(filelink_target)
1096 missing_link = 'missing link'
1097
1098 def setUp(self):
1099 assert os.path.exists(self.dirlink_target)
1100 assert os.path.exists(self.filelink_target)
1101 assert not os.path.exists(self.dirlink)
1102 assert not os.path.exists(self.filelink)
1103 assert not os.path.exists(self.missing_link)
1104
1105 def tearDown(self):
1106 if os.path.exists(self.filelink):
1107 os.remove(self.filelink)
1108 if os.path.exists(self.dirlink):
1109 os.rmdir(self.dirlink)
1110 if os.path.lexists(self.missing_link):
1111 os.remove(self.missing_link)
1112
1113 def test_directory_link(self):
1114 os.symlink(self.dirlink_target, self.dirlink)
1115 self.assertTrue(os.path.exists(self.dirlink))
1116 self.assertTrue(os.path.isdir(self.dirlink))
1117 self.assertTrue(os.path.islink(self.dirlink))
1118 self.check_stat(self.dirlink, self.dirlink_target)
1119
1120 def test_file_link(self):
1121 os.symlink(self.filelink_target, self.filelink)
1122 self.assertTrue(os.path.exists(self.filelink))
1123 self.assertTrue(os.path.isfile(self.filelink))
1124 self.assertTrue(os.path.islink(self.filelink))
1125 self.check_stat(self.filelink, self.filelink_target)
1126
1127 def _create_missing_dir_link(self):
1128 'Create a "directory" link to a non-existent target'
1129 linkname = self.missing_link
1130 if os.path.lexists(linkname):
1131 os.remove(linkname)
1132 target = r'c:\\target does not exist.29r3c740'
1133 assert not os.path.exists(target)
1134 target_is_dir = True
1135 os.symlink(target, linkname, target_is_dir)
1136
1137 def test_remove_directory_link_to_missing_target(self):
1138 self._create_missing_dir_link()
1139 # For compatibility with Unix, os.remove will check the
1140 # directory status and call RemoveDirectory if the symlink
1141 # was created with target_is_dir==True.
1142 os.remove(self.missing_link)
1143
1144 @unittest.skip("currently fails; consider for improvement")
1145 def test_isdir_on_directory_link_to_missing_target(self):
1146 self._create_missing_dir_link()
1147 # consider having isdir return true for directory links
1148 self.assertTrue(os.path.isdir(self.missing_link))
1149
1150 @unittest.skip("currently fails; consider for improvement")
1151 def test_rmdir_on_directory_link_to_missing_target(self):
1152 self._create_missing_dir_link()
1153 # consider allowing rmdir to remove directory links
1154 os.rmdir(self.missing_link)
1155
1156 def check_stat(self, link, target):
1157 self.assertEqual(os.stat(link), os.stat(target))
1158 self.assertNotEqual(os.lstat(link), os.stat(link))
1159
1160
Victor Stinnere8d51452010-08-19 01:05:19 +00001161class FSEncodingTests(unittest.TestCase):
1162 def test_nop(self):
1163 self.assertEquals(os.fsencode(b'abc\xff'), b'abc\xff')
1164 self.assertEquals(os.fsdecode('abc\u0141'), 'abc\u0141')
Benjamin Peterson31191a92010-05-09 03:22:58 +00001165
Victor Stinnere8d51452010-08-19 01:05:19 +00001166 def test_identity(self):
1167 # assert fsdecode(fsencode(x)) == x
1168 for fn in ('unicode\u0141', 'latin\xe9', 'ascii'):
1169 try:
1170 bytesfn = os.fsencode(fn)
1171 except UnicodeEncodeError:
1172 continue
1173 self.assertEquals(os.fsdecode(bytesfn), fn)
1174
Victor Stinnerbf9bcab2010-05-09 03:15:33 +00001175
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00001176class PidTests(unittest.TestCase):
1177 @unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid")
1178 def test_getppid(self):
1179 p = subprocess.Popen([sys.executable, '-c',
1180 'import os; print(os.getppid())'],
1181 stdout=subprocess.PIPE)
1182 stdout, _ = p.communicate()
1183 # We are the parent of our subprocess
1184 self.assertEqual(int(stdout), os.getpid())
1185
1186
Brian Curtin0151b8e2010-09-24 13:43:43 +00001187# The introduction of this TestCase caused at least two different errors on
1188# *nix buildbots. Temporarily skip this to let the buildbots move along.
1189@unittest.skip("Skip due to platform/environment differences on *NIX buildbots")
Brian Curtine8e4b3b2010-09-23 20:04:14 +00001190@unittest.skipUnless(hasattr(os, 'getlogin'), "test needs os.getlogin")
1191class LoginTests(unittest.TestCase):
1192 def test_getlogin(self):
1193 user_name = os.getlogin()
1194 self.assertNotEqual(len(user_name), 0)
1195
1196
Fred Drake2e2be372001-09-20 21:33:42 +00001197def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001198 support.run_unittest(
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001199 FileTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001200 StatAttributeTests,
1201 EnvironTests,
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001202 WalkTests,
1203 MakedirTests,
Martin v. Löwisbdec50f2004-06-08 08:29:33 +00001204 DevNullTests,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001205 URandomTests,
Guido van Rossume7ba4952007-06-06 23:52:48 +00001206 ExecTests,
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001207 Win32ErrorTests,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001208 TestInvalidFD,
Martin v. Löwis011e8422009-05-05 04:43:17 +00001209 PosixUidGidTests,
Brian Curtineb24d742010-04-12 17:16:38 +00001210 Pep383Tests,
Victor Stinnerbf9bcab2010-05-09 03:15:33 +00001211 Win32KillTests,
Brian Curtind40e6f72010-07-08 21:39:08 +00001212 Win32SymlinkTests,
Victor Stinnere8d51452010-08-19 01:05:19 +00001213 FSEncodingTests,
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00001214 PidTests,
Brian Curtine8e4b3b2010-09-23 20:04:14 +00001215 LoginTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001216 )
Fred Drake2e2be372001-09-20 21:33:42 +00001217
1218if __name__ == "__main__":
1219 test_main()