blob: efa28ea952b1c6aefdb91dde6fdca91c592c9226 [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
Victor Stinnere0daff12011-03-20 23:36:35 +010093 def write_windows_console(self, *args):
94 retcode = subprocess.call(args,
95 # use a new console to not flood the test output
96 creationflags=subprocess.CREATE_NEW_CONSOLE,
97 # use a shell to hide the console window (SW_HIDE)
98 shell=True)
99 self.assertEqual(retcode, 0)
100
101 @unittest.skipUnless(sys.platform == 'win32',
102 'test specific to the Windows console')
103 def test_write_windows_console(self):
104 # Issue #11395: the Windows console returns an error (12: not enough
105 # space error) on writing into stdout if stdout mode is binary and the
106 # length is greater than 66,000 bytes (or less, depending on heap
107 # usage).
108 code = "print('x' * 100000)"
109 self.write_windows_console(sys.executable, "-c", code)
110 self.write_windows_console(sys.executable, "-u", "-c", code)
111
Amaury Forgeot d'Arce2e36ba2008-08-01 00:14:22 +0000112 def fdopen_helper(self, *args):
113 fd = os.open(support.TESTFN, os.O_RDONLY)
Victor Stinnerbef7fdf2011-07-01 13:45:30 +0200114 f = os.fdopen(fd, *args)
115 f.close()
Amaury Forgeot d'Arce2e36ba2008-08-01 00:14:22 +0000116
117 def test_fdopen(self):
Victor Stinnerbef7fdf2011-07-01 13:45:30 +0200118 fd = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR)
119 os.close(fd)
120
Amaury Forgeot d'Arce2e36ba2008-08-01 00:14:22 +0000121 self.fdopen_helper()
122 self.fdopen_helper('r')
123 self.fdopen_helper('r', 100)
124
Victor Stinnerbef7fdf2011-07-01 13:45:30 +0200125
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000126# Test attributes on return values from os.*stat* family.
127class StatAttributeTests(unittest.TestCase):
128 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000129 os.mkdir(support.TESTFN)
130 self.fname = os.path.join(support.TESTFN, "f1")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000131 f = open(self.fname, 'wb')
Guido van Rossum26d95c32007-08-27 23:18:54 +0000132 f.write(b"ABC")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000133 f.close()
Tim Peterse0c446b2001-10-18 21:57:37 +0000134
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000135 def tearDown(self):
136 os.unlink(self.fname)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000137 os.rmdir(support.TESTFN)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000138
Antoine Pitrou38425292010-09-21 18:19:07 +0000139 def check_stat_attributes(self, fname):
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000140 if not hasattr(os, "stat"):
141 return
142
143 import stat
Antoine Pitrou38425292010-09-21 18:19:07 +0000144 result = os.stat(fname)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000145
146 # Make sure direct access works
Ezio Melottib3aedd42010-11-20 19:04:17 +0000147 self.assertEqual(result[stat.ST_SIZE], 3)
148 self.assertEqual(result.st_size, 3)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000149
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000150 # Make sure all the attributes are there
151 members = dir(result)
152 for name in dir(stat):
153 if name[:3] == 'ST_':
154 attr = name.lower()
Martin v. Löwis4d394df2005-01-23 09:19:22 +0000155 if name.endswith("TIME"):
156 def trunc(x): return int(x)
157 else:
158 def trunc(x): return x
Ezio Melottib3aedd42010-11-20 19:04:17 +0000159 self.assertEqual(trunc(getattr(result, attr)),
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000160 result[getattr(stat, name)])
Benjamin Peterson577473f2010-01-19 00:09:57 +0000161 self.assertIn(attr, members)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000162
163 try:
164 result[200]
165 self.fail("No exception thrown")
166 except IndexError:
167 pass
168
169 # Make sure that assignment fails
170 try:
171 result.st_mode = 1
172 self.fail("No exception thrown")
Collin Winter42dae6a2007-03-28 21:44:53 +0000173 except AttributeError:
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000174 pass
175
176 try:
177 result.st_rdev = 1
178 self.fail("No exception thrown")
Guido van Rossum1fff8782001-10-18 21:19:31 +0000179 except (AttributeError, TypeError):
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000180 pass
181
182 try:
183 result.parrot = 1
184 self.fail("No exception thrown")
185 except AttributeError:
186 pass
187
188 # Use the stat_result constructor with a too-short tuple.
189 try:
190 result2 = os.stat_result((10,))
191 self.fail("No exception thrown")
192 except TypeError:
193 pass
194
Ezio Melotti42da6632011-03-15 05:18:48 +0200195 # Use the constructor with a too-long tuple.
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000196 try:
197 result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
198 except TypeError:
199 pass
200
Antoine Pitrou38425292010-09-21 18:19:07 +0000201 def test_stat_attributes(self):
202 self.check_stat_attributes(self.fname)
203
204 def test_stat_attributes_bytes(self):
205 try:
206 fname = self.fname.encode(sys.getfilesystemencoding())
207 except UnicodeEncodeError:
208 self.skipTest("cannot encode %a for the filesystem" % self.fname)
209 self.check_stat_attributes(fname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000210
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000211 def test_statvfs_attributes(self):
212 if not hasattr(os, "statvfs"):
213 return
214
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000215 try:
216 result = os.statvfs(self.fname)
Guido van Rossumb940e112007-01-10 16:19:56 +0000217 except OSError as e:
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000218 # On AtheOS, glibc always returns ENOSYS
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000219 if e.errno == errno.ENOSYS:
220 return
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000221
222 # Make sure direct access works
Ezio Melottib3aedd42010-11-20 19:04:17 +0000223 self.assertEqual(result.f_bfree, result[3])
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000224
Brett Cannoncfaf10c2008-05-16 00:45:35 +0000225 # Make sure all the attributes are there.
226 members = ('bsize', 'frsize', 'blocks', 'bfree', 'bavail', 'files',
227 'ffree', 'favail', 'flag', 'namemax')
228 for value, member in enumerate(members):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000229 self.assertEqual(getattr(result, 'f_' + member), result[value])
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000230
231 # Make sure that assignment really fails
232 try:
233 result.f_bfree = 1
234 self.fail("No exception thrown")
Collin Winter42dae6a2007-03-28 21:44:53 +0000235 except AttributeError:
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000236 pass
237
238 try:
239 result.parrot = 1
240 self.fail("No exception thrown")
241 except AttributeError:
242 pass
243
244 # Use the constructor with a too-short tuple.
245 try:
246 result2 = os.statvfs_result((10,))
247 self.fail("No exception thrown")
248 except TypeError:
249 pass
250
Ezio Melotti42da6632011-03-15 05:18:48 +0200251 # Use the constructor with a too-long tuple.
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000252 try:
253 result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
254 except TypeError:
255 pass
Fred Drake38c2ef02001-07-17 20:52:51 +0000256
Thomas Wouters89f507f2006-12-13 04:49:30 +0000257 def test_utime_dir(self):
258 delta = 1000000
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000259 st = os.stat(support.TESTFN)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000260 # round to int, because some systems may support sub-second
261 # time stamps in stat, but not in utime.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000262 os.utime(support.TESTFN, (st.st_atime, int(st.st_mtime-delta)))
263 st2 = os.stat(support.TESTFN)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000264 self.assertEqual(st2.st_mtime, int(st.st_mtime-delta))
Thomas Wouters89f507f2006-12-13 04:49:30 +0000265
266 # Restrict test to Win32, since there is no guarantee other
267 # systems support centiseconds
268 if sys.platform == 'win32':
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000269 def get_file_system(path):
Hirokazu Yamamoto5ef6d182008-08-20 04:17:24 +0000270 root = os.path.splitdrive(os.path.abspath(path))[0] + '\\'
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000271 import ctypes
Hirokazu Yamamotoca765d52008-08-20 16:18:19 +0000272 kernel32 = ctypes.windll.kernel32
Hirokazu Yamamoto5ef6d182008-08-20 04:17:24 +0000273 buf = ctypes.create_unicode_buffer("", 100)
Hirokazu Yamamotoca765d52008-08-20 16:18:19 +0000274 if kernel32.GetVolumeInformationW(root, None, 0, None, None, None, buf, len(buf)):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000275 return buf.value
276
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000277 if get_file_system(support.TESTFN) == "NTFS":
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000278 def test_1565150(self):
279 t1 = 1159195039.25
280 os.utime(self.fname, (t1, t1))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000281 self.assertEqual(os.stat(self.fname).st_mtime, t1)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000282
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000283 def test_large_time(self):
284 t1 = 5000000000 # some day in 2128
285 os.utime(self.fname, (t1, t1))
286 self.assertEqual(os.stat(self.fname).st_mtime, t1)
287
Guido van Rossumd8faa362007-04-27 19:54:29 +0000288 def test_1686475(self):
289 # Verify that an open file can be stat'ed
290 try:
291 os.stat(r"c:\pagefile.sys")
292 except WindowsError as e:
Benjamin Petersonc4fe6f32008-08-19 18:57:56 +0000293 if e.errno == 2: # file does not exist; cannot run test
Guido van Rossumd8faa362007-04-27 19:54:29 +0000294 return
295 self.fail("Could not stat pagefile.sys")
296
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000297from test import mapping_tests
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000298
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000299class EnvironTests(mapping_tests.BasicTestMappingProtocol):
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000300 """check that os.environ object conform to mapping protocol"""
Walter Dörwald118f9312004-06-02 18:42:25 +0000301 type2test = None
Christian Heimes90333392007-11-01 19:08:42 +0000302
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000303 def setUp(self):
304 self.__save = dict(os.environ)
Victor Stinnerb745a742010-05-18 17:17:23 +0000305 if os.supports_bytes_environ:
Victor Stinner208d28c2010-05-07 00:54:14 +0000306 self.__saveb = dict(os.environb)
Christian Heimes90333392007-11-01 19:08:42 +0000307 for key, value in self._reference().items():
308 os.environ[key] = value
309
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000310 def tearDown(self):
311 os.environ.clear()
312 os.environ.update(self.__save)
Victor Stinnerb745a742010-05-18 17:17:23 +0000313 if os.supports_bytes_environ:
Victor Stinner208d28c2010-05-07 00:54:14 +0000314 os.environb.clear()
315 os.environb.update(self.__saveb)
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000316
Christian Heimes90333392007-11-01 19:08:42 +0000317 def _reference(self):
318 return {"KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3"}
319
320 def _empty_mapping(self):
321 os.environ.clear()
322 return os.environ
323
Martin v. Löwis1d11de62005-01-29 13:29:23 +0000324 # Bug 1110478
Martin v. Löwis5510f652005-02-17 21:23:20 +0000325 def test_update2(self):
Christian Heimes90333392007-11-01 19:08:42 +0000326 os.environ.clear()
Martin v. Löwis1d11de62005-01-29 13:29:23 +0000327 if os.path.exists("/bin/sh"):
328 os.environ.update(HELLO="World")
Brian Curtin810921b2010-10-30 21:24:21 +0000329 with os.popen("/bin/sh -c 'echo $HELLO'") as popen:
330 value = popen.read().strip()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000331 self.assertEqual(value, "World")
Martin v. Löwis1d11de62005-01-29 13:29:23 +0000332
Christian Heimes1a13d592007-11-08 14:16:55 +0000333 def test_os_popen_iter(self):
334 if os.path.exists("/bin/sh"):
Brian Curtin810921b2010-10-30 21:24:21 +0000335 with os.popen(
336 "/bin/sh -c 'echo \"line1\nline2\nline3\"'") as popen:
337 it = iter(popen)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000338 self.assertEqual(next(it), "line1\n")
339 self.assertEqual(next(it), "line2\n")
340 self.assertEqual(next(it), "line3\n")
Brian Curtin810921b2010-10-30 21:24:21 +0000341 self.assertRaises(StopIteration, next, it)
Christian Heimes1a13d592007-11-08 14:16:55 +0000342
Guido van Rossum67aca9e2007-06-13 21:51:27 +0000343 # Verify environ keys and values from the OS are of the
344 # correct str type.
345 def test_keyvalue_types(self):
346 for key, val in os.environ.items():
Ezio Melottib3aedd42010-11-20 19:04:17 +0000347 self.assertEqual(type(key), str)
348 self.assertEqual(type(val), str)
Guido van Rossum67aca9e2007-06-13 21:51:27 +0000349
Christian Heimes90333392007-11-01 19:08:42 +0000350 def test_items(self):
351 for key, value in self._reference().items():
352 self.assertEqual(os.environ.get(key), value)
353
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000354 # Issue 7310
355 def test___repr__(self):
356 """Check that the repr() of os.environ looks like environ({...})."""
357 env = os.environ
Victor Stinner96f0de92010-07-29 00:29:00 +0000358 self.assertEqual(repr(env), 'environ({{{}}})'.format(', '.join(
359 '{!r}: {!r}'.format(key, value)
360 for key, value in env.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000361
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000362 def test_get_exec_path(self):
363 defpath_list = os.defpath.split(os.pathsep)
364 test_path = ['/monty', '/python', '', '/flying/circus']
365 test_env = {'PATH': os.pathsep.join(test_path)}
366
367 saved_environ = os.environ
368 try:
369 os.environ = dict(test_env)
370 # Test that defaulting to os.environ works.
371 self.assertSequenceEqual(test_path, os.get_exec_path())
372 self.assertSequenceEqual(test_path, os.get_exec_path(env=None))
373 finally:
374 os.environ = saved_environ
375
376 # No PATH environment variable
377 self.assertSequenceEqual(defpath_list, os.get_exec_path({}))
378 # Empty PATH environment variable
379 self.assertSequenceEqual(('',), os.get_exec_path({'PATH':''}))
380 # Supplied PATH environment variable
381 self.assertSequenceEqual(test_path, os.get_exec_path(test_env))
382
Victor Stinnerb745a742010-05-18 17:17:23 +0000383 if os.supports_bytes_environ:
384 # env cannot contain 'PATH' and b'PATH' keys
Victor Stinner38430e22010-08-19 17:10:18 +0000385 try:
Victor Stinner6f35eda2010-10-29 00:38:58 +0000386 # ignore BytesWarning warning
387 with warnings.catch_warnings(record=True):
388 mixed_env = {'PATH': '1', b'PATH': b'2'}
Victor Stinner38430e22010-08-19 17:10:18 +0000389 except BytesWarning:
Victor Stinner6f35eda2010-10-29 00:38:58 +0000390 # mixed_env cannot be created with python -bb
Victor Stinner38430e22010-08-19 17:10:18 +0000391 pass
392 else:
393 self.assertRaises(ValueError, os.get_exec_path, mixed_env)
Victor Stinnerb745a742010-05-18 17:17:23 +0000394
395 # bytes key and/or value
396 self.assertSequenceEqual(os.get_exec_path({b'PATH': b'abc'}),
397 ['abc'])
398 self.assertSequenceEqual(os.get_exec_path({b'PATH': 'abc'}),
399 ['abc'])
400 self.assertSequenceEqual(os.get_exec_path({'PATH': b'abc'}),
401 ['abc'])
402
403 @unittest.skipUnless(os.supports_bytes_environ,
404 "os.environb required for this test.")
Victor Stinner84ae1182010-05-06 22:05:07 +0000405 def test_environb(self):
406 # os.environ -> os.environb
407 value = 'euro\u20ac'
408 try:
Benjamin Peterson180799d2010-05-06 22:25:42 +0000409 value_bytes = value.encode(sys.getfilesystemencoding(),
410 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000411 except UnicodeEncodeError:
Benjamin Peterson180799d2010-05-06 22:25:42 +0000412 msg = "U+20AC character is not encodable to %s" % (
413 sys.getfilesystemencoding(),)
Benjamin Peterson932d3f42010-05-06 22:26:31 +0000414 self.skipTest(msg)
Victor Stinner84ae1182010-05-06 22:05:07 +0000415 os.environ['unicode'] = value
Ezio Melottib3aedd42010-11-20 19:04:17 +0000416 self.assertEqual(os.environ['unicode'], value)
417 self.assertEqual(os.environb[b'unicode'], value_bytes)
Victor Stinner84ae1182010-05-06 22:05:07 +0000418
419 # os.environb -> os.environ
420 value = b'\xff'
421 os.environb[b'bytes'] = value
Ezio Melottib3aedd42010-11-20 19:04:17 +0000422 self.assertEqual(os.environb[b'bytes'], value)
Victor Stinner84ae1182010-05-06 22:05:07 +0000423 value_str = value.decode(sys.getfilesystemencoding(), 'surrogateescape')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000424 self.assertEqual(os.environ['bytes'], value_str)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000425
Tim Petersc4e09402003-04-25 07:11:48 +0000426class WalkTests(unittest.TestCase):
427 """Tests for os.walk()."""
428
429 def test_traversal(self):
430 import os
431 from os.path import join
432
433 # Build:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000434 # TESTFN/
435 # TEST1/ a file kid and two directory kids
Tim Petersc4e09402003-04-25 07:11:48 +0000436 # tmp1
437 # SUB1/ a file kid and a directory kid
Guido van Rossumd8faa362007-04-27 19:54:29 +0000438 # tmp2
439 # SUB11/ no kids
440 # SUB2/ a file kid and a dirsymlink kid
441 # tmp3
442 # link/ a symlink to TESTFN.2
443 # TEST2/
444 # tmp4 a lone file
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000445 walk_path = join(support.TESTFN, "TEST1")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000446 sub1_path = join(walk_path, "SUB1")
Tim Petersc4e09402003-04-25 07:11:48 +0000447 sub11_path = join(sub1_path, "SUB11")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000448 sub2_path = join(walk_path, "SUB2")
449 tmp1_path = join(walk_path, "tmp1")
Tim Petersc4e09402003-04-25 07:11:48 +0000450 tmp2_path = join(sub1_path, "tmp2")
451 tmp3_path = join(sub2_path, "tmp3")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000452 link_path = join(sub2_path, "link")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000453 t2_path = join(support.TESTFN, "TEST2")
454 tmp4_path = join(support.TESTFN, "TEST2", "tmp4")
Tim Petersc4e09402003-04-25 07:11:48 +0000455
456 # Create stuff.
457 os.makedirs(sub11_path)
458 os.makedirs(sub2_path)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000459 os.makedirs(t2_path)
460 for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path:
Alex Martelli01c77c62006-08-24 02:58:11 +0000461 f = open(path, "w")
Tim Petersc4e09402003-04-25 07:11:48 +0000462 f.write("I'm " + path + " and proud of it. Blame test_os.\n")
463 f.close()
Brian Curtin3b4499c2010-12-28 14:31:47 +0000464 if support.can_symlink():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000465 os.symlink(os.path.abspath(t2_path), link_path)
466 sub2_tree = (sub2_path, ["link"], ["tmp3"])
467 else:
468 sub2_tree = (sub2_path, [], ["tmp3"])
Tim Petersc4e09402003-04-25 07:11:48 +0000469
470 # Walk top-down.
Guido van Rossumd8faa362007-04-27 19:54:29 +0000471 all = list(os.walk(walk_path))
Tim Petersc4e09402003-04-25 07:11:48 +0000472 self.assertEqual(len(all), 4)
473 # We can't know which order SUB1 and SUB2 will appear in.
474 # Not flipped: TESTFN, SUB1, SUB11, SUB2
475 # flipped: TESTFN, SUB2, SUB1, SUB11
476 flipped = all[0][1][0] != "SUB1"
477 all[0][1].sort()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000478 self.assertEqual(all[0], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
Tim Petersc4e09402003-04-25 07:11:48 +0000479 self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"]))
480 self.assertEqual(all[2 + flipped], (sub11_path, [], []))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000481 self.assertEqual(all[3 - 2 * flipped], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000482
483 # Prune the search.
484 all = []
Guido van Rossumd8faa362007-04-27 19:54:29 +0000485 for root, dirs, files in os.walk(walk_path):
Tim Petersc4e09402003-04-25 07:11:48 +0000486 all.append((root, dirs, files))
487 # Don't descend into SUB1.
488 if 'SUB1' in dirs:
489 # Note that this also mutates the dirs we appended to all!
490 dirs.remove('SUB1')
491 self.assertEqual(len(all), 2)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000492 self.assertEqual(all[0], (walk_path, ["SUB2"], ["tmp1"]))
493 self.assertEqual(all[1], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000494
495 # Walk bottom-up.
Guido van Rossumd8faa362007-04-27 19:54:29 +0000496 all = list(os.walk(walk_path, topdown=False))
Tim Petersc4e09402003-04-25 07:11:48 +0000497 self.assertEqual(len(all), 4)
498 # We can't know which order SUB1 and SUB2 will appear in.
499 # Not flipped: SUB11, SUB1, SUB2, TESTFN
500 # flipped: SUB2, SUB11, SUB1, TESTFN
501 flipped = all[3][1][0] != "SUB1"
502 all[3][1].sort()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000503 self.assertEqual(all[3], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
Tim Petersc4e09402003-04-25 07:11:48 +0000504 self.assertEqual(all[flipped], (sub11_path, [], []))
505 self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"]))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000506 self.assertEqual(all[2 - 2 * flipped], sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000507
Brian Curtin3b4499c2010-12-28 14:31:47 +0000508 if support.can_symlink():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000509 # Walk, following symlinks.
510 for root, dirs, files in os.walk(walk_path, followlinks=True):
511 if root == link_path:
512 self.assertEqual(dirs, [])
513 self.assertEqual(files, ["tmp4"])
514 break
515 else:
516 self.fail("Didn't follow symlink with followlinks=True")
517
518 def tearDown(self):
Tim Petersc4e09402003-04-25 07:11:48 +0000519 # Tear everything down. This is a decent use for bottom-up on
520 # Windows, which doesn't have a recursive delete command. The
521 # (not so) subtlety is that rmdir will fail unless the dir's
522 # kids are removed first, so bottom up is essential.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000523 for root, dirs, files in os.walk(support.TESTFN, topdown=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000524 for name in files:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000525 os.remove(os.path.join(root, name))
Tim Petersc4e09402003-04-25 07:11:48 +0000526 for name in dirs:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000527 dirname = os.path.join(root, name)
528 if not os.path.islink(dirname):
529 os.rmdir(dirname)
530 else:
531 os.remove(dirname)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000532 os.rmdir(support.TESTFN)
Tim Petersc4e09402003-04-25 07:11:48 +0000533
Guido van Rossume7ba4952007-06-06 23:52:48 +0000534class MakedirTests(unittest.TestCase):
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000535 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000536 os.mkdir(support.TESTFN)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000537
538 def test_makedir(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000539 base = support.TESTFN
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000540 path = os.path.join(base, 'dir1', 'dir2', 'dir3')
541 os.makedirs(path) # Should work
542 path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4')
543 os.makedirs(path)
544
545 # Try paths with a '.' in them
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000546 self.assertRaises(OSError, os.makedirs, os.curdir)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000547 path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir)
548 os.makedirs(path)
549 path = os.path.join(base, 'dir1', os.curdir, 'dir2', 'dir3', 'dir4',
550 'dir5', 'dir6')
551 os.makedirs(path)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000552
Terry Reedy5a22b652010-12-02 07:05:56 +0000553 def test_exist_ok_existing_directory(self):
554 path = os.path.join(support.TESTFN, 'dir1')
555 mode = 0o777
556 old_mask = os.umask(0o022)
557 os.makedirs(path, mode)
558 self.assertRaises(OSError, os.makedirs, path, mode)
559 self.assertRaises(OSError, os.makedirs, path, mode, exist_ok=False)
560 self.assertRaises(OSError, os.makedirs, path, 0o776, exist_ok=True)
561 os.makedirs(path, mode=mode, exist_ok=True)
562 os.umask(old_mask)
563
564 def test_exist_ok_existing_regular_file(self):
565 base = support.TESTFN
566 path = os.path.join(support.TESTFN, 'dir1')
567 f = open(path, 'w')
568 f.write('abc')
569 f.close()
570 self.assertRaises(OSError, os.makedirs, path)
571 self.assertRaises(OSError, os.makedirs, path, exist_ok=False)
572 self.assertRaises(OSError, os.makedirs, path, exist_ok=True)
573 os.remove(path)
574
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000575 def tearDown(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000576 path = os.path.join(support.TESTFN, 'dir1', 'dir2', 'dir3',
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000577 'dir4', 'dir5', 'dir6')
578 # If the tests failed, the bottom-most directory ('../dir6')
579 # may not have been created, so we look for the outermost directory
580 # that exists.
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000581 while not os.path.exists(path) and path != support.TESTFN:
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000582 path = os.path.dirname(path)
583
584 os.removedirs(path)
585
Guido van Rossume7ba4952007-06-06 23:52:48 +0000586class DevNullTests(unittest.TestCase):
Martin v. Löwisbdec50f2004-06-08 08:29:33 +0000587 def test_devnull(self):
Victor Stinnera6d2c762011-06-30 18:20:11 +0200588 with open(os.devnull, 'wb') as f:
589 f.write(b'hello')
590 f.close()
591 with open(os.devnull, 'rb') as f:
592 self.assertEqual(f.read(), b'')
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +0000593
Guido van Rossume7ba4952007-06-06 23:52:48 +0000594class URandomTests(unittest.TestCase):
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000595 def test_urandom(self):
596 try:
597 self.assertEqual(len(os.urandom(1)), 1)
598 self.assertEqual(len(os.urandom(10)), 10)
599 self.assertEqual(len(os.urandom(100)), 100)
600 self.assertEqual(len(os.urandom(1000)), 1000)
601 except NotImplementedError:
602 pass
603
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000604@contextlib.contextmanager
605def _execvpe_mockup(defpath=None):
606 """
607 Stubs out execv and execve functions when used as context manager.
608 Records exec calls. The mock execv and execve functions always raise an
609 exception as they would normally never return.
610 """
611 # A list of tuples containing (function name, first arg, args)
612 # of calls to execv or execve that have been made.
613 calls = []
614
615 def mock_execv(name, *args):
616 calls.append(('execv', name, args))
617 raise RuntimeError("execv called")
618
619 def mock_execve(name, *args):
620 calls.append(('execve', name, args))
621 raise OSError(errno.ENOTDIR, "execve called")
622
623 try:
624 orig_execv = os.execv
625 orig_execve = os.execve
626 orig_defpath = os.defpath
627 os.execv = mock_execv
628 os.execve = mock_execve
629 if defpath is not None:
630 os.defpath = defpath
631 yield calls
632 finally:
633 os.execv = orig_execv
634 os.execve = orig_execve
635 os.defpath = orig_defpath
636
Guido van Rossume7ba4952007-06-06 23:52:48 +0000637class ExecTests(unittest.TestCase):
Mark Dickinson7cf03892010-04-16 13:45:35 +0000638 @unittest.skipIf(USING_LINUXTHREADS,
639 "avoid triggering a linuxthreads bug: see issue #4970")
Guido van Rossume7ba4952007-06-06 23:52:48 +0000640 def test_execvpe_with_bad_program(self):
Mark Dickinson7cf03892010-04-16 13:45:35 +0000641 self.assertRaises(OSError, os.execvpe, 'no such app-',
642 ['no such app-'], None)
Guido van Rossume7ba4952007-06-06 23:52:48 +0000643
Thomas Heller6790d602007-08-30 17:15:14 +0000644 def test_execvpe_with_bad_arglist(self):
645 self.assertRaises(ValueError, os.execvpe, 'notepad', [], None)
646
Gregory P. Smith4ae37772010-05-08 18:05:46 +0000647 @unittest.skipUnless(hasattr(os, '_execvpe'),
648 "No internal os._execvpe function to test.")
Victor Stinnerb745a742010-05-18 17:17:23 +0000649 def _test_internal_execvpe(self, test_type):
650 program_path = os.sep + 'absolutepath'
651 if test_type is bytes:
652 program = b'executable'
653 fullpath = os.path.join(os.fsencode(program_path), program)
654 native_fullpath = fullpath
655 arguments = [b'progname', 'arg1', 'arg2']
656 else:
657 program = 'executable'
658 arguments = ['progname', 'arg1', 'arg2']
659 fullpath = os.path.join(program_path, program)
660 if os.name != "nt":
661 native_fullpath = os.fsencode(fullpath)
662 else:
663 native_fullpath = fullpath
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000664 env = {'spam': 'beans'}
665
Victor Stinnerb745a742010-05-18 17:17:23 +0000666 # test os._execvpe() with an absolute path
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000667 with _execvpe_mockup() as calls:
Victor Stinnerb745a742010-05-18 17:17:23 +0000668 self.assertRaises(RuntimeError,
669 os._execvpe, fullpath, arguments)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000670 self.assertEqual(len(calls), 1)
671 self.assertEqual(calls[0], ('execv', fullpath, (arguments,)))
672
Victor Stinnerb745a742010-05-18 17:17:23 +0000673 # test os._execvpe() with a relative path:
674 # os.get_exec_path() returns defpath
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000675 with _execvpe_mockup(defpath=program_path) as calls:
Victor Stinnerb745a742010-05-18 17:17:23 +0000676 self.assertRaises(OSError,
677 os._execvpe, program, arguments, env=env)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000678 self.assertEqual(len(calls), 1)
Victor Stinnerb745a742010-05-18 17:17:23 +0000679 self.assertSequenceEqual(calls[0],
680 ('execve', native_fullpath, (arguments, env)))
681
682 # test os._execvpe() with a relative path:
683 # os.get_exec_path() reads the 'PATH' variable
684 with _execvpe_mockup() as calls:
685 env_path = env.copy()
Victor Stinner38430e22010-08-19 17:10:18 +0000686 if test_type is bytes:
687 env_path[b'PATH'] = program_path
688 else:
689 env_path['PATH'] = program_path
Victor Stinnerb745a742010-05-18 17:17:23 +0000690 self.assertRaises(OSError,
691 os._execvpe, program, arguments, env=env_path)
692 self.assertEqual(len(calls), 1)
693 self.assertSequenceEqual(calls[0],
694 ('execve', native_fullpath, (arguments, env_path)))
695
696 def test_internal_execvpe_str(self):
697 self._test_internal_execvpe(str)
698 if os.name != "nt":
699 self._test_internal_execvpe(bytes)
Victor Stinnerc2d095f2010-05-17 00:14:53 +0000700
Gregory P. Smith4ae37772010-05-08 18:05:46 +0000701
Thomas Wouters477c8d52006-05-27 19:21:47 +0000702class Win32ErrorTests(unittest.TestCase):
703 def test_rename(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000704 self.assertRaises(WindowsError, os.rename, support.TESTFN, support.TESTFN+".bak")
Thomas Wouters477c8d52006-05-27 19:21:47 +0000705
706 def test_remove(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000707 self.assertRaises(WindowsError, os.remove, support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000708
709 def test_chdir(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000710 self.assertRaises(WindowsError, os.chdir, support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000711
712 def test_mkdir(self):
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000713 f = open(support.TESTFN, "w")
Benjamin Petersonf91df042009-02-13 02:50:59 +0000714 try:
715 self.assertRaises(WindowsError, os.mkdir, support.TESTFN)
716 finally:
717 f.close()
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000718 os.unlink(support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000719
720 def test_utime(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000721 self.assertRaises(WindowsError, os.utime, support.TESTFN, None)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000722
Thomas Wouters477c8d52006-05-27 19:21:47 +0000723 def test_chmod(self):
Benjamin Petersonf91df042009-02-13 02:50:59 +0000724 self.assertRaises(WindowsError, os.chmod, support.TESTFN, 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000725
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000726class TestInvalidFD(unittest.TestCase):
Benjamin Peterson05e782f2009-01-19 15:15:02 +0000727 singles = ["fchdir", "dup", "fdopen", "fdatasync", "fstat",
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000728 "fstatvfs", "fsync", "tcgetpgrp", "ttyname"]
729 #singles.append("close")
730 #We omit close because it doesn'r raise an exception on some platforms
731 def get_single(f):
732 def helper(self):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000733 if hasattr(os, f):
734 self.check(getattr(os, f))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000735 return helper
736 for f in singles:
737 locals()["test_"+f] = get_single(f)
738
Benjamin Peterson7522c742009-01-19 21:00:09 +0000739 def check(self, f, *args):
Benjamin Peterson5c6d7872009-02-06 02:40:07 +0000740 try:
741 f(support.make_bad_fd(), *args)
742 except OSError as e:
743 self.assertEqual(e.errno, errno.EBADF)
744 else:
745 self.fail("%r didn't raise a OSError with a bad file descriptor"
746 % f)
Benjamin Peterson7522c742009-01-19 21:00:09 +0000747
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000748 def test_isatty(self):
749 if hasattr(os, "isatty"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000750 self.assertEqual(os.isatty(support.make_bad_fd()), False)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000751
752 def test_closerange(self):
753 if hasattr(os, "closerange"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000754 fd = support.make_bad_fd()
R. David Murray630cc482009-07-22 15:20:27 +0000755 # Make sure none of the descriptors we are about to close are
756 # currently valid (issue 6542).
757 for i in range(10):
758 try: os.fstat(fd+i)
759 except OSError:
760 pass
761 else:
762 break
763 if i < 2:
764 raise unittest.SkipTest(
765 "Unable to acquire a range of invalid file descriptors")
766 self.assertEqual(os.closerange(fd, fd + i-1), None)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000767
768 def test_dup2(self):
769 if hasattr(os, "dup2"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000770 self.check(os.dup2, 20)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000771
772 def test_fchmod(self):
773 if hasattr(os, "fchmod"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000774 self.check(os.fchmod, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000775
776 def test_fchown(self):
777 if hasattr(os, "fchown"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000778 self.check(os.fchown, -1, -1)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000779
780 def test_fpathconf(self):
781 if hasattr(os, "fpathconf"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000782 self.check(os.fpathconf, "PC_NAME_MAX")
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000783
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000784 def test_ftruncate(self):
785 if hasattr(os, "ftruncate"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000786 self.check(os.ftruncate, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000787
788 def test_lseek(self):
789 if hasattr(os, "lseek"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000790 self.check(os.lseek, 0, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000791
792 def test_read(self):
793 if hasattr(os, "read"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000794 self.check(os.read, 1)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000795
796 def test_tcsetpgrpt(self):
797 if hasattr(os, "tcsetpgrp"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000798 self.check(os.tcsetpgrp, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000799
800 def test_write(self):
801 if hasattr(os, "write"):
Benjamin Peterson7522c742009-01-19 21:00:09 +0000802 self.check(os.write, b" ")
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000803
Brian Curtin1b9df392010-11-24 20:24:31 +0000804
805class LinkTests(unittest.TestCase):
806 def setUp(self):
807 self.file1 = support.TESTFN
808 self.file2 = os.path.join(support.TESTFN + "2")
809
Brian Curtinc0abc4e2010-11-30 23:46:54 +0000810 def tearDown(self):
Brian Curtin1b9df392010-11-24 20:24:31 +0000811 for file in (self.file1, self.file2):
812 if os.path.exists(file):
813 os.unlink(file)
814
Brian Curtin1b9df392010-11-24 20:24:31 +0000815 def _test_link(self, file1, file2):
816 with open(file1, "w") as f1:
817 f1.write("test")
818
819 os.link(file1, file2)
820 with open(file1, "r") as f1, open(file2, "r") as f2:
821 self.assertTrue(os.path.sameopenfile(f1.fileno(), f2.fileno()))
822
823 def test_link(self):
824 self._test_link(self.file1, self.file2)
825
826 def test_link_bytes(self):
827 self._test_link(bytes(self.file1, sys.getfilesystemencoding()),
828 bytes(self.file2, sys.getfilesystemencoding()))
829
Brian Curtinf498b752010-11-30 15:54:04 +0000830 def test_unicode_name(self):
Brian Curtin43f0c272010-11-30 15:40:04 +0000831 try:
Brian Curtinf498b752010-11-30 15:54:04 +0000832 os.fsencode("\xf1")
Brian Curtin43f0c272010-11-30 15:40:04 +0000833 except UnicodeError:
834 raise unittest.SkipTest("Unable to encode for this platform.")
835
Brian Curtinf498b752010-11-30 15:54:04 +0000836 self.file1 += "\xf1"
Brian Curtinfc889c42010-11-28 23:59:46 +0000837 self.file2 = self.file1 + "2"
838 self._test_link(self.file1, self.file2)
839
Thomas Wouters477c8d52006-05-27 19:21:47 +0000840if sys.platform != 'win32':
841 class Win32ErrorTests(unittest.TestCase):
842 pass
843
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000844 class PosixUidGidTests(unittest.TestCase):
845 if hasattr(os, 'setuid'):
846 def test_setuid(self):
847 if os.getuid() != 0:
848 self.assertRaises(os.error, os.setuid, 0)
849 self.assertRaises(OverflowError, os.setuid, 1<<32)
850
851 if hasattr(os, 'setgid'):
852 def test_setgid(self):
853 if os.getuid() != 0:
854 self.assertRaises(os.error, os.setgid, 0)
855 self.assertRaises(OverflowError, os.setgid, 1<<32)
856
857 if hasattr(os, 'seteuid'):
858 def test_seteuid(self):
859 if os.getuid() != 0:
860 self.assertRaises(os.error, os.seteuid, 0)
861 self.assertRaises(OverflowError, os.seteuid, 1<<32)
862
863 if hasattr(os, 'setegid'):
864 def test_setegid(self):
865 if os.getuid() != 0:
866 self.assertRaises(os.error, os.setegid, 0)
867 self.assertRaises(OverflowError, os.setegid, 1<<32)
868
869 if hasattr(os, 'setreuid'):
870 def test_setreuid(self):
871 if os.getuid() != 0:
872 self.assertRaises(os.error, os.setreuid, 0, 0)
873 self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
874 self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000875
876 def test_setreuid_neg1(self):
877 # Needs to accept -1. We run this in a subprocess to avoid
878 # altering the test runner's process state (issue8045).
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000879 subprocess.check_call([
880 sys.executable, '-c',
881 'import os,sys;os.setreuid(-1,-1);sys.exit(0)'])
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000882
883 if hasattr(os, 'setregid'):
884 def test_setregid(self):
885 if os.getuid() != 0:
886 self.assertRaises(os.error, os.setregid, 0, 0)
887 self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
888 self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000889
890 def test_setregid_neg1(self):
891 # Needs to accept -1. We run this in a subprocess to avoid
892 # altering the test runner's process state (issue8045).
Benjamin Petersonebe87ba2010-03-06 20:34:24 +0000893 subprocess.check_call([
894 sys.executable, '-c',
895 'import os,sys;os.setregid(-1,-1);sys.exit(0)'])
Martin v. Löwis011e8422009-05-05 04:43:17 +0000896
897 class Pep383Tests(unittest.TestCase):
Martin v. Löwis011e8422009-05-05 04:43:17 +0000898 def setUp(self):
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000899 if support.TESTFN_UNENCODABLE:
900 self.dir = support.TESTFN_UNENCODABLE
901 else:
902 self.dir = support.TESTFN
903 self.bdir = os.fsencode(self.dir)
904
905 bytesfn = []
906 def add_filename(fn):
907 try:
908 fn = os.fsencode(fn)
909 except UnicodeEncodeError:
910 return
911 bytesfn.append(fn)
912 add_filename(support.TESTFN_UNICODE)
913 if support.TESTFN_UNENCODABLE:
914 add_filename(support.TESTFN_UNENCODABLE)
915 if not bytesfn:
916 self.skipTest("couldn't create any non-ascii filename")
917
918 self.unicodefn = set()
Martin v. Löwis011e8422009-05-05 04:43:17 +0000919 os.mkdir(self.dir)
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000920 try:
921 for fn in bytesfn:
922 f = open(os.path.join(self.bdir, fn), "w")
923 f.close()
Victor Stinnere8d51452010-08-19 01:05:19 +0000924 fn = os.fsdecode(fn)
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000925 if fn in self.unicodefn:
926 raise ValueError("duplicate filename")
927 self.unicodefn.add(fn)
928 except:
929 shutil.rmtree(self.dir)
930 raise
Martin v. Löwis011e8422009-05-05 04:43:17 +0000931
932 def tearDown(self):
933 shutil.rmtree(self.dir)
Martin v. Löwis011e8422009-05-05 04:43:17 +0000934
935 def test_listdir(self):
Victor Stinnerd91df1a2010-08-18 10:56:19 +0000936 expected = self.unicodefn
937 found = set(os.listdir(self.dir))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000938 self.assertEqual(found, expected)
Martin v. Löwis011e8422009-05-05 04:43:17 +0000939
940 def test_open(self):
941 for fn in self.unicodefn:
Victor Stinnera6d2c762011-06-30 18:20:11 +0200942 f = open(os.path.join(self.dir, fn), 'rb')
Martin v. Löwis011e8422009-05-05 04:43:17 +0000943 f.close()
944
945 def test_stat(self):
946 for fn in self.unicodefn:
947 os.stat(os.path.join(self.dir, fn))
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000948else:
949 class PosixUidGidTests(unittest.TestCase):
950 pass
Martin v. Löwis011e8422009-05-05 04:43:17 +0000951 class Pep383Tests(unittest.TestCase):
952 pass
Benjamin Petersonef3e4c22009-04-11 19:48:14 +0000953
Brian Curtineb24d742010-04-12 17:16:38 +0000954@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
955class Win32KillTests(unittest.TestCase):
Brian Curtinc3acbc32010-05-28 16:08:40 +0000956 def _kill(self, sig):
957 # Start sys.executable as a subprocess and communicate from the
958 # subprocess to the parent that the interpreter is ready. When it
959 # becomes ready, send *sig* via os.kill to the subprocess and check
960 # that the return code is equal to *sig*.
961 import ctypes
962 from ctypes import wintypes
963 import msvcrt
964
965 # Since we can't access the contents of the process' stdout until the
966 # process has exited, use PeekNamedPipe to see what's inside stdout
967 # without waiting. This is done so we can tell that the interpreter
968 # is started and running at a point where it could handle a signal.
969 PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe
970 PeekNamedPipe.restype = wintypes.BOOL
971 PeekNamedPipe.argtypes = (wintypes.HANDLE, # Pipe handle
972 ctypes.POINTER(ctypes.c_char), # stdout buf
973 wintypes.DWORD, # Buffer size
974 ctypes.POINTER(wintypes.DWORD), # bytes read
975 ctypes.POINTER(wintypes.DWORD), # bytes avail
976 ctypes.POINTER(wintypes.DWORD)) # bytes left
977 msg = "running"
978 proc = subprocess.Popen([sys.executable, "-c",
979 "import sys;"
980 "sys.stdout.write('{}');"
981 "sys.stdout.flush();"
982 "input()".format(msg)],
983 stdout=subprocess.PIPE,
984 stderr=subprocess.PIPE,
985 stdin=subprocess.PIPE)
Brian Curtin43ec5772010-11-05 15:17:11 +0000986 self.addCleanup(proc.stdout.close)
987 self.addCleanup(proc.stderr.close)
988 self.addCleanup(proc.stdin.close)
Brian Curtinc3acbc32010-05-28 16:08:40 +0000989
990 count, max = 0, 100
991 while count < max and proc.poll() is None:
992 # Create a string buffer to store the result of stdout from the pipe
993 buf = ctypes.create_string_buffer(len(msg))
994 # Obtain the text currently in proc.stdout
995 # Bytes read/avail/left are left as NULL and unused
996 rslt = PeekNamedPipe(msvcrt.get_osfhandle(proc.stdout.fileno()),
997 buf, ctypes.sizeof(buf), None, None, None)
998 self.assertNotEqual(rslt, 0, "PeekNamedPipe failed")
999 if buf.value:
1000 self.assertEqual(msg, buf.value.decode())
1001 break
1002 time.sleep(0.1)
1003 count += 1
1004 else:
1005 self.fail("Did not receive communication from the subprocess")
1006
Brian Curtineb24d742010-04-12 17:16:38 +00001007 os.kill(proc.pid, sig)
1008 self.assertEqual(proc.wait(), sig)
1009
1010 def test_kill_sigterm(self):
1011 # SIGTERM doesn't mean anything special, but make sure it works
Brian Curtinc3acbc32010-05-28 16:08:40 +00001012 self._kill(signal.SIGTERM)
Brian Curtineb24d742010-04-12 17:16:38 +00001013
1014 def test_kill_int(self):
1015 # os.kill on Windows can take an int which gets set as the exit code
Brian Curtinc3acbc32010-05-28 16:08:40 +00001016 self._kill(100)
Brian Curtineb24d742010-04-12 17:16:38 +00001017
1018 def _kill_with_event(self, event, name):
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001019 tagname = "test_os_%s" % uuid.uuid1()
1020 m = mmap.mmap(-1, 1, tagname)
1021 m[0] = 0
Brian Curtineb24d742010-04-12 17:16:38 +00001022 # Run a script which has console control handling enabled.
1023 proc = subprocess.Popen([sys.executable,
1024 os.path.join(os.path.dirname(__file__),
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001025 "win_console_handler.py"), tagname],
Brian Curtineb24d742010-04-12 17:16:38 +00001026 creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
1027 # Let the interpreter startup before we send signals. See #3137.
Hirokazu Yamamoto8e9fe9f2010-12-05 02:41:46 +00001028 count, max = 0, 100
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001029 while count < max and proc.poll() is None:
Brian Curtinf668df52010-10-15 14:21:06 +00001030 if m[0] == 1:
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001031 break
Hirokazu Yamamoto8e9fe9f2010-12-05 02:41:46 +00001032 time.sleep(0.1)
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001033 count += 1
1034 else:
Hirokazu Yamamoto8e9fe9f2010-12-05 02:41:46 +00001035 # Forcefully kill the process if we weren't able to signal it.
1036 os.kill(proc.pid, signal.SIGINT)
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001037 self.fail("Subprocess didn't finish initialization")
Brian Curtineb24d742010-04-12 17:16:38 +00001038 os.kill(proc.pid, event)
1039 # proc.send_signal(event) could also be done here.
1040 # Allow time for the signal to be passed and the process to exit.
1041 time.sleep(0.5)
1042 if not proc.poll():
1043 # Forcefully kill the process if we weren't able to signal it.
1044 os.kill(proc.pid, signal.SIGINT)
1045 self.fail("subprocess did not stop on {}".format(name))
1046
1047 @unittest.skip("subprocesses aren't inheriting CTRL+C property")
1048 def test_CTRL_C_EVENT(self):
1049 from ctypes import wintypes
1050 import ctypes
1051
1052 # Make a NULL value by creating a pointer with no argument.
1053 NULL = ctypes.POINTER(ctypes.c_int)()
1054 SetConsoleCtrlHandler = ctypes.windll.kernel32.SetConsoleCtrlHandler
1055 SetConsoleCtrlHandler.argtypes = (ctypes.POINTER(ctypes.c_int),
1056 wintypes.BOOL)
1057 SetConsoleCtrlHandler.restype = wintypes.BOOL
1058
1059 # Calling this with NULL and FALSE causes the calling process to
1060 # handle CTRL+C, rather than ignore it. This property is inherited
1061 # by subprocesses.
1062 SetConsoleCtrlHandler(NULL, 0)
1063
1064 self._kill_with_event(signal.CTRL_C_EVENT, "CTRL_C_EVENT")
1065
1066 def test_CTRL_BREAK_EVENT(self):
1067 self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT")
1068
1069
Brian Curtind40e6f72010-07-08 21:39:08 +00001070@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
Brian Curtin3b4499c2010-12-28 14:31:47 +00001071@support.skip_unless_symlink
Brian Curtind40e6f72010-07-08 21:39:08 +00001072class Win32SymlinkTests(unittest.TestCase):
1073 filelink = 'filelinktest'
1074 filelink_target = os.path.abspath(__file__)
1075 dirlink = 'dirlinktest'
1076 dirlink_target = os.path.dirname(filelink_target)
1077 missing_link = 'missing link'
1078
1079 def setUp(self):
1080 assert os.path.exists(self.dirlink_target)
1081 assert os.path.exists(self.filelink_target)
1082 assert not os.path.exists(self.dirlink)
1083 assert not os.path.exists(self.filelink)
1084 assert not os.path.exists(self.missing_link)
1085
1086 def tearDown(self):
1087 if os.path.exists(self.filelink):
1088 os.remove(self.filelink)
1089 if os.path.exists(self.dirlink):
1090 os.rmdir(self.dirlink)
1091 if os.path.lexists(self.missing_link):
1092 os.remove(self.missing_link)
1093
1094 def test_directory_link(self):
1095 os.symlink(self.dirlink_target, self.dirlink)
1096 self.assertTrue(os.path.exists(self.dirlink))
1097 self.assertTrue(os.path.isdir(self.dirlink))
1098 self.assertTrue(os.path.islink(self.dirlink))
1099 self.check_stat(self.dirlink, self.dirlink_target)
1100
1101 def test_file_link(self):
1102 os.symlink(self.filelink_target, self.filelink)
1103 self.assertTrue(os.path.exists(self.filelink))
1104 self.assertTrue(os.path.isfile(self.filelink))
1105 self.assertTrue(os.path.islink(self.filelink))
1106 self.check_stat(self.filelink, self.filelink_target)
1107
1108 def _create_missing_dir_link(self):
1109 'Create a "directory" link to a non-existent target'
1110 linkname = self.missing_link
1111 if os.path.lexists(linkname):
1112 os.remove(linkname)
1113 target = r'c:\\target does not exist.29r3c740'
1114 assert not os.path.exists(target)
1115 target_is_dir = True
1116 os.symlink(target, linkname, target_is_dir)
1117
1118 def test_remove_directory_link_to_missing_target(self):
1119 self._create_missing_dir_link()
1120 # For compatibility with Unix, os.remove will check the
1121 # directory status and call RemoveDirectory if the symlink
1122 # was created with target_is_dir==True.
1123 os.remove(self.missing_link)
1124
1125 @unittest.skip("currently fails; consider for improvement")
1126 def test_isdir_on_directory_link_to_missing_target(self):
1127 self._create_missing_dir_link()
1128 # consider having isdir return true for directory links
1129 self.assertTrue(os.path.isdir(self.missing_link))
1130
1131 @unittest.skip("currently fails; consider for improvement")
1132 def test_rmdir_on_directory_link_to_missing_target(self):
1133 self._create_missing_dir_link()
1134 # consider allowing rmdir to remove directory links
1135 os.rmdir(self.missing_link)
1136
1137 def check_stat(self, link, target):
1138 self.assertEqual(os.stat(link), os.stat(target))
1139 self.assertNotEqual(os.lstat(link), os.stat(link))
1140
Brian Curtind25aef52011-06-13 15:16:04 -05001141 bytes_link = os.fsencode(link)
1142 self.assertEqual(os.stat(bytes_link), os.stat(target))
1143 self.assertNotEqual(os.lstat(bytes_link), os.stat(bytes_link))
1144
1145 def test_12084(self):
1146 level1 = os.path.abspath(support.TESTFN)
1147 level2 = os.path.join(level1, "level2")
1148 level3 = os.path.join(level2, "level3")
1149 try:
1150 os.mkdir(level1)
1151 os.mkdir(level2)
1152 os.mkdir(level3)
1153
1154 file1 = os.path.abspath(os.path.join(level1, "file1"))
1155
1156 with open(file1, "w") as f:
1157 f.write("file1")
1158
1159 orig_dir = os.getcwd()
1160 try:
1161 os.chdir(level2)
1162 link = os.path.join(level2, "link")
1163 os.symlink(os.path.relpath(file1), "link")
1164 self.assertIn("link", os.listdir(os.getcwd()))
1165
1166 # Check os.stat calls from the same dir as the link
1167 self.assertEqual(os.stat(file1), os.stat("link"))
1168
1169 # Check os.stat calls from a dir below the link
1170 os.chdir(level1)
1171 self.assertEqual(os.stat(file1),
1172 os.stat(os.path.relpath(link)))
1173
1174 # Check os.stat calls from a dir above the link
1175 os.chdir(level3)
1176 self.assertEqual(os.stat(file1),
1177 os.stat(os.path.relpath(link)))
1178 finally:
1179 os.chdir(orig_dir)
1180 except OSError as err:
1181 self.fail(err)
1182 finally:
1183 os.remove(file1)
1184 shutil.rmtree(level1)
1185
Brian Curtind40e6f72010-07-08 21:39:08 +00001186
Victor Stinnere8d51452010-08-19 01:05:19 +00001187class FSEncodingTests(unittest.TestCase):
1188 def test_nop(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +00001189 self.assertEqual(os.fsencode(b'abc\xff'), b'abc\xff')
1190 self.assertEqual(os.fsdecode('abc\u0141'), 'abc\u0141')
Benjamin Peterson31191a92010-05-09 03:22:58 +00001191
Victor Stinnere8d51452010-08-19 01:05:19 +00001192 def test_identity(self):
1193 # assert fsdecode(fsencode(x)) == x
1194 for fn in ('unicode\u0141', 'latin\xe9', 'ascii'):
1195 try:
1196 bytesfn = os.fsencode(fn)
1197 except UnicodeEncodeError:
1198 continue
Ezio Melottib3aedd42010-11-20 19:04:17 +00001199 self.assertEqual(os.fsdecode(bytesfn), fn)
Victor Stinnere8d51452010-08-19 01:05:19 +00001200
Victor Stinnerbf9bcab2010-05-09 03:15:33 +00001201
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00001202class PidTests(unittest.TestCase):
1203 @unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid")
1204 def test_getppid(self):
1205 p = subprocess.Popen([sys.executable, '-c',
1206 'import os; print(os.getppid())'],
1207 stdout=subprocess.PIPE)
1208 stdout, _ = p.communicate()
1209 # We are the parent of our subprocess
1210 self.assertEqual(int(stdout), os.getpid())
1211
1212
Brian Curtin0151b8e2010-09-24 13:43:43 +00001213# The introduction of this TestCase caused at least two different errors on
1214# *nix buildbots. Temporarily skip this to let the buildbots move along.
1215@unittest.skip("Skip due to platform/environment differences on *NIX buildbots")
Brian Curtine8e4b3b2010-09-23 20:04:14 +00001216@unittest.skipUnless(hasattr(os, 'getlogin'), "test needs os.getlogin")
1217class LoginTests(unittest.TestCase):
1218 def test_getlogin(self):
1219 user_name = os.getlogin()
1220 self.assertNotEqual(len(user_name), 0)
1221
1222
Fred Drake2e2be372001-09-20 21:33:42 +00001223def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001224 support.run_unittest(
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001225 FileTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001226 StatAttributeTests,
1227 EnvironTests,
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001228 WalkTests,
1229 MakedirTests,
Martin v. Löwisbdec50f2004-06-08 08:29:33 +00001230 DevNullTests,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001231 URandomTests,
Guido van Rossume7ba4952007-06-06 23:52:48 +00001232 ExecTests,
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001233 Win32ErrorTests,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001234 TestInvalidFD,
Martin v. Löwis011e8422009-05-05 04:43:17 +00001235 PosixUidGidTests,
Brian Curtineb24d742010-04-12 17:16:38 +00001236 Pep383Tests,
Victor Stinnerbf9bcab2010-05-09 03:15:33 +00001237 Win32KillTests,
Brian Curtind40e6f72010-07-08 21:39:08 +00001238 Win32SymlinkTests,
Victor Stinnere8d51452010-08-19 01:05:19 +00001239 FSEncodingTests,
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00001240 PidTests,
Brian Curtine8e4b3b2010-09-23 20:04:14 +00001241 LoginTests,
Brian Curtin1b9df392010-11-24 20:24:31 +00001242 LinkTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001243 )
Fred Drake2e2be372001-09-20 21:33:42 +00001244
1245if __name__ == "__main__":
1246 test_main()