blob: d7d08cece3cd04316f143163290b81cfb723d1dd [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
Victor Stinner47aacc82015-06-12 17:26:23 +02005import asynchat
6import asyncore
7import codecs
Victor Stinnerc2d095f2010-05-17 00:14:53 +00008import contextlib
Victor Stinner47aacc82015-06-12 17:26:23 +02009import decimal
10import errno
11import fractions
12import getpass
13import itertools
14import locale
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +000015import mmap
Victor Stinner47aacc82015-06-12 17:26:23 +020016import os
17import pickle
Victor Stinner47aacc82015-06-12 17:26:23 +020018import shutil
19import signal
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000020import socket
Charles-François Natali7372b062012-02-05 15:15:38 +010021import stat
Victor Stinner47aacc82015-06-12 17:26:23 +020022import subprocess
23import sys
Victor Stinner4d6a3d62014-12-21 01:16:38 +010024import sysconfig
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020025import threading
Victor Stinner47aacc82015-06-12 17:26:23 +020026import time
27import unittest
28import uuid
29import warnings
30from test import support
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020031
Antoine Pitrouec34ab52013-08-16 20:44:38 +020032try:
33 import resource
34except ImportError:
35 resource = None
Victor Stinner7ba6b0f2013-09-08 11:47:54 +020036try:
37 import fcntl
38except ImportError:
39 fcntl = None
Tim Golden0321cf22014-05-05 19:46:17 +010040try:
41 import _winapi
42except ImportError:
43 _winapi = None
Victor Stinnerb28ed922014-07-11 17:04:41 +020044try:
R David Murrayf2ad1732014-12-25 18:36:56 -050045 import grp
46 groups = [g.gr_gid for g in grp.getgrall() if getpass.getuser() in g.gr_mem]
47 if hasattr(os, 'getgid'):
48 process_gid = os.getgid()
49 if process_gid not in groups:
50 groups.append(process_gid)
51except ImportError:
52 groups = []
53try:
54 import pwd
55 all_users = [u.pw_uid for u in pwd.getpwall()]
Xavier de Gaye21060102016-11-16 08:05:27 +010056except (ImportError, AttributeError):
R David Murrayf2ad1732014-12-25 18:36:56 -050057 all_users = []
58try:
Victor Stinner5c6e6fc2014-07-12 11:03:53 +020059 from _testcapi import INT_MAX, PY_SSIZE_T_MAX
Victor Stinnerb28ed922014-07-11 17:04:41 +020060except ImportError:
Victor Stinner5c6e6fc2014-07-12 11:03:53 +020061 INT_MAX = PY_SSIZE_T_MAX = sys.maxsize
Antoine Pitrouec34ab52013-08-16 20:44:38 +020062
Berker Peksagce643912015-05-06 06:33:17 +030063from test.support.script_helper import assert_python_ok
Xavier de Gayed1415312016-07-22 12:15:29 +020064from test.support import unix_shell
Fred Drake38c2ef02001-07-17 20:52:51 +000065
Victor Stinner923590e2016-03-24 09:11:48 +010066
R David Murrayf2ad1732014-12-25 18:36:56 -050067root_in_posix = False
68if hasattr(os, 'geteuid'):
69 root_in_posix = (os.geteuid() == 0)
70
Mark Dickinson7cf03892010-04-16 13:45:35 +000071# Detect whether we're on a Linux system that uses the (now outdated
72# and unmaintained) linuxthreads threading library. There's an issue
73# when combining linuxthreads with a failed execv call: see
74# http://bugs.python.org/issue4970.
Victor Stinnerd5c355c2011-04-30 14:53:09 +020075if hasattr(sys, 'thread_info') and sys.thread_info.version:
76 USING_LINUXTHREADS = sys.thread_info.version.startswith("linuxthreads")
77else:
78 USING_LINUXTHREADS = False
Brian Curtineb24d742010-04-12 17:16:38 +000079
Stefan Krahebee49a2013-01-17 15:31:00 +010080# Issue #14110: Some tests fail on FreeBSD if the user is in the wheel group.
81HAVE_WHEEL_GROUP = sys.platform.startswith('freebsd') and os.getgid() == 0
82
Victor Stinner923590e2016-03-24 09:11:48 +010083
84@contextlib.contextmanager
85def ignore_deprecation_warnings(msg_regex, quiet=False):
86 with support.check_warnings((msg_regex, DeprecationWarning), quiet=quiet):
87 yield
88
89
Berker Peksag4af23d72016-09-15 20:32:44 +030090def requires_os_func(name):
91 return unittest.skipUnless(hasattr(os, name), 'requires os.%s' % name)
92
93
Brett Cannonec6ce872016-09-06 15:50:29 -070094class _PathLike(os.PathLike):
95
96 def __init__(self, path=""):
97 self.path = path
98
99 def __str__(self):
100 return str(self.path)
101
102 def __fspath__(self):
103 if isinstance(self.path, BaseException):
104 raise self.path
105 else:
106 return self.path
107
108
Victor Stinnerae39d232016-03-24 17:12:55 +0100109def create_file(filename, content=b'content'):
110 with open(filename, "xb", 0) as fp:
111 fp.write(content)
112
113
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000114# Tests creating TESTFN
115class FileTests(unittest.TestCase):
116 def setUp(self):
Martin Panterbf19d162015-09-09 01:01:13 +0000117 if os.path.lexists(support.TESTFN):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000118 os.unlink(support.TESTFN)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000119 tearDown = setUp
120
121 def test_access(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000122 f = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000123 os.close(f)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000124 self.assertTrue(os.access(support.TESTFN, os.W_OK))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000125
Christian Heimesfdab48e2008-01-20 09:06:41 +0000126 def test_closerange(self):
Antoine Pitroub9ee06c2008-08-16 22:03:17 +0000127 first = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR)
128 # We must allocate two consecutive file descriptors, otherwise
129 # it will mess up other file descriptors (perhaps even the three
130 # standard ones).
131 second = os.dup(first)
132 try:
133 retries = 0
134 while second != first + 1:
135 os.close(first)
136 retries += 1
137 if retries > 10:
138 # XXX test skipped
Benjamin Petersonfa0d7032009-06-01 22:42:33 +0000139 self.skipTest("couldn't allocate two consecutive fds")
Antoine Pitroub9ee06c2008-08-16 22:03:17 +0000140 first, second = second, os.dup(second)
141 finally:
142 os.close(second)
Christian Heimesfdab48e2008-01-20 09:06:41 +0000143 # close a fd that is open, and one that isn't
Antoine Pitroub9ee06c2008-08-16 22:03:17 +0000144 os.closerange(first, first + 2)
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000145 self.assertRaises(OSError, os.write, first, b"a")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000146
Benjamin Peterson1cc6df92010-06-30 17:39:45 +0000147 @support.cpython_only
Hirokazu Yamamoto4c19e6e2008-09-08 23:41:21 +0000148 def test_rename(self):
149 path = support.TESTFN
150 old = sys.getrefcount(path)
151 self.assertRaises(TypeError, os.rename, path, 0)
152 new = sys.getrefcount(path)
153 self.assertEqual(old, new)
154
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000155 def test_read(self):
156 with open(support.TESTFN, "w+b") as fobj:
157 fobj.write(b"spam")
158 fobj.flush()
159 fd = fobj.fileno()
160 os.lseek(fd, 0, 0)
161 s = os.read(fd, 4)
162 self.assertEqual(type(s), bytes)
163 self.assertEqual(s, b"spam")
164
Victor Stinner6e1ccfe2014-07-11 17:35:06 +0200165 @support.cpython_only
Victor Stinner5c6e6fc2014-07-12 11:03:53 +0200166 # Skip the test on 32-bit platforms: the number of bytes must fit in a
167 # Py_ssize_t type
168 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX,
169 "needs INT_MAX < PY_SSIZE_T_MAX")
Victor Stinner6e1ccfe2014-07-11 17:35:06 +0200170 @support.bigmemtest(size=INT_MAX + 10, memuse=1, dry_run=False)
171 def test_large_read(self, size):
Victor Stinnerb28ed922014-07-11 17:04:41 +0200172 self.addCleanup(support.unlink, support.TESTFN)
Victor Stinnerae39d232016-03-24 17:12:55 +0100173 create_file(support.TESTFN, b'test')
Victor Stinnerb28ed922014-07-11 17:04:41 +0200174
175 # Issue #21932: Make sure that os.read() does not raise an
176 # OverflowError for size larger than INT_MAX
Victor Stinnerb28ed922014-07-11 17:04:41 +0200177 with open(support.TESTFN, "rb") as fp:
178 data = os.read(fp.fileno(), size)
179
180 # The test does not try to read more than 2 GB at once because the
181 # operating system is free to return less bytes than requested.
182 self.assertEqual(data, b'test')
183
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000184 def test_write(self):
185 # os.write() accepts bytes- and buffer-like objects but not strings
186 fd = os.open(support.TESTFN, os.O_CREAT | os.O_WRONLY)
187 self.assertRaises(TypeError, os.write, fd, "beans")
188 os.write(fd, b"bacon\n")
189 os.write(fd, bytearray(b"eggs\n"))
190 os.write(fd, memoryview(b"spam\n"))
191 os.close(fd)
192 with open(support.TESTFN, "rb") as fobj:
Antoine Pitroud62269f2008-09-15 23:54:52 +0000193 self.assertEqual(fobj.read().splitlines(),
194 [b"bacon", b"eggs", b"spam"])
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000195
Victor Stinnere0daff12011-03-20 23:36:35 +0100196 def write_windows_console(self, *args):
197 retcode = subprocess.call(args,
198 # use a new console to not flood the test output
199 creationflags=subprocess.CREATE_NEW_CONSOLE,
200 # use a shell to hide the console window (SW_HIDE)
201 shell=True)
202 self.assertEqual(retcode, 0)
203
204 @unittest.skipUnless(sys.platform == 'win32',
205 'test specific to the Windows console')
206 def test_write_windows_console(self):
207 # Issue #11395: the Windows console returns an error (12: not enough
208 # space error) on writing into stdout if stdout mode is binary and the
209 # length is greater than 66,000 bytes (or less, depending on heap
210 # usage).
211 code = "print('x' * 100000)"
212 self.write_windows_console(sys.executable, "-c", code)
213 self.write_windows_console(sys.executable, "-u", "-c", code)
214
Amaury Forgeot d'Arce2e36ba2008-08-01 00:14:22 +0000215 def fdopen_helper(self, *args):
216 fd = os.open(support.TESTFN, os.O_RDONLY)
Victor Stinnerbef7fdf2011-07-01 13:45:30 +0200217 f = os.fdopen(fd, *args)
218 f.close()
Amaury Forgeot d'Arce2e36ba2008-08-01 00:14:22 +0000219
220 def test_fdopen(self):
Victor Stinnerbef7fdf2011-07-01 13:45:30 +0200221 fd = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR)
222 os.close(fd)
223
Amaury Forgeot d'Arce2e36ba2008-08-01 00:14:22 +0000224 self.fdopen_helper()
225 self.fdopen_helper('r')
226 self.fdopen_helper('r', 100)
227
Antoine Pitrouf3b2d882012-01-30 22:08:52 +0100228 def test_replace(self):
229 TESTFN2 = support.TESTFN + ".2"
Victor Stinnerae39d232016-03-24 17:12:55 +0100230 self.addCleanup(support.unlink, support.TESTFN)
231 self.addCleanup(support.unlink, TESTFN2)
232
233 create_file(support.TESTFN, b"1")
234 create_file(TESTFN2, b"2")
235
Antoine Pitrouf3b2d882012-01-30 22:08:52 +0100236 os.replace(support.TESTFN, TESTFN2)
237 self.assertRaises(FileNotFoundError, os.stat, support.TESTFN)
238 with open(TESTFN2, 'r') as f:
239 self.assertEqual(f.read(), "1")
240
Martin Panterbf19d162015-09-09 01:01:13 +0000241 def test_open_keywords(self):
242 f = os.open(path=__file__, flags=os.O_RDONLY, mode=0o777,
243 dir_fd=None)
244 os.close(f)
245
246 def test_symlink_keywords(self):
247 symlink = support.get_attribute(os, "symlink")
248 try:
249 symlink(src='target', dst=support.TESTFN,
250 target_is_directory=False, dir_fd=None)
251 except (NotImplementedError, OSError):
252 pass # No OS support or unprivileged user
253
Victor Stinnerbef7fdf2011-07-01 13:45:30 +0200254
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000255# Test attributes on return values from os.*stat* family.
256class StatAttributeTests(unittest.TestCase):
257 def setUp(self):
Victor Stinner47aacc82015-06-12 17:26:23 +0200258 self.fname = support.TESTFN
259 self.addCleanup(support.unlink, self.fname)
Victor Stinnerae39d232016-03-24 17:12:55 +0100260 create_file(self.fname, b"ABC")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000261
Serhiy Storchaka43767632013-11-03 21:31:38 +0200262 @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
Antoine Pitrou38425292010-09-21 18:19:07 +0000263 def check_stat_attributes(self, fname):
Antoine Pitrou38425292010-09-21 18:19:07 +0000264 result = os.stat(fname)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000265
266 # Make sure direct access works
Ezio Melottib3aedd42010-11-20 19:04:17 +0000267 self.assertEqual(result[stat.ST_SIZE], 3)
268 self.assertEqual(result.st_size, 3)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000269
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000270 # Make sure all the attributes are there
271 members = dir(result)
272 for name in dir(stat):
273 if name[:3] == 'ST_':
274 attr = name.lower()
Martin v. Löwis4d394df2005-01-23 09:19:22 +0000275 if name.endswith("TIME"):
276 def trunc(x): return int(x)
277 else:
278 def trunc(x): return x
Ezio Melottib3aedd42010-11-20 19:04:17 +0000279 self.assertEqual(trunc(getattr(result, attr)),
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000280 result[getattr(stat, name)])
Benjamin Peterson577473f2010-01-19 00:09:57 +0000281 self.assertIn(attr, members)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000282
Larry Hastings6fe20b32012-04-19 15:07:49 -0700283 # Make sure that the st_?time and st_?time_ns fields roughly agree
Larry Hastings76ad59b2012-05-03 00:30:07 -0700284 # (they should always agree up to around tens-of-microseconds)
Larry Hastings6fe20b32012-04-19 15:07:49 -0700285 for name in 'st_atime st_mtime st_ctime'.split():
286 floaty = int(getattr(result, name) * 100000)
287 nanosecondy = getattr(result, name + "_ns") // 10000
Larry Hastings76ad59b2012-05-03 00:30:07 -0700288 self.assertAlmostEqual(floaty, nanosecondy, delta=2)
Larry Hastings6fe20b32012-04-19 15:07:49 -0700289
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000290 try:
291 result[200]
Andrew Svetlov737fb892012-12-18 21:14:22 +0200292 self.fail("No exception raised")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000293 except IndexError:
294 pass
295
296 # Make sure that assignment fails
297 try:
298 result.st_mode = 1
Andrew Svetlov737fb892012-12-18 21:14:22 +0200299 self.fail("No exception raised")
Collin Winter42dae6a2007-03-28 21:44:53 +0000300 except AttributeError:
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000301 pass
302
303 try:
304 result.st_rdev = 1
Andrew Svetlov737fb892012-12-18 21:14:22 +0200305 self.fail("No exception raised")
Guido van Rossum1fff8782001-10-18 21:19:31 +0000306 except (AttributeError, TypeError):
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000307 pass
308
309 try:
310 result.parrot = 1
Andrew Svetlov737fb892012-12-18 21:14:22 +0200311 self.fail("No exception raised")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000312 except AttributeError:
313 pass
314
315 # Use the stat_result constructor with a too-short tuple.
316 try:
317 result2 = os.stat_result((10,))
Andrew Svetlov737fb892012-12-18 21:14:22 +0200318 self.fail("No exception raised")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000319 except TypeError:
320 pass
321
Ezio Melotti42da6632011-03-15 05:18:48 +0200322 # Use the constructor with a too-long tuple.
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000323 try:
324 result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
325 except TypeError:
326 pass
327
Antoine Pitrou38425292010-09-21 18:19:07 +0000328 def test_stat_attributes(self):
329 self.check_stat_attributes(self.fname)
330
331 def test_stat_attributes_bytes(self):
332 try:
333 fname = self.fname.encode(sys.getfilesystemencoding())
334 except UnicodeEncodeError:
335 self.skipTest("cannot encode %a for the filesystem" % self.fname)
Steve Dowercc16be82016-09-08 10:35:16 -0700336 self.check_stat_attributes(fname)
Tim Peterse0c446b2001-10-18 21:57:37 +0000337
Christian Heimes25827622013-10-12 01:27:08 +0200338 def test_stat_result_pickle(self):
339 result = os.stat(self.fname)
Serhiy Storchakabad12572014-12-15 14:03:42 +0200340 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
341 p = pickle.dumps(result, proto)
342 self.assertIn(b'stat_result', p)
343 if proto < 4:
344 self.assertIn(b'cos\nstat_result\n', p)
345 unpickled = pickle.loads(p)
346 self.assertEqual(result, unpickled)
Christian Heimes25827622013-10-12 01:27:08 +0200347
Serhiy Storchaka43767632013-11-03 21:31:38 +0200348 @unittest.skipUnless(hasattr(os, 'statvfs'), 'test needs os.statvfs()')
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000349 def test_statvfs_attributes(self):
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000350 try:
351 result = os.statvfs(self.fname)
Guido van Rossumb940e112007-01-10 16:19:56 +0000352 except OSError as e:
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000353 # On AtheOS, glibc always returns ENOSYS
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000354 if e.errno == errno.ENOSYS:
Victor Stinner370cb252013-10-12 01:33:54 +0200355 self.skipTest('os.statvfs() failed with ENOSYS')
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000356
357 # Make sure direct access works
Ezio Melottib3aedd42010-11-20 19:04:17 +0000358 self.assertEqual(result.f_bfree, result[3])
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000359
Brett Cannoncfaf10c2008-05-16 00:45:35 +0000360 # Make sure all the attributes are there.
361 members = ('bsize', 'frsize', 'blocks', 'bfree', 'bavail', 'files',
362 'ffree', 'favail', 'flag', 'namemax')
363 for value, member in enumerate(members):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000364 self.assertEqual(getattr(result, 'f_' + member), result[value])
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000365
366 # Make sure that assignment really fails
367 try:
368 result.f_bfree = 1
Andrew Svetlov737fb892012-12-18 21:14:22 +0200369 self.fail("No exception raised")
Collin Winter42dae6a2007-03-28 21:44:53 +0000370 except AttributeError:
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000371 pass
372
373 try:
374 result.parrot = 1
Andrew Svetlov737fb892012-12-18 21:14:22 +0200375 self.fail("No exception raised")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000376 except AttributeError:
377 pass
378
379 # Use the constructor with a too-short tuple.
380 try:
381 result2 = os.statvfs_result((10,))
Andrew Svetlov737fb892012-12-18 21:14:22 +0200382 self.fail("No exception raised")
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000383 except TypeError:
384 pass
385
Ezio Melotti42da6632011-03-15 05:18:48 +0200386 # Use the constructor with a too-long tuple.
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000387 try:
388 result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
389 except TypeError:
390 pass
Fred Drake38c2ef02001-07-17 20:52:51 +0000391
Christian Heimes25827622013-10-12 01:27:08 +0200392 @unittest.skipUnless(hasattr(os, 'statvfs'),
393 "need os.statvfs()")
394 def test_statvfs_result_pickle(self):
395 try:
396 result = os.statvfs(self.fname)
397 except OSError as e:
398 # On AtheOS, glibc always returns ENOSYS
399 if e.errno == errno.ENOSYS:
Victor Stinner370cb252013-10-12 01:33:54 +0200400 self.skipTest('os.statvfs() failed with ENOSYS')
401
Serhiy Storchakabad12572014-12-15 14:03:42 +0200402 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
403 p = pickle.dumps(result, proto)
404 self.assertIn(b'statvfs_result', p)
405 if proto < 4:
406 self.assertIn(b'cos\nstatvfs_result\n', p)
407 unpickled = pickle.loads(p)
408 self.assertEqual(result, unpickled)
Christian Heimes25827622013-10-12 01:27:08 +0200409
Serhiy Storchaka43767632013-11-03 21:31:38 +0200410 @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
411 def test_1686475(self):
412 # Verify that an open file can be stat'ed
413 try:
414 os.stat(r"c:\pagefile.sys")
415 except FileNotFoundError:
Zachary Ware101d9e72013-12-08 00:44:27 -0600416 self.skipTest(r'c:\pagefile.sys does not exist')
Serhiy Storchaka43767632013-11-03 21:31:38 +0200417 except OSError as e:
418 self.fail("Could not stat pagefile.sys")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000419
Serhiy Storchaka43767632013-11-03 21:31:38 +0200420 @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
421 @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
422 def test_15261(self):
423 # Verify that stat'ing a closed fd does not cause crash
424 r, w = os.pipe()
425 try:
426 os.stat(r) # should not raise error
427 finally:
428 os.close(r)
429 os.close(w)
430 with self.assertRaises(OSError) as ctx:
431 os.stat(r)
432 self.assertEqual(ctx.exception.errno, errno.EBADF)
Richard Oudkerk2240ac12012-07-06 12:05:32 +0100433
Zachary Ware63f277b2014-06-19 09:46:37 -0500434 def check_file_attributes(self, result):
435 self.assertTrue(hasattr(result, 'st_file_attributes'))
436 self.assertTrue(isinstance(result.st_file_attributes, int))
437 self.assertTrue(0 <= result.st_file_attributes <= 0xFFFFFFFF)
438
439 @unittest.skipUnless(sys.platform == "win32",
440 "st_file_attributes is Win32 specific")
441 def test_file_attributes(self):
442 # test file st_file_attributes (FILE_ATTRIBUTE_DIRECTORY not set)
443 result = os.stat(self.fname)
444 self.check_file_attributes(result)
445 self.assertEqual(
446 result.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY,
447 0)
448
449 # test directory st_file_attributes (FILE_ATTRIBUTE_DIRECTORY set)
Victor Stinner47aacc82015-06-12 17:26:23 +0200450 dirname = support.TESTFN + "dir"
451 os.mkdir(dirname)
452 self.addCleanup(os.rmdir, dirname)
453
454 result = os.stat(dirname)
Zachary Ware63f277b2014-06-19 09:46:37 -0500455 self.check_file_attributes(result)
456 self.assertEqual(
457 result.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY,
458 stat.FILE_ATTRIBUTE_DIRECTORY)
459
Berker Peksag0b4dc482016-09-17 15:49:59 +0300460 @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
461 def test_access_denied(self):
462 # Default to FindFirstFile WIN32_FIND_DATA when access is
463 # denied. See issue 28075.
464 # os.environ['TEMP'] should be located on a volume that
465 # supports file ACLs.
466 fname = os.path.join(os.environ['TEMP'], self.fname)
467 self.addCleanup(support.unlink, fname)
468 create_file(fname, b'ABC')
469 # Deny the right to [S]YNCHRONIZE on the file to
470 # force CreateFile to fail with ERROR_ACCESS_DENIED.
471 DETACHED_PROCESS = 8
472 subprocess.check_call(
Denis Osipov897bba72017-06-07 22:15:26 +0500473 # bpo-30584: Use security identifier *S-1-5-32-545 instead
474 # of localized "Users" to not depend on the locale.
475 ['icacls.exe', fname, '/deny', '*S-1-5-32-545:(S)'],
Berker Peksag0b4dc482016-09-17 15:49:59 +0300476 creationflags=DETACHED_PROCESS
477 )
478 result = os.stat(fname)
479 self.assertNotEqual(result.st_size, 0)
480
Victor Stinner47aacc82015-06-12 17:26:23 +0200481
482class UtimeTests(unittest.TestCase):
483 def setUp(self):
484 self.dirname = support.TESTFN
485 self.fname = os.path.join(self.dirname, "f1")
486
487 self.addCleanup(support.rmtree, self.dirname)
488 os.mkdir(self.dirname)
Victor Stinnerae39d232016-03-24 17:12:55 +0100489 create_file(self.fname)
Victor Stinner47aacc82015-06-12 17:26:23 +0200490
Victor Stinnerc0b1e0f2015-07-20 17:12:57 +0200491 def restore_float_times(state):
Victor Stinner923590e2016-03-24 09:11:48 +0100492 with ignore_deprecation_warnings('stat_float_times'):
Victor Stinnerc0b1e0f2015-07-20 17:12:57 +0200493 os.stat_float_times(state)
494
Victor Stinner47aacc82015-06-12 17:26:23 +0200495 # ensure that st_atime and st_mtime are float
Victor Stinner923590e2016-03-24 09:11:48 +0100496 with ignore_deprecation_warnings('stat_float_times'):
Victor Stinnerc0b1e0f2015-07-20 17:12:57 +0200497 old_float_times = os.stat_float_times(-1)
498 self.addCleanup(restore_float_times, old_float_times)
Victor Stinner47aacc82015-06-12 17:26:23 +0200499
500 os.stat_float_times(True)
501
502 def support_subsecond(self, filename):
503 # Heuristic to check if the filesystem supports timestamp with
504 # subsecond resolution: check if float and int timestamps are different
505 st = os.stat(filename)
506 return ((st.st_atime != st[7])
507 or (st.st_mtime != st[8])
508 or (st.st_ctime != st[9]))
509
510 def _test_utime(self, set_time, filename=None):
511 if not filename:
512 filename = self.fname
513
514 support_subsecond = self.support_subsecond(filename)
515 if support_subsecond:
516 # Timestamp with a resolution of 1 microsecond (10^-6).
517 #
518 # The resolution of the C internal function used by os.utime()
519 # depends on the platform: 1 sec, 1 us, 1 ns. Writing a portable
520 # test with a resolution of 1 ns requires more work:
521 # see the issue #15745.
522 atime_ns = 1002003000 # 1.002003 seconds
523 mtime_ns = 4005006000 # 4.005006 seconds
524 else:
525 # use a resolution of 1 second
526 atime_ns = 5 * 10**9
527 mtime_ns = 8 * 10**9
528
529 set_time(filename, (atime_ns, mtime_ns))
530 st = os.stat(filename)
531
532 if support_subsecond:
533 self.assertAlmostEqual(st.st_atime, atime_ns * 1e-9, delta=1e-6)
534 self.assertAlmostEqual(st.st_mtime, mtime_ns * 1e-9, delta=1e-6)
535 else:
536 self.assertEqual(st.st_atime, atime_ns * 1e-9)
537 self.assertEqual(st.st_mtime, mtime_ns * 1e-9)
538 self.assertEqual(st.st_atime_ns, atime_ns)
539 self.assertEqual(st.st_mtime_ns, mtime_ns)
540
541 def test_utime(self):
542 def set_time(filename, ns):
543 # test the ns keyword parameter
544 os.utime(filename, ns=ns)
545 self._test_utime(set_time)
546
547 @staticmethod
548 def ns_to_sec(ns):
549 # Convert a number of nanosecond (int) to a number of seconds (float).
550 # Round towards infinity by adding 0.5 nanosecond to avoid rounding
551 # issue, os.utime() rounds towards minus infinity.
552 return (ns * 1e-9) + 0.5e-9
553
554 def test_utime_by_indexed(self):
555 # pass times as floating point seconds as the second indexed parameter
556 def set_time(filename, ns):
557 atime_ns, mtime_ns = ns
558 atime = self.ns_to_sec(atime_ns)
559 mtime = self.ns_to_sec(mtime_ns)
560 # test utimensat(timespec), utimes(timeval), utime(utimbuf)
561 # or utime(time_t)
562 os.utime(filename, (atime, mtime))
563 self._test_utime(set_time)
564
565 def test_utime_by_times(self):
566 def set_time(filename, ns):
567 atime_ns, mtime_ns = ns
568 atime = self.ns_to_sec(atime_ns)
569 mtime = self.ns_to_sec(mtime_ns)
570 # test the times keyword parameter
571 os.utime(filename, times=(atime, mtime))
572 self._test_utime(set_time)
573
574 @unittest.skipUnless(os.utime in os.supports_follow_symlinks,
575 "follow_symlinks support for utime required "
576 "for this test.")
577 def test_utime_nofollow_symlinks(self):
578 def set_time(filename, ns):
579 # use follow_symlinks=False to test utimensat(timespec)
580 # or lutimes(timeval)
581 os.utime(filename, ns=ns, follow_symlinks=False)
582 self._test_utime(set_time)
583
584 @unittest.skipUnless(os.utime in os.supports_fd,
585 "fd support for utime required for this test.")
586 def test_utime_fd(self):
587 def set_time(filename, ns):
Victor Stinnerae39d232016-03-24 17:12:55 +0100588 with open(filename, 'wb', 0) as fp:
Victor Stinner47aacc82015-06-12 17:26:23 +0200589 # use a file descriptor to test futimens(timespec)
590 # or futimes(timeval)
591 os.utime(fp.fileno(), ns=ns)
592 self._test_utime(set_time)
593
594 @unittest.skipUnless(os.utime in os.supports_dir_fd,
595 "dir_fd support for utime required for this test.")
596 def test_utime_dir_fd(self):
597 def set_time(filename, ns):
598 dirname, name = os.path.split(filename)
599 dirfd = os.open(dirname, os.O_RDONLY)
600 try:
601 # pass dir_fd to test utimensat(timespec) or futimesat(timeval)
602 os.utime(name, dir_fd=dirfd, ns=ns)
603 finally:
604 os.close(dirfd)
605 self._test_utime(set_time)
606
607 def test_utime_directory(self):
608 def set_time(filename, ns):
609 # test calling os.utime() on a directory
610 os.utime(filename, ns=ns)
611 self._test_utime(set_time, filename=self.dirname)
612
613 def _test_utime_current(self, set_time):
614 # Get the system clock
615 current = time.time()
616
617 # Call os.utime() to set the timestamp to the current system clock
618 set_time(self.fname)
619
620 if not self.support_subsecond(self.fname):
621 delta = 1.0
Victor Stinnera8e7d902017-09-18 08:49:45 -0700622 else:
Victor Stinnerc94caca2017-06-13 23:48:27 +0200623 # On Windows, the usual resolution of time.time() is 15.6 ms.
624 # bpo-30649: Tolerate 50 ms for slow Windows buildbots.
Victor Stinnera8e7d902017-09-18 08:49:45 -0700625 #
626 # x86 Gentoo Refleaks 3.x once failed with dt=20.2 ms. So use
627 # also 50 ms on other platforms.
Victor Stinnerc94caca2017-06-13 23:48:27 +0200628 delta = 0.050
Victor Stinner47aacc82015-06-12 17:26:23 +0200629 st = os.stat(self.fname)
630 msg = ("st_time=%r, current=%r, dt=%r"
631 % (st.st_mtime, current, st.st_mtime - current))
632 self.assertAlmostEqual(st.st_mtime, current,
633 delta=delta, msg=msg)
634
635 def test_utime_current(self):
636 def set_time(filename):
637 # Set to the current time in the new way
638 os.utime(self.fname)
639 self._test_utime_current(set_time)
640
641 def test_utime_current_old(self):
642 def set_time(filename):
643 # Set to the current time in the old explicit way.
644 os.utime(self.fname, None)
645 self._test_utime_current(set_time)
646
647 def get_file_system(self, path):
648 if sys.platform == 'win32':
649 root = os.path.splitdrive(os.path.abspath(path))[0] + '\\'
650 import ctypes
651 kernel32 = ctypes.windll.kernel32
652 buf = ctypes.create_unicode_buffer("", 100)
653 ok = kernel32.GetVolumeInformationW(root, None, 0,
654 None, None, None,
655 buf, len(buf))
656 if ok:
657 return buf.value
658 # return None if the filesystem is unknown
659
660 def test_large_time(self):
661 # Many filesystems are limited to the year 2038. At least, the test
662 # pass with NTFS filesystem.
663 if self.get_file_system(self.dirname) != "NTFS":
664 self.skipTest("requires NTFS")
665
666 large = 5000000000 # some day in 2128
667 os.utime(self.fname, (large, large))
668 self.assertEqual(os.stat(self.fname).st_mtime, large)
669
670 def test_utime_invalid_arguments(self):
671 # seconds and nanoseconds parameters are mutually exclusive
672 with self.assertRaises(ValueError):
673 os.utime(self.fname, (5, 5), ns=(5, 5))
674
675
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000676from test import mapping_tests
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000677
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000678class EnvironTests(mapping_tests.BasicTestMappingProtocol):
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000679 """check that os.environ object conform to mapping protocol"""
Walter Dörwald118f9312004-06-02 18:42:25 +0000680 type2test = None
Christian Heimes90333392007-11-01 19:08:42 +0000681
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000682 def setUp(self):
683 self.__save = dict(os.environ)
Victor Stinnerb745a742010-05-18 17:17:23 +0000684 if os.supports_bytes_environ:
Victor Stinner208d28c2010-05-07 00:54:14 +0000685 self.__saveb = dict(os.environb)
Christian Heimes90333392007-11-01 19:08:42 +0000686 for key, value in self._reference().items():
687 os.environ[key] = value
688
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000689 def tearDown(self):
690 os.environ.clear()
691 os.environ.update(self.__save)
Victor Stinnerb745a742010-05-18 17:17:23 +0000692 if os.supports_bytes_environ:
Victor Stinner208d28c2010-05-07 00:54:14 +0000693 os.environb.clear()
694 os.environb.update(self.__saveb)
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000695
Christian Heimes90333392007-11-01 19:08:42 +0000696 def _reference(self):
697 return {"KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3"}
698
699 def _empty_mapping(self):
700 os.environ.clear()
701 return os.environ
702
Martin v. Löwis1d11de62005-01-29 13:29:23 +0000703 # Bug 1110478
Xavier de Gayed1415312016-07-22 12:15:29 +0200704 @unittest.skipUnless(unix_shell and os.path.exists(unix_shell),
705 'requires a shell')
Martin v. Löwis5510f652005-02-17 21:23:20 +0000706 def test_update2(self):
Christian Heimes90333392007-11-01 19:08:42 +0000707 os.environ.clear()
Ezio Melottic7e139b2012-09-26 20:01:34 +0300708 os.environ.update(HELLO="World")
Xavier de Gayed1415312016-07-22 12:15:29 +0200709 with os.popen("%s -c 'echo $HELLO'" % unix_shell) as popen:
Ezio Melottic7e139b2012-09-26 20:01:34 +0300710 value = popen.read().strip()
711 self.assertEqual(value, "World")
Martin v. Löwis1d11de62005-01-29 13:29:23 +0000712
Xavier de Gayed1415312016-07-22 12:15:29 +0200713 @unittest.skipUnless(unix_shell and os.path.exists(unix_shell),
714 'requires a shell')
Christian Heimes1a13d592007-11-08 14:16:55 +0000715 def test_os_popen_iter(self):
Xavier de Gayed1415312016-07-22 12:15:29 +0200716 with os.popen("%s -c 'echo \"line1\nline2\nline3\"'"
717 % unix_shell) as popen:
Ezio Melottic7e139b2012-09-26 20:01:34 +0300718 it = iter(popen)
719 self.assertEqual(next(it), "line1\n")
720 self.assertEqual(next(it), "line2\n")
721 self.assertEqual(next(it), "line3\n")
722 self.assertRaises(StopIteration, next, it)
Christian Heimes1a13d592007-11-08 14:16:55 +0000723
Guido van Rossum67aca9e2007-06-13 21:51:27 +0000724 # Verify environ keys and values from the OS are of the
725 # correct str type.
726 def test_keyvalue_types(self):
727 for key, val in os.environ.items():
Ezio Melottib3aedd42010-11-20 19:04:17 +0000728 self.assertEqual(type(key), str)
729 self.assertEqual(type(val), str)
Guido van Rossum67aca9e2007-06-13 21:51:27 +0000730
Christian Heimes90333392007-11-01 19:08:42 +0000731 def test_items(self):
732 for key, value in self._reference().items():
733 self.assertEqual(os.environ.get(key), value)
734
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000735 # Issue 7310
736 def test___repr__(self):
737 """Check that the repr() of os.environ looks like environ({...})."""
738 env = os.environ
Victor Stinner96f0de92010-07-29 00:29:00 +0000739 self.assertEqual(repr(env), 'environ({{{}}})'.format(', '.join(
740 '{!r}: {!r}'.format(key, value)
741 for key, value in env.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000742
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000743 def test_get_exec_path(self):
744 defpath_list = os.defpath.split(os.pathsep)
745 test_path = ['/monty', '/python', '', '/flying/circus']
746 test_env = {'PATH': os.pathsep.join(test_path)}
747
748 saved_environ = os.environ
749 try:
750 os.environ = dict(test_env)
751 # Test that defaulting to os.environ works.
752 self.assertSequenceEqual(test_path, os.get_exec_path())
753 self.assertSequenceEqual(test_path, os.get_exec_path(env=None))
754 finally:
755 os.environ = saved_environ
756
757 # No PATH environment variable
758 self.assertSequenceEqual(defpath_list, os.get_exec_path({}))
759 # Empty PATH environment variable
760 self.assertSequenceEqual(('',), os.get_exec_path({'PATH':''}))
761 # Supplied PATH environment variable
762 self.assertSequenceEqual(test_path, os.get_exec_path(test_env))
763
Victor Stinnerb745a742010-05-18 17:17:23 +0000764 if os.supports_bytes_environ:
765 # env cannot contain 'PATH' and b'PATH' keys
Victor Stinner38430e22010-08-19 17:10:18 +0000766 try:
Victor Stinner6f35eda2010-10-29 00:38:58 +0000767 # ignore BytesWarning warning
768 with warnings.catch_warnings(record=True):
769 mixed_env = {'PATH': '1', b'PATH': b'2'}
Victor Stinner38430e22010-08-19 17:10:18 +0000770 except BytesWarning:
Victor Stinner6f35eda2010-10-29 00:38:58 +0000771 # mixed_env cannot be created with python -bb
Victor Stinner38430e22010-08-19 17:10:18 +0000772 pass
773 else:
774 self.assertRaises(ValueError, os.get_exec_path, mixed_env)
Victor Stinnerb745a742010-05-18 17:17:23 +0000775
776 # bytes key and/or value
777 self.assertSequenceEqual(os.get_exec_path({b'PATH': b'abc'}),
778 ['abc'])
779 self.assertSequenceEqual(os.get_exec_path({b'PATH': 'abc'}),
780 ['abc'])
781 self.assertSequenceEqual(os.get_exec_path({'PATH': b'abc'}),
782 ['abc'])
783
784 @unittest.skipUnless(os.supports_bytes_environ,
785 "os.environb required for this test.")
Victor Stinner84ae1182010-05-06 22:05:07 +0000786 def test_environb(self):
787 # os.environ -> os.environb
788 value = 'euro\u20ac'
789 try:
Benjamin Peterson180799d2010-05-06 22:25:42 +0000790 value_bytes = value.encode(sys.getfilesystemencoding(),
791 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000792 except UnicodeEncodeError:
Benjamin Peterson180799d2010-05-06 22:25:42 +0000793 msg = "U+20AC character is not encodable to %s" % (
794 sys.getfilesystemencoding(),)
Benjamin Peterson932d3f42010-05-06 22:26:31 +0000795 self.skipTest(msg)
Victor Stinner84ae1182010-05-06 22:05:07 +0000796 os.environ['unicode'] = value
Ezio Melottib3aedd42010-11-20 19:04:17 +0000797 self.assertEqual(os.environ['unicode'], value)
798 self.assertEqual(os.environb[b'unicode'], value_bytes)
Victor Stinner84ae1182010-05-06 22:05:07 +0000799
800 # os.environb -> os.environ
801 value = b'\xff'
802 os.environb[b'bytes'] = value
Ezio Melottib3aedd42010-11-20 19:04:17 +0000803 self.assertEqual(os.environb[b'bytes'], value)
Victor Stinner84ae1182010-05-06 22:05:07 +0000804 value_str = value.decode(sys.getfilesystemencoding(), 'surrogateescape')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000805 self.assertEqual(os.environ['bytes'], value_str)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000806
Charles-François Natali2966f102011-11-26 11:32:46 +0100807 # On FreeBSD < 7 and OS X < 10.6, unsetenv() doesn't return a value (issue
808 # #13415).
809 @support.requires_freebsd_version(7)
810 @support.requires_mac_ver(10, 6)
Victor Stinner60b385e2011-11-22 22:01:28 +0100811 def test_unset_error(self):
812 if sys.platform == "win32":
813 # an environment variable is limited to 32,767 characters
814 key = 'x' * 50000
Victor Stinnerb3f82682011-11-22 22:30:19 +0100815 self.assertRaises(ValueError, os.environ.__delitem__, key)
Victor Stinner60b385e2011-11-22 22:01:28 +0100816 else:
817 # "=" is not allowed in a variable name
818 key = 'key='
Victor Stinnerb3f82682011-11-22 22:30:19 +0100819 self.assertRaises(OSError, os.environ.__delitem__, key)
Victor Stinner60b385e2011-11-22 22:01:28 +0100820
Victor Stinner6d101392013-04-14 16:35:04 +0200821 def test_key_type(self):
822 missing = 'missingkey'
823 self.assertNotIn(missing, os.environ)
824
Victor Stinner839e5ea2013-04-14 16:43:03 +0200825 with self.assertRaises(KeyError) as cm:
Victor Stinner6d101392013-04-14 16:35:04 +0200826 os.environ[missing]
Victor Stinner839e5ea2013-04-14 16:43:03 +0200827 self.assertIs(cm.exception.args[0], missing)
Victor Stinner0c2dd0c2013-08-23 19:19:15 +0200828 self.assertTrue(cm.exception.__suppress_context__)
Victor Stinner6d101392013-04-14 16:35:04 +0200829
Victor Stinner839e5ea2013-04-14 16:43:03 +0200830 with self.assertRaises(KeyError) as cm:
Victor Stinner6d101392013-04-14 16:35:04 +0200831 del os.environ[missing]
Victor Stinner839e5ea2013-04-14 16:43:03 +0200832 self.assertIs(cm.exception.args[0], missing)
Victor Stinner0c2dd0c2013-08-23 19:19:15 +0200833 self.assertTrue(cm.exception.__suppress_context__)
834
Osvaldo Santana Neto8a8d2852017-07-01 14:34:45 -0300835 def _test_environ_iteration(self, collection):
836 iterator = iter(collection)
837 new_key = "__new_key__"
838
839 next(iterator) # start iteration over os.environ.items
840
841 # add a new key in os.environ mapping
842 os.environ[new_key] = "test_environ_iteration"
843
844 try:
845 next(iterator) # force iteration over modified mapping
846 self.assertEqual(os.environ[new_key], "test_environ_iteration")
847 finally:
848 del os.environ[new_key]
849
850 def test_iter_error_when_changing_os_environ(self):
851 self._test_environ_iteration(os.environ)
852
853 def test_iter_error_when_changing_os_environ_items(self):
854 self._test_environ_iteration(os.environ.items())
855
856 def test_iter_error_when_changing_os_environ_values(self):
857 self._test_environ_iteration(os.environ.values())
858
Victor Stinner6d101392013-04-14 16:35:04 +0200859
Tim Petersc4e09402003-04-25 07:11:48 +0000860class WalkTests(unittest.TestCase):
861 """Tests for os.walk()."""
862
Victor Stinner0561c532015-03-12 10:28:24 +0100863 # Wrapper to hide minor differences between os.walk and os.fwalk
864 # to tests both functions with the same code base
Serhiy Storchaka5f6a0b42016-02-08 16:23:28 +0200865 def walk(self, top, **kwargs):
Serhiy Storchakaa17ca192015-12-23 00:37:34 +0200866 if 'follow_symlinks' in kwargs:
867 kwargs['followlinks'] = kwargs.pop('follow_symlinks')
Serhiy Storchaka5f6a0b42016-02-08 16:23:28 +0200868 return os.walk(top, **kwargs)
Victor Stinner0561c532015-03-12 10:28:24 +0100869
Charles-François Natali7372b062012-02-05 15:15:38 +0100870 def setUp(self):
Victor Stinner0561c532015-03-12 10:28:24 +0100871 join = os.path.join
Victor Stinner3899b542016-03-24 17:21:17 +0100872 self.addCleanup(support.rmtree, support.TESTFN)
Tim Petersc4e09402003-04-25 07:11:48 +0000873
874 # Build:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000875 # TESTFN/
876 # TEST1/ a file kid and two directory kids
Tim Petersc4e09402003-04-25 07:11:48 +0000877 # tmp1
878 # SUB1/ a file kid and a directory kid
Guido van Rossumd8faa362007-04-27 19:54:29 +0000879 # tmp2
880 # SUB11/ no kids
881 # SUB2/ a file kid and a dirsymlink kid
882 # tmp3
Serhiy Storchaka42babab2016-10-25 14:28:38 +0300883 # SUB21/ not readable
884 # tmp5
Guido van Rossumd8faa362007-04-27 19:54:29 +0000885 # link/ a symlink to TESTFN.2
Hynek Schlawack66bfcc12012-05-15 16:32:21 +0200886 # broken_link
Serhiy Storchaka42babab2016-10-25 14:28:38 +0300887 # broken_link2
888 # broken_link3
Guido van Rossumd8faa362007-04-27 19:54:29 +0000889 # TEST2/
890 # tmp4 a lone file
Victor Stinner0561c532015-03-12 10:28:24 +0100891 self.walk_path = join(support.TESTFN, "TEST1")
892 self.sub1_path = join(self.walk_path, "SUB1")
893 self.sub11_path = join(self.sub1_path, "SUB11")
894 sub2_path = join(self.walk_path, "SUB2")
Serhiy Storchakaaf4e4742016-10-25 14:34:38 +0300895 sub21_path = join(sub2_path, "SUB21")
Victor Stinner0561c532015-03-12 10:28:24 +0100896 tmp1_path = join(self.walk_path, "tmp1")
897 tmp2_path = join(self.sub1_path, "tmp2")
Tim Petersc4e09402003-04-25 07:11:48 +0000898 tmp3_path = join(sub2_path, "tmp3")
Serhiy Storchakaaf4e4742016-10-25 14:34:38 +0300899 tmp5_path = join(sub21_path, "tmp3")
Victor Stinner0561c532015-03-12 10:28:24 +0100900 self.link_path = join(sub2_path, "link")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000901 t2_path = join(support.TESTFN, "TEST2")
902 tmp4_path = join(support.TESTFN, "TEST2", "tmp4")
Hynek Schlawack66bfcc12012-05-15 16:32:21 +0200903 broken_link_path = join(sub2_path, "broken_link")
Serhiy Storchaka42babab2016-10-25 14:28:38 +0300904 broken_link2_path = join(sub2_path, "broken_link2")
905 broken_link3_path = join(sub2_path, "broken_link3")
Tim Petersc4e09402003-04-25 07:11:48 +0000906
907 # Create stuff.
Victor Stinner0561c532015-03-12 10:28:24 +0100908 os.makedirs(self.sub11_path)
Tim Petersc4e09402003-04-25 07:11:48 +0000909 os.makedirs(sub2_path)
Serhiy Storchakaaf4e4742016-10-25 14:34:38 +0300910 os.makedirs(sub21_path)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000911 os.makedirs(t2_path)
Victor Stinner0561c532015-03-12 10:28:24 +0100912
Serhiy Storchaka42babab2016-10-25 14:28:38 +0300913 for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path, tmp5_path:
Victor Stinnere77c9742016-03-25 10:28:23 +0100914 with open(path, "x") as f:
915 f.write("I'm " + path + " and proud of it. Blame test_os.\n")
Tim Petersc4e09402003-04-25 07:11:48 +0000916
Victor Stinner0561c532015-03-12 10:28:24 +0100917 if support.can_symlink():
918 os.symlink(os.path.abspath(t2_path), self.link_path)
919 os.symlink('broken', broken_link_path, True)
Serhiy Storchaka42babab2016-10-25 14:28:38 +0300920 os.symlink(join('tmp3', 'broken'), broken_link2_path, True)
921 os.symlink(join('SUB21', 'tmp5'), broken_link3_path, True)
Serhiy Storchaka28f98202016-10-25 19:01:41 +0300922 self.sub2_tree = (sub2_path, ["SUB21", "link"],
Serhiy Storchaka42babab2016-10-25 14:28:38 +0300923 ["broken_link", "broken_link2", "broken_link3",
924 "tmp3"])
Victor Stinner0561c532015-03-12 10:28:24 +0100925 else:
926 self.sub2_tree = (sub2_path, [], ["tmp3"])
927
Serhiy Storchakaaf4e4742016-10-25 14:34:38 +0300928 os.chmod(sub21_path, 0)
Serhiy Storchaka28f98202016-10-25 19:01:41 +0300929 try:
930 os.listdir(sub21_path)
931 except PermissionError:
932 self.addCleanup(os.chmod, sub21_path, stat.S_IRWXU)
933 else:
934 os.chmod(sub21_path, stat.S_IRWXU)
935 os.unlink(tmp5_path)
936 os.rmdir(sub21_path)
937 del self.sub2_tree[1][:1]
Serhiy Storchaka42babab2016-10-25 14:28:38 +0300938
Victor Stinner0561c532015-03-12 10:28:24 +0100939 def test_walk_topdown(self):
Tim Petersc4e09402003-04-25 07:11:48 +0000940 # Walk top-down.
Serhiy Storchakaa07ab292016-04-16 17:51:00 +0300941 all = list(self.walk(self.walk_path))
Victor Stinner0561c532015-03-12 10:28:24 +0100942
Tim Petersc4e09402003-04-25 07:11:48 +0000943 self.assertEqual(len(all), 4)
944 # We can't know which order SUB1 and SUB2 will appear in.
945 # Not flipped: TESTFN, SUB1, SUB11, SUB2
946 # flipped: TESTFN, SUB2, SUB1, SUB11
947 flipped = all[0][1][0] != "SUB1"
948 all[0][1].sort()
Hynek Schlawackc96f5a02012-05-15 17:55:38 +0200949 all[3 - 2 * flipped][-1].sort()
Serhiy Storchaka28f98202016-10-25 19:01:41 +0300950 all[3 - 2 * flipped][1].sort()
Victor Stinner0561c532015-03-12 10:28:24 +0100951 self.assertEqual(all[0], (self.walk_path, ["SUB1", "SUB2"], ["tmp1"]))
952 self.assertEqual(all[1 + flipped], (self.sub1_path, ["SUB11"], ["tmp2"]))
953 self.assertEqual(all[2 + flipped], (self.sub11_path, [], []))
954 self.assertEqual(all[3 - 2 * flipped], self.sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000955
Brett Cannon3f9183b2016-08-26 14:44:48 -0700956 def test_walk_prune(self, walk_path=None):
957 if walk_path is None:
958 walk_path = self.walk_path
Tim Petersc4e09402003-04-25 07:11:48 +0000959 # Prune the search.
960 all = []
Brett Cannon3f9183b2016-08-26 14:44:48 -0700961 for root, dirs, files in self.walk(walk_path):
Tim Petersc4e09402003-04-25 07:11:48 +0000962 all.append((root, dirs, files))
963 # Don't descend into SUB1.
964 if 'SUB1' in dirs:
965 # Note that this also mutates the dirs we appended to all!
966 dirs.remove('SUB1')
Tim Petersc4e09402003-04-25 07:11:48 +0000967
Victor Stinner0561c532015-03-12 10:28:24 +0100968 self.assertEqual(len(all), 2)
969 self.assertEqual(all[0],
Brett Cannon3f9183b2016-08-26 14:44:48 -0700970 (str(walk_path), ["SUB2"], ["tmp1"]))
Victor Stinner0561c532015-03-12 10:28:24 +0100971
972 all[1][-1].sort()
Serhiy Storchaka28f98202016-10-25 19:01:41 +0300973 all[1][1].sort()
Victor Stinner0561c532015-03-12 10:28:24 +0100974 self.assertEqual(all[1], self.sub2_tree)
975
Brett Cannon3f9183b2016-08-26 14:44:48 -0700976 def test_file_like_path(self):
Brett Cannonec6ce872016-09-06 15:50:29 -0700977 self.test_walk_prune(_PathLike(self.walk_path))
Brett Cannon3f9183b2016-08-26 14:44:48 -0700978
Victor Stinner0561c532015-03-12 10:28:24 +0100979 def test_walk_bottom_up(self):
Tim Petersc4e09402003-04-25 07:11:48 +0000980 # Walk bottom-up.
Victor Stinner0561c532015-03-12 10:28:24 +0100981 all = list(self.walk(self.walk_path, topdown=False))
982
Victor Stinner53b0a412016-03-26 01:12:36 +0100983 self.assertEqual(len(all), 4, all)
Tim Petersc4e09402003-04-25 07:11:48 +0000984 # We can't know which order SUB1 and SUB2 will appear in.
985 # Not flipped: SUB11, SUB1, SUB2, TESTFN
986 # flipped: SUB2, SUB11, SUB1, TESTFN
987 flipped = all[3][1][0] != "SUB1"
988 all[3][1].sort()
Hynek Schlawack39bf90d2012-05-15 18:40:17 +0200989 all[2 - 2 * flipped][-1].sort()
Serhiy Storchaka28f98202016-10-25 19:01:41 +0300990 all[2 - 2 * flipped][1].sort()
Victor Stinner0561c532015-03-12 10:28:24 +0100991 self.assertEqual(all[3],
992 (self.walk_path, ["SUB1", "SUB2"], ["tmp1"]))
993 self.assertEqual(all[flipped],
994 (self.sub11_path, [], []))
995 self.assertEqual(all[flipped + 1],
996 (self.sub1_path, ["SUB11"], ["tmp2"]))
997 self.assertEqual(all[2 - 2 * flipped],
998 self.sub2_tree)
Tim Petersc4e09402003-04-25 07:11:48 +0000999
Victor Stinner0561c532015-03-12 10:28:24 +01001000 def test_walk_symlink(self):
1001 if not support.can_symlink():
1002 self.skipTest("need symlink support")
1003
1004 # Walk, following symlinks.
1005 walk_it = self.walk(self.walk_path, follow_symlinks=True)
1006 for root, dirs, files in walk_it:
1007 if root == self.link_path:
1008 self.assertEqual(dirs, [])
1009 self.assertEqual(files, ["tmp4"])
1010 break
1011 else:
1012 self.fail("Didn't follow symlink with followlinks=True")
Guido van Rossumd8faa362007-04-27 19:54:29 +00001013
Serhiy Storchaka0bddc9e2015-12-23 00:08:24 +02001014 def test_walk_bad_dir(self):
1015 # Walk top-down.
1016 errors = []
1017 walk_it = self.walk(self.walk_path, onerror=errors.append)
1018 root, dirs, files = next(walk_it)
Serhiy Storchaka7865dff2016-10-28 09:17:38 +03001019 self.assertEqual(errors, [])
1020 dir1 = 'SUB1'
1021 path1 = os.path.join(root, dir1)
1022 path1new = os.path.join(root, dir1 + '.new')
1023 os.rename(path1, path1new)
1024 try:
1025 roots = [r for r, d, f in walk_it]
1026 self.assertTrue(errors)
1027 self.assertNotIn(path1, roots)
1028 self.assertNotIn(path1new, roots)
1029 for dir2 in dirs:
1030 if dir2 != dir1:
1031 self.assertIn(os.path.join(root, dir2), roots)
1032 finally:
1033 os.rename(path1new, path1)
Serhiy Storchaka0bddc9e2015-12-23 00:08:24 +02001034
Charles-François Natali7372b062012-02-05 15:15:38 +01001035
1036@unittest.skipUnless(hasattr(os, 'fwalk'), "Test needs os.fwalk()")
1037class FwalkTests(WalkTests):
1038 """Tests for os.fwalk()."""
1039
Serhiy Storchaka5f6a0b42016-02-08 16:23:28 +02001040 def walk(self, top, **kwargs):
Serhiy Storchaka8f6b3442017-03-07 14:33:21 +02001041 for root, dirs, files, root_fd in self.fwalk(top, **kwargs):
Victor Stinner0561c532015-03-12 10:28:24 +01001042 yield (root, dirs, files)
1043
Serhiy Storchaka8f6b3442017-03-07 14:33:21 +02001044 def fwalk(self, *args, **kwargs):
1045 return os.fwalk(*args, **kwargs)
1046
Larry Hastingsc48fe982012-06-25 04:49:05 -07001047 def _compare_to_walk(self, walk_kwargs, fwalk_kwargs):
1048 """
1049 compare with walk() results.
1050 """
Larry Hastingsb4038062012-07-15 10:57:38 -07001051 walk_kwargs = walk_kwargs.copy()
1052 fwalk_kwargs = fwalk_kwargs.copy()
1053 for topdown, follow_symlinks in itertools.product((True, False), repeat=2):
1054 walk_kwargs.update(topdown=topdown, followlinks=follow_symlinks)
1055 fwalk_kwargs.update(topdown=topdown, follow_symlinks=follow_symlinks)
Larry Hastingsc48fe982012-06-25 04:49:05 -07001056
Charles-François Natali7372b062012-02-05 15:15:38 +01001057 expected = {}
Larry Hastingsc48fe982012-06-25 04:49:05 -07001058 for root, dirs, files in os.walk(**walk_kwargs):
Charles-François Natali7372b062012-02-05 15:15:38 +01001059 expected[root] = (set(dirs), set(files))
1060
Serhiy Storchaka8f6b3442017-03-07 14:33:21 +02001061 for root, dirs, files, rootfd in self.fwalk(**fwalk_kwargs):
Charles-François Natali7372b062012-02-05 15:15:38 +01001062 self.assertIn(root, expected)
1063 self.assertEqual(expected[root], (set(dirs), set(files)))
1064
Larry Hastingsc48fe982012-06-25 04:49:05 -07001065 def test_compare_to_walk(self):
1066 kwargs = {'top': support.TESTFN}
1067 self._compare_to_walk(kwargs, kwargs)
1068
Charles-François Natali7372b062012-02-05 15:15:38 +01001069 def test_dir_fd(self):
Larry Hastingsc48fe982012-06-25 04:49:05 -07001070 try:
1071 fd = os.open(".", os.O_RDONLY)
1072 walk_kwargs = {'top': support.TESTFN}
1073 fwalk_kwargs = walk_kwargs.copy()
1074 fwalk_kwargs['dir_fd'] = fd
1075 self._compare_to_walk(walk_kwargs, fwalk_kwargs)
1076 finally:
1077 os.close(fd)
1078
1079 def test_yields_correct_dir_fd(self):
Charles-François Natali7372b062012-02-05 15:15:38 +01001080 # check returned file descriptors
Larry Hastingsb4038062012-07-15 10:57:38 -07001081 for topdown, follow_symlinks in itertools.product((True, False), repeat=2):
1082 args = support.TESTFN, topdown, None
Serhiy Storchaka8f6b3442017-03-07 14:33:21 +02001083 for root, dirs, files, rootfd in self.fwalk(*args, follow_symlinks=follow_symlinks):
Charles-François Natali7372b062012-02-05 15:15:38 +01001084 # check that the FD is valid
1085 os.fstat(rootfd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001086 # redundant check
1087 os.stat(rootfd)
1088 # check that listdir() returns consistent information
1089 self.assertEqual(set(os.listdir(rootfd)), set(dirs) | set(files))
Charles-François Natali7372b062012-02-05 15:15:38 +01001090
1091 def test_fd_leak(self):
1092 # Since we're opening a lot of FDs, we must be careful to avoid leaks:
1093 # we both check that calling fwalk() a large number of times doesn't
1094 # yield EMFILE, and that the minimum allocated FD hasn't changed.
1095 minfd = os.dup(1)
1096 os.close(minfd)
1097 for i in range(256):
Serhiy Storchaka8f6b3442017-03-07 14:33:21 +02001098 for x in self.fwalk(support.TESTFN):
Charles-François Natali7372b062012-02-05 15:15:38 +01001099 pass
1100 newfd = os.dup(1)
1101 self.addCleanup(os.close, newfd)
1102 self.assertEqual(newfd, minfd)
1103
Serhiy Storchaka5f6a0b42016-02-08 16:23:28 +02001104class BytesWalkTests(WalkTests):
1105 """Tests for os.walk() with bytes."""
1106 def walk(self, top, **kwargs):
1107 if 'follow_symlinks' in kwargs:
1108 kwargs['followlinks'] = kwargs.pop('follow_symlinks')
1109 for broot, bdirs, bfiles in os.walk(os.fsencode(top), **kwargs):
1110 root = os.fsdecode(broot)
1111 dirs = list(map(os.fsdecode, bdirs))
1112 files = list(map(os.fsdecode, bfiles))
1113 yield (root, dirs, files)
1114 bdirs[:] = list(map(os.fsencode, dirs))
1115 bfiles[:] = list(map(os.fsencode, files))
1116
Serhiy Storchaka8f6b3442017-03-07 14:33:21 +02001117@unittest.skipUnless(hasattr(os, 'fwalk'), "Test needs os.fwalk()")
1118class BytesFwalkTests(FwalkTests):
1119 """Tests for os.walk() with bytes."""
1120 def fwalk(self, top='.', *args, **kwargs):
1121 for broot, bdirs, bfiles, topfd in os.fwalk(os.fsencode(top), *args, **kwargs):
1122 root = os.fsdecode(broot)
1123 dirs = list(map(os.fsdecode, bdirs))
1124 files = list(map(os.fsdecode, bfiles))
1125 yield (root, dirs, files, topfd)
1126 bdirs[:] = list(map(os.fsencode, dirs))
1127 bfiles[:] = list(map(os.fsencode, files))
1128
Charles-François Natali7372b062012-02-05 15:15:38 +01001129
Guido van Rossume7ba4952007-06-06 23:52:48 +00001130class MakedirTests(unittest.TestCase):
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001131 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001132 os.mkdir(support.TESTFN)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001133
1134 def test_makedir(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001135 base = support.TESTFN
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001136 path = os.path.join(base, 'dir1', 'dir2', 'dir3')
1137 os.makedirs(path) # Should work
1138 path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4')
1139 os.makedirs(path)
1140
1141 # Try paths with a '.' in them
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001142 self.assertRaises(OSError, os.makedirs, os.curdir)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001143 path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir)
1144 os.makedirs(path)
1145 path = os.path.join(base, 'dir1', os.curdir, 'dir2', 'dir3', 'dir4',
1146 'dir5', 'dir6')
1147 os.makedirs(path)
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001148
Serhiy Storchakae304e332017-03-24 13:27:42 +02001149 def test_mode(self):
1150 with support.temp_umask(0o002):
1151 base = support.TESTFN
1152 parent = os.path.join(base, 'dir1')
1153 path = os.path.join(parent, 'dir2')
1154 os.makedirs(path, 0o555)
1155 self.assertTrue(os.path.exists(path))
1156 self.assertTrue(os.path.isdir(path))
1157 if os.name != 'nt':
1158 self.assertEqual(stat.S_IMODE(os.stat(path).st_mode), 0o555)
1159 self.assertEqual(stat.S_IMODE(os.stat(parent).st_mode), 0o775)
1160
Terry Reedy5a22b652010-12-02 07:05:56 +00001161 def test_exist_ok_existing_directory(self):
1162 path = os.path.join(support.TESTFN, 'dir1')
1163 mode = 0o777
1164 old_mask = os.umask(0o022)
1165 os.makedirs(path, mode)
1166 self.assertRaises(OSError, os.makedirs, path, mode)
1167 self.assertRaises(OSError, os.makedirs, path, mode, exist_ok=False)
Benjamin Peterson4717e212014-04-01 19:17:57 -04001168 os.makedirs(path, 0o776, exist_ok=True)
Terry Reedy5a22b652010-12-02 07:05:56 +00001169 os.makedirs(path, mode=mode, exist_ok=True)
1170 os.umask(old_mask)
1171
Martin Pantera82642f2015-11-19 04:48:44 +00001172 # Issue #25583: A drive root could raise PermissionError on Windows
1173 os.makedirs(os.path.abspath('/'), exist_ok=True)
1174
Gregory P. Smitha81c8562012-06-03 14:30:44 -07001175 def test_exist_ok_s_isgid_directory(self):
1176 path = os.path.join(support.TESTFN, 'dir1')
1177 S_ISGID = stat.S_ISGID
1178 mode = 0o777
1179 old_mask = os.umask(0o022)
1180 try:
1181 existing_testfn_mode = stat.S_IMODE(
1182 os.lstat(support.TESTFN).st_mode)
Ned Deilyc622f422012-08-08 20:57:24 -07001183 try:
1184 os.chmod(support.TESTFN, existing_testfn_mode | S_ISGID)
Ned Deily3a2b97e2012-08-08 21:03:02 -07001185 except PermissionError:
Ned Deilyc622f422012-08-08 20:57:24 -07001186 raise unittest.SkipTest('Cannot set S_ISGID for dir.')
Gregory P. Smitha81c8562012-06-03 14:30:44 -07001187 if (os.lstat(support.TESTFN).st_mode & S_ISGID != S_ISGID):
1188 raise unittest.SkipTest('No support for S_ISGID dir mode.')
1189 # The os should apply S_ISGID from the parent dir for us, but
1190 # this test need not depend on that behavior. Be explicit.
1191 os.makedirs(path, mode | S_ISGID)
1192 # http://bugs.python.org/issue14992
1193 # Should not fail when the bit is already set.
1194 os.makedirs(path, mode, exist_ok=True)
1195 # remove the bit.
1196 os.chmod(path, stat.S_IMODE(os.lstat(path).st_mode) & ~S_ISGID)
Benjamin Petersonee5f1c12014-04-01 19:13:18 -04001197 # May work even when the bit is not already set when demanded.
1198 os.makedirs(path, mode | S_ISGID, exist_ok=True)
Gregory P. Smitha81c8562012-06-03 14:30:44 -07001199 finally:
1200 os.umask(old_mask)
Terry Reedy5a22b652010-12-02 07:05:56 +00001201
1202 def test_exist_ok_existing_regular_file(self):
1203 base = support.TESTFN
1204 path = os.path.join(support.TESTFN, 'dir1')
1205 f = open(path, 'w')
1206 f.write('abc')
1207 f.close()
1208 self.assertRaises(OSError, os.makedirs, path)
1209 self.assertRaises(OSError, os.makedirs, path, exist_ok=False)
1210 self.assertRaises(OSError, os.makedirs, path, exist_ok=True)
1211 os.remove(path)
1212
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001213 def tearDown(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001214 path = os.path.join(support.TESTFN, 'dir1', 'dir2', 'dir3',
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001215 'dir4', 'dir5', 'dir6')
1216 # If the tests failed, the bottom-most directory ('../dir6')
1217 # may not have been created, so we look for the outermost directory
1218 # that exists.
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001219 while not os.path.exists(path) and path != support.TESTFN:
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001220 path = os.path.dirname(path)
1221
1222 os.removedirs(path)
1223
Andrew Svetlov405faed2012-12-25 12:18:09 +02001224
R David Murrayf2ad1732014-12-25 18:36:56 -05001225@unittest.skipUnless(hasattr(os, 'chown'), "Test needs chown")
1226class ChownFileTests(unittest.TestCase):
1227
Berker Peksag036a71b2015-07-21 09:29:48 +03001228 @classmethod
1229 def setUpClass(cls):
R David Murrayf2ad1732014-12-25 18:36:56 -05001230 os.mkdir(support.TESTFN)
1231
1232 def test_chown_uid_gid_arguments_must_be_index(self):
1233 stat = os.stat(support.TESTFN)
1234 uid = stat.st_uid
1235 gid = stat.st_gid
1236 for value in (-1.0, -1j, decimal.Decimal(-1), fractions.Fraction(-2, 2)):
1237 self.assertRaises(TypeError, os.chown, support.TESTFN, value, gid)
1238 self.assertRaises(TypeError, os.chown, support.TESTFN, uid, value)
1239 self.assertIsNone(os.chown(support.TESTFN, uid, gid))
1240 self.assertIsNone(os.chown(support.TESTFN, -1, -1))
1241
1242 @unittest.skipUnless(len(groups) > 1, "test needs more than one group")
1243 def test_chown(self):
1244 gid_1, gid_2 = groups[:2]
1245 uid = os.stat(support.TESTFN).st_uid
1246 os.chown(support.TESTFN, uid, gid_1)
1247 gid = os.stat(support.TESTFN).st_gid
1248 self.assertEqual(gid, gid_1)
1249 os.chown(support.TESTFN, uid, gid_2)
1250 gid = os.stat(support.TESTFN).st_gid
1251 self.assertEqual(gid, gid_2)
1252
1253 @unittest.skipUnless(root_in_posix and len(all_users) > 1,
1254 "test needs root privilege and more than one user")
1255 def test_chown_with_root(self):
1256 uid_1, uid_2 = all_users[:2]
1257 gid = os.stat(support.TESTFN).st_gid
1258 os.chown(support.TESTFN, uid_1, gid)
1259 uid = os.stat(support.TESTFN).st_uid
1260 self.assertEqual(uid, uid_1)
1261 os.chown(support.TESTFN, uid_2, gid)
1262 uid = os.stat(support.TESTFN).st_uid
1263 self.assertEqual(uid, uid_2)
1264
1265 @unittest.skipUnless(not root_in_posix and len(all_users) > 1,
1266 "test needs non-root account and more than one user")
1267 def test_chown_without_permission(self):
1268 uid_1, uid_2 = all_users[:2]
1269 gid = os.stat(support.TESTFN).st_gid
Serhiy Storchakaa9e00d12015-02-16 08:35:18 +02001270 with self.assertRaises(PermissionError):
R David Murrayf2ad1732014-12-25 18:36:56 -05001271 os.chown(support.TESTFN, uid_1, gid)
1272 os.chown(support.TESTFN, uid_2, gid)
1273
Berker Peksag036a71b2015-07-21 09:29:48 +03001274 @classmethod
1275 def tearDownClass(cls):
R David Murrayf2ad1732014-12-25 18:36:56 -05001276 os.rmdir(support.TESTFN)
1277
1278
Andrew Svetlov405faed2012-12-25 12:18:09 +02001279class RemoveDirsTests(unittest.TestCase):
1280 def setUp(self):
1281 os.makedirs(support.TESTFN)
1282
1283 def tearDown(self):
1284 support.rmtree(support.TESTFN)
1285
1286 def test_remove_all(self):
1287 dira = os.path.join(support.TESTFN, 'dira')
1288 os.mkdir(dira)
1289 dirb = os.path.join(dira, 'dirb')
1290 os.mkdir(dirb)
1291 os.removedirs(dirb)
1292 self.assertFalse(os.path.exists(dirb))
1293 self.assertFalse(os.path.exists(dira))
1294 self.assertFalse(os.path.exists(support.TESTFN))
1295
1296 def test_remove_partial(self):
1297 dira = os.path.join(support.TESTFN, 'dira')
1298 os.mkdir(dira)
1299 dirb = os.path.join(dira, 'dirb')
1300 os.mkdir(dirb)
Victor Stinnerae39d232016-03-24 17:12:55 +01001301 create_file(os.path.join(dira, 'file.txt'))
Andrew Svetlov405faed2012-12-25 12:18:09 +02001302 os.removedirs(dirb)
1303 self.assertFalse(os.path.exists(dirb))
1304 self.assertTrue(os.path.exists(dira))
1305 self.assertTrue(os.path.exists(support.TESTFN))
1306
1307 def test_remove_nothing(self):
1308 dira = os.path.join(support.TESTFN, 'dira')
1309 os.mkdir(dira)
1310 dirb = os.path.join(dira, 'dirb')
1311 os.mkdir(dirb)
Victor Stinnerae39d232016-03-24 17:12:55 +01001312 create_file(os.path.join(dirb, 'file.txt'))
Andrew Svetlov405faed2012-12-25 12:18:09 +02001313 with self.assertRaises(OSError):
1314 os.removedirs(dirb)
1315 self.assertTrue(os.path.exists(dirb))
1316 self.assertTrue(os.path.exists(dira))
1317 self.assertTrue(os.path.exists(support.TESTFN))
1318
1319
Guido van Rossume7ba4952007-06-06 23:52:48 +00001320class DevNullTests(unittest.TestCase):
Martin v. Löwisbdec50f2004-06-08 08:29:33 +00001321 def test_devnull(self):
Victor Stinnerae39d232016-03-24 17:12:55 +01001322 with open(os.devnull, 'wb', 0) as f:
Victor Stinnera6d2c762011-06-30 18:20:11 +02001323 f.write(b'hello')
1324 f.close()
1325 with open(os.devnull, 'rb') as f:
1326 self.assertEqual(f.read(), b'')
Andrew M. Kuchlingb386f6a2003-12-23 16:36:11 +00001327
Andrew Svetlov405faed2012-12-25 12:18:09 +02001328
Guido van Rossume7ba4952007-06-06 23:52:48 +00001329class URandomTests(unittest.TestCase):
Georg Brandl2daf6ae2012-02-20 19:54:16 +01001330 def test_urandom_length(self):
1331 self.assertEqual(len(os.urandom(0)), 0)
1332 self.assertEqual(len(os.urandom(1)), 1)
1333 self.assertEqual(len(os.urandom(10)), 10)
1334 self.assertEqual(len(os.urandom(100)), 100)
1335 self.assertEqual(len(os.urandom(1000)), 1000)
1336
1337 def test_urandom_value(self):
1338 data1 = os.urandom(16)
Victor Stinner9b1f4742016-09-06 16:18:52 -07001339 self.assertIsInstance(data1, bytes)
Georg Brandl2daf6ae2012-02-20 19:54:16 +01001340 data2 = os.urandom(16)
1341 self.assertNotEqual(data1, data2)
1342
1343 def get_urandom_subprocess(self, count):
1344 code = '\n'.join((
1345 'import os, sys',
1346 'data = os.urandom(%s)' % count,
1347 'sys.stdout.buffer.write(data)',
1348 'sys.stdout.buffer.flush()'))
1349 out = assert_python_ok('-c', code)
1350 stdout = out[1]
1351 self.assertEqual(len(stdout), 16)
1352 return stdout
1353
1354 def test_urandom_subprocess(self):
1355 data1 = self.get_urandom_subprocess(16)
1356 data2 = self.get_urandom_subprocess(16)
1357 self.assertNotEqual(data1, data2)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00001358
Victor Stinner4d6a3d62014-12-21 01:16:38 +01001359
Victor Stinner9b1f4742016-09-06 16:18:52 -07001360@unittest.skipUnless(hasattr(os, 'getrandom'), 'need os.getrandom()')
1361class GetRandomTests(unittest.TestCase):
Victor Stinner173a1f32016-09-06 19:57:40 -07001362 @classmethod
1363 def setUpClass(cls):
1364 try:
1365 os.getrandom(1)
1366 except OSError as exc:
1367 if exc.errno == errno.ENOSYS:
1368 # Python compiled on a more recent Linux version
1369 # than the current Linux kernel
1370 raise unittest.SkipTest("getrandom() syscall fails with ENOSYS")
1371 else:
1372 raise
1373
Victor Stinner9b1f4742016-09-06 16:18:52 -07001374 def test_getrandom_type(self):
1375 data = os.getrandom(16)
1376 self.assertIsInstance(data, bytes)
1377 self.assertEqual(len(data), 16)
1378
1379 def test_getrandom0(self):
1380 empty = os.getrandom(0)
1381 self.assertEqual(empty, b'')
1382
1383 def test_getrandom_random(self):
1384 self.assertTrue(hasattr(os, 'GRND_RANDOM'))
1385
1386 # Don't test os.getrandom(1, os.GRND_RANDOM) to not consume the rare
1387 # resource /dev/random
1388
1389 def test_getrandom_nonblock(self):
1390 # The call must not fail. Check also that the flag exists
1391 try:
1392 os.getrandom(1, os.GRND_NONBLOCK)
1393 except BlockingIOError:
1394 # System urandom is not initialized yet
1395 pass
1396
1397 def test_getrandom_value(self):
1398 data1 = os.getrandom(16)
1399 data2 = os.getrandom(16)
1400 self.assertNotEqual(data1, data2)
1401
1402
Victor Stinnerd8f432a2015-09-18 16:24:31 +02001403# os.urandom() doesn't use a file descriptor when it is implemented with the
1404# getentropy() function, the getrandom() function or the getrandom() syscall
1405OS_URANDOM_DONT_USE_FD = (
1406 sysconfig.get_config_var('HAVE_GETENTROPY') == 1
1407 or sysconfig.get_config_var('HAVE_GETRANDOM') == 1
1408 or sysconfig.get_config_var('HAVE_GETRANDOM_SYSCALL') == 1)
Victor Stinner4d6a3d62014-12-21 01:16:38 +01001409
Victor Stinnerd8f432a2015-09-18 16:24:31 +02001410@unittest.skipIf(OS_URANDOM_DONT_USE_FD ,
1411 "os.random() does not use a file descriptor")
Victor Stinner4d6a3d62014-12-21 01:16:38 +01001412class URandomFDTests(unittest.TestCase):
Antoine Pitrouec34ab52013-08-16 20:44:38 +02001413 @unittest.skipUnless(resource, "test requires the resource module")
1414 def test_urandom_failure(self):
Antoine Pitroueba25ba2013-08-24 20:52:27 +02001415 # Check urandom() failing when it is not able to open /dev/random.
1416 # We spawn a new process to make the test more robust (if getrlimit()
1417 # failed to restore the file descriptor limit after this, the whole
1418 # test suite would crash; this actually happened on the OS X Tiger
1419 # buildbot).
1420 code = """if 1:
1421 import errno
1422 import os
1423 import resource
1424
1425 soft_limit, hard_limit = resource.getrlimit(resource.RLIMIT_NOFILE)
1426 resource.setrlimit(resource.RLIMIT_NOFILE, (1, hard_limit))
1427 try:
Antoine Pitrouec34ab52013-08-16 20:44:38 +02001428 os.urandom(16)
Antoine Pitroueba25ba2013-08-24 20:52:27 +02001429 except OSError as e:
1430 assert e.errno == errno.EMFILE, e.errno
1431 else:
1432 raise AssertionError("OSError not raised")
1433 """
1434 assert_python_ok('-c', code)
Antoine Pitrouec34ab52013-08-16 20:44:38 +02001435
Antoine Pitroue472aea2014-04-26 14:33:03 +02001436 def test_urandom_fd_closed(self):
1437 # Issue #21207: urandom() should reopen its fd to /dev/urandom if
1438 # closed.
1439 code = """if 1:
1440 import os
1441 import sys
Steve Dowerd5a0be62015-03-07 21:25:54 -08001442 import test.support
Antoine Pitroue472aea2014-04-26 14:33:03 +02001443 os.urandom(4)
Steve Dowerd5a0be62015-03-07 21:25:54 -08001444 with test.support.SuppressCrashReport():
1445 os.closerange(3, 256)
Antoine Pitroue472aea2014-04-26 14:33:03 +02001446 sys.stdout.buffer.write(os.urandom(4))
1447 """
1448 rc, out, err = assert_python_ok('-Sc', code)
1449
1450 def test_urandom_fd_reopened(self):
1451 # Issue #21207: urandom() should detect its fd to /dev/urandom
1452 # changed to something else, and reopen it.
Victor Stinnerae39d232016-03-24 17:12:55 +01001453 self.addCleanup(support.unlink, support.TESTFN)
1454 create_file(support.TESTFN, b"x" * 256)
1455
Antoine Pitroue472aea2014-04-26 14:33:03 +02001456 code = """if 1:
1457 import os
1458 import sys
Steve Dowerd5a0be62015-03-07 21:25:54 -08001459 import test.support
Antoine Pitroue472aea2014-04-26 14:33:03 +02001460 os.urandom(4)
Steve Dowerd5a0be62015-03-07 21:25:54 -08001461 with test.support.SuppressCrashReport():
1462 for fd in range(3, 256):
1463 try:
1464 os.close(fd)
1465 except OSError:
1466 pass
1467 else:
1468 # Found the urandom fd (XXX hopefully)
1469 break
1470 os.closerange(3, 256)
Antoine Pitroue472aea2014-04-26 14:33:03 +02001471 with open({TESTFN!r}, 'rb') as f:
Xavier de Gaye21060102016-11-16 08:05:27 +01001472 new_fd = f.fileno()
1473 # Issue #26935: posix allows new_fd and fd to be equal but
1474 # some libc implementations have dup2 return an error in this
1475 # case.
1476 if new_fd != fd:
1477 os.dup2(new_fd, fd)
Antoine Pitroue472aea2014-04-26 14:33:03 +02001478 sys.stdout.buffer.write(os.urandom(4))
1479 sys.stdout.buffer.write(os.urandom(4))
1480 """.format(TESTFN=support.TESTFN)
1481 rc, out, err = assert_python_ok('-Sc', code)
1482 self.assertEqual(len(out), 8)
1483 self.assertNotEqual(out[0:4], out[4:8])
1484 rc, out2, err2 = assert_python_ok('-Sc', code)
1485 self.assertEqual(len(out2), 8)
1486 self.assertNotEqual(out2, out)
1487
Antoine Pitrouec34ab52013-08-16 20:44:38 +02001488
Victor Stinnerc2d095f2010-05-17 00:14:53 +00001489@contextlib.contextmanager
1490def _execvpe_mockup(defpath=None):
1491 """
1492 Stubs out execv and execve functions when used as context manager.
1493 Records exec calls. The mock execv and execve functions always raise an
1494 exception as they would normally never return.
1495 """
1496 # A list of tuples containing (function name, first arg, args)
1497 # of calls to execv or execve that have been made.
1498 calls = []
1499
1500 def mock_execv(name, *args):
1501 calls.append(('execv', name, args))
1502 raise RuntimeError("execv called")
1503
1504 def mock_execve(name, *args):
1505 calls.append(('execve', name, args))
1506 raise OSError(errno.ENOTDIR, "execve called")
1507
1508 try:
1509 orig_execv = os.execv
1510 orig_execve = os.execve
1511 orig_defpath = os.defpath
1512 os.execv = mock_execv
1513 os.execve = mock_execve
1514 if defpath is not None:
1515 os.defpath = defpath
1516 yield calls
1517 finally:
1518 os.execv = orig_execv
1519 os.execve = orig_execve
1520 os.defpath = orig_defpath
1521
Victor Stinner4659ccf2016-09-14 10:57:00 +02001522
Guido van Rossume7ba4952007-06-06 23:52:48 +00001523class ExecTests(unittest.TestCase):
Mark Dickinson7cf03892010-04-16 13:45:35 +00001524 @unittest.skipIf(USING_LINUXTHREADS,
1525 "avoid triggering a linuxthreads bug: see issue #4970")
Guido van Rossume7ba4952007-06-06 23:52:48 +00001526 def test_execvpe_with_bad_program(self):
Mark Dickinson7cf03892010-04-16 13:45:35 +00001527 self.assertRaises(OSError, os.execvpe, 'no such app-',
1528 ['no such app-'], None)
Guido van Rossume7ba4952007-06-06 23:52:48 +00001529
Steve Dowerbce26262016-11-19 19:17:26 -08001530 def test_execv_with_bad_arglist(self):
1531 self.assertRaises(ValueError, os.execv, 'notepad', ())
1532 self.assertRaises(ValueError, os.execv, 'notepad', [])
1533 self.assertRaises(ValueError, os.execv, 'notepad', ('',))
1534 self.assertRaises(ValueError, os.execv, 'notepad', [''])
1535
Thomas Heller6790d602007-08-30 17:15:14 +00001536 def test_execvpe_with_bad_arglist(self):
1537 self.assertRaises(ValueError, os.execvpe, 'notepad', [], None)
Steve Dowerbce26262016-11-19 19:17:26 -08001538 self.assertRaises(ValueError, os.execvpe, 'notepad', [], {})
1539 self.assertRaises(ValueError, os.execvpe, 'notepad', [''], {})
Thomas Heller6790d602007-08-30 17:15:14 +00001540
Gregory P. Smith4ae37772010-05-08 18:05:46 +00001541 @unittest.skipUnless(hasattr(os, '_execvpe'),
1542 "No internal os._execvpe function to test.")
Victor Stinnerb745a742010-05-18 17:17:23 +00001543 def _test_internal_execvpe(self, test_type):
1544 program_path = os.sep + 'absolutepath'
1545 if test_type is bytes:
1546 program = b'executable'
1547 fullpath = os.path.join(os.fsencode(program_path), program)
1548 native_fullpath = fullpath
1549 arguments = [b'progname', 'arg1', 'arg2']
1550 else:
1551 program = 'executable'
1552 arguments = ['progname', 'arg1', 'arg2']
1553 fullpath = os.path.join(program_path, program)
1554 if os.name != "nt":
1555 native_fullpath = os.fsencode(fullpath)
1556 else:
1557 native_fullpath = fullpath
Victor Stinnerc2d095f2010-05-17 00:14:53 +00001558 env = {'spam': 'beans'}
1559
Victor Stinnerb745a742010-05-18 17:17:23 +00001560 # test os._execvpe() with an absolute path
Victor Stinnerc2d095f2010-05-17 00:14:53 +00001561 with _execvpe_mockup() as calls:
Victor Stinnerb745a742010-05-18 17:17:23 +00001562 self.assertRaises(RuntimeError,
1563 os._execvpe, fullpath, arguments)
Victor Stinnerc2d095f2010-05-17 00:14:53 +00001564 self.assertEqual(len(calls), 1)
1565 self.assertEqual(calls[0], ('execv', fullpath, (arguments,)))
1566
Victor Stinnerb745a742010-05-18 17:17:23 +00001567 # test os._execvpe() with a relative path:
1568 # os.get_exec_path() returns defpath
Victor Stinnerc2d095f2010-05-17 00:14:53 +00001569 with _execvpe_mockup(defpath=program_path) as calls:
Victor Stinnerb745a742010-05-18 17:17:23 +00001570 self.assertRaises(OSError,
1571 os._execvpe, program, arguments, env=env)
Victor Stinnerc2d095f2010-05-17 00:14:53 +00001572 self.assertEqual(len(calls), 1)
Victor Stinnerb745a742010-05-18 17:17:23 +00001573 self.assertSequenceEqual(calls[0],
1574 ('execve', native_fullpath, (arguments, env)))
1575
1576 # test os._execvpe() with a relative path:
1577 # os.get_exec_path() reads the 'PATH' variable
1578 with _execvpe_mockup() as calls:
1579 env_path = env.copy()
Victor Stinner38430e22010-08-19 17:10:18 +00001580 if test_type is bytes:
1581 env_path[b'PATH'] = program_path
1582 else:
1583 env_path['PATH'] = program_path
Victor Stinnerb745a742010-05-18 17:17:23 +00001584 self.assertRaises(OSError,
1585 os._execvpe, program, arguments, env=env_path)
1586 self.assertEqual(len(calls), 1)
1587 self.assertSequenceEqual(calls[0],
1588 ('execve', native_fullpath, (arguments, env_path)))
1589
1590 def test_internal_execvpe_str(self):
1591 self._test_internal_execvpe(str)
1592 if os.name != "nt":
1593 self._test_internal_execvpe(bytes)
Victor Stinnerc2d095f2010-05-17 00:14:53 +00001594
Serhiy Storchakaaf5392f2017-06-25 09:48:54 +03001595 def test_execve_invalid_env(self):
1596 args = [sys.executable, '-c', 'pass']
1597
Ville Skyttä49b27342017-08-03 09:00:59 +03001598 # null character in the environment variable name
Serhiy Storchakaaf5392f2017-06-25 09:48:54 +03001599 newenv = os.environ.copy()
1600 newenv["FRUIT\0VEGETABLE"] = "cabbage"
1601 with self.assertRaises(ValueError):
1602 os.execve(args[0], args, newenv)
1603
Ville Skyttä49b27342017-08-03 09:00:59 +03001604 # null character in the environment variable value
Serhiy Storchakaaf5392f2017-06-25 09:48:54 +03001605 newenv = os.environ.copy()
1606 newenv["FRUIT"] = "orange\0VEGETABLE=cabbage"
1607 with self.assertRaises(ValueError):
1608 os.execve(args[0], args, newenv)
1609
Ville Skyttä49b27342017-08-03 09:00:59 +03001610 # equal character in the environment variable name
Serhiy Storchakaaf5392f2017-06-25 09:48:54 +03001611 newenv = os.environ.copy()
1612 newenv["FRUIT=ORANGE"] = "lemon"
1613 with self.assertRaises(ValueError):
1614 os.execve(args[0], args, newenv)
1615
Gregory P. Smith4ae37772010-05-08 18:05:46 +00001616
Serhiy Storchaka43767632013-11-03 21:31:38 +02001617@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
Thomas Wouters477c8d52006-05-27 19:21:47 +00001618class Win32ErrorTests(unittest.TestCase):
Victor Stinnere77c9742016-03-25 10:28:23 +01001619 def setUp(self):
Victor Stinner32830142016-03-25 15:12:08 +01001620 try:
1621 os.stat(support.TESTFN)
1622 except FileNotFoundError:
1623 exists = False
1624 except OSError as exc:
1625 exists = True
1626 self.fail("file %s must not exist; os.stat failed with %s"
1627 % (support.TESTFN, exc))
1628 else:
1629 self.fail("file %s must not exist" % support.TESTFN)
Victor Stinnere77c9742016-03-25 10:28:23 +01001630
Thomas Wouters477c8d52006-05-27 19:21:47 +00001631 def test_rename(self):
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001632 self.assertRaises(OSError, os.rename, support.TESTFN, support.TESTFN+".bak")
Thomas Wouters477c8d52006-05-27 19:21:47 +00001633
1634 def test_remove(self):
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001635 self.assertRaises(OSError, os.remove, support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001636
1637 def test_chdir(self):
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001638 self.assertRaises(OSError, os.chdir, support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001639
1640 def test_mkdir(self):
Victor Stinnerae39d232016-03-24 17:12:55 +01001641 self.addCleanup(support.unlink, support.TESTFN)
1642
Victor Stinnere77c9742016-03-25 10:28:23 +01001643 with open(support.TESTFN, "x") as f:
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001644 self.assertRaises(OSError, os.mkdir, support.TESTFN)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001645
1646 def test_utime(self):
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001647 self.assertRaises(OSError, os.utime, support.TESTFN, None)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001648
Thomas Wouters477c8d52006-05-27 19:21:47 +00001649 def test_chmod(self):
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001650 self.assertRaises(OSError, os.chmod, support.TESTFN, 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001651
Victor Stinnere77c9742016-03-25 10:28:23 +01001652
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001653class TestInvalidFD(unittest.TestCase):
Benjamin Peterson05e782f2009-01-19 15:15:02 +00001654 singles = ["fchdir", "dup", "fdopen", "fdatasync", "fstat",
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001655 "fstatvfs", "fsync", "tcgetpgrp", "ttyname"]
1656 #singles.append("close")
Steve Dower39294992016-08-30 21:22:36 -07001657 #We omit close because it doesn't raise an exception on some platforms
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001658 def get_single(f):
1659 def helper(self):
Benjamin Peterson7522c742009-01-19 21:00:09 +00001660 if hasattr(os, f):
1661 self.check(getattr(os, f))
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001662 return helper
1663 for f in singles:
1664 locals()["test_"+f] = get_single(f)
1665
Benjamin Peterson7522c742009-01-19 21:00:09 +00001666 def check(self, f, *args):
Benjamin Peterson5c6d7872009-02-06 02:40:07 +00001667 try:
1668 f(support.make_bad_fd(), *args)
1669 except OSError as e:
1670 self.assertEqual(e.errno, errno.EBADF)
1671 else:
Martin Panter7462b6492015-11-02 03:37:02 +00001672 self.fail("%r didn't raise an OSError with a bad file descriptor"
Benjamin Peterson5c6d7872009-02-06 02:40:07 +00001673 % f)
Benjamin Peterson7522c742009-01-19 21:00:09 +00001674
Serhiy Storchaka43767632013-11-03 21:31:38 +02001675 @unittest.skipUnless(hasattr(os, 'isatty'), 'test needs os.isatty()')
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001676 def test_isatty(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +02001677 self.assertEqual(os.isatty(support.make_bad_fd()), False)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001678
Serhiy Storchaka43767632013-11-03 21:31:38 +02001679 @unittest.skipUnless(hasattr(os, 'closerange'), 'test needs os.closerange()')
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001680 def test_closerange(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +02001681 fd = support.make_bad_fd()
1682 # Make sure none of the descriptors we are about to close are
1683 # currently valid (issue 6542).
1684 for i in range(10):
1685 try: os.fstat(fd+i)
1686 except OSError:
1687 pass
1688 else:
1689 break
1690 if i < 2:
1691 raise unittest.SkipTest(
1692 "Unable to acquire a range of invalid file descriptors")
1693 self.assertEqual(os.closerange(fd, fd + i-1), None)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001694
Serhiy Storchaka43767632013-11-03 21:31:38 +02001695 @unittest.skipUnless(hasattr(os, 'dup2'), 'test needs os.dup2()')
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001696 def test_dup2(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +02001697 self.check(os.dup2, 20)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001698
Serhiy Storchaka43767632013-11-03 21:31:38 +02001699 @unittest.skipUnless(hasattr(os, 'fchmod'), 'test needs os.fchmod()')
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001700 def test_fchmod(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +02001701 self.check(os.fchmod, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001702
Serhiy Storchaka43767632013-11-03 21:31:38 +02001703 @unittest.skipUnless(hasattr(os, 'fchown'), 'test needs os.fchown()')
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001704 def test_fchown(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +02001705 self.check(os.fchown, -1, -1)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001706
Serhiy Storchaka43767632013-11-03 21:31:38 +02001707 @unittest.skipUnless(hasattr(os, 'fpathconf'), 'test needs os.fpathconf()')
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001708 def test_fpathconf(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +02001709 self.check(os.pathconf, "PC_NAME_MAX")
1710 self.check(os.fpathconf, "PC_NAME_MAX")
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001711
Serhiy Storchaka43767632013-11-03 21:31:38 +02001712 @unittest.skipUnless(hasattr(os, 'ftruncate'), 'test needs os.ftruncate()')
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001713 def test_ftruncate(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +02001714 self.check(os.truncate, 0)
1715 self.check(os.ftruncate, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001716
Serhiy Storchaka43767632013-11-03 21:31:38 +02001717 @unittest.skipUnless(hasattr(os, 'lseek'), 'test needs os.lseek()')
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001718 def test_lseek(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +02001719 self.check(os.lseek, 0, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001720
Serhiy Storchaka43767632013-11-03 21:31:38 +02001721 @unittest.skipUnless(hasattr(os, 'read'), 'test needs os.read()')
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001722 def test_read(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +02001723 self.check(os.read, 1)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001724
Victor Stinner57ddf782014-01-08 15:21:28 +01001725 @unittest.skipUnless(hasattr(os, 'readv'), 'test needs os.readv()')
1726 def test_readv(self):
1727 buf = bytearray(10)
1728 self.check(os.readv, [buf])
1729
Serhiy Storchaka43767632013-11-03 21:31:38 +02001730 @unittest.skipUnless(hasattr(os, 'tcsetpgrp'), 'test needs os.tcsetpgrp()')
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001731 def test_tcsetpgrpt(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +02001732 self.check(os.tcsetpgrp, 0)
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001733
Serhiy Storchaka43767632013-11-03 21:31:38 +02001734 @unittest.skipUnless(hasattr(os, 'write'), 'test needs os.write()')
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001735 def test_write(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +02001736 self.check(os.write, b" ")
Benjamin Petersone1cdfd72009-01-18 21:02:37 +00001737
Victor Stinner57ddf782014-01-08 15:21:28 +01001738 @unittest.skipUnless(hasattr(os, 'writev'), 'test needs os.writev()')
1739 def test_writev(self):
1740 self.check(os.writev, [b'abc'])
1741
Victor Stinner1db9e7b2014-07-29 22:32:47 +02001742 def test_inheritable(self):
1743 self.check(os.get_inheritable)
1744 self.check(os.set_inheritable, True)
1745
1746 @unittest.skipUnless(hasattr(os, 'get_blocking'),
1747 'needs os.get_blocking() and os.set_blocking()')
1748 def test_blocking(self):
1749 self.check(os.get_blocking)
1750 self.check(os.set_blocking, True)
1751
Brian Curtin1b9df392010-11-24 20:24:31 +00001752
1753class LinkTests(unittest.TestCase):
1754 def setUp(self):
1755 self.file1 = support.TESTFN
1756 self.file2 = os.path.join(support.TESTFN + "2")
1757
Brian Curtinc0abc4e2010-11-30 23:46:54 +00001758 def tearDown(self):
Brian Curtin1b9df392010-11-24 20:24:31 +00001759 for file in (self.file1, self.file2):
1760 if os.path.exists(file):
1761 os.unlink(file)
1762
Brian Curtin1b9df392010-11-24 20:24:31 +00001763 def _test_link(self, file1, file2):
Victor Stinnere77c9742016-03-25 10:28:23 +01001764 create_file(file1)
Brian Curtin1b9df392010-11-24 20:24:31 +00001765
Steve Dowercc16be82016-09-08 10:35:16 -07001766 os.link(file1, file2)
Brian Curtin1b9df392010-11-24 20:24:31 +00001767 with open(file1, "r") as f1, open(file2, "r") as f2:
1768 self.assertTrue(os.path.sameopenfile(f1.fileno(), f2.fileno()))
1769
1770 def test_link(self):
1771 self._test_link(self.file1, self.file2)
1772
1773 def test_link_bytes(self):
1774 self._test_link(bytes(self.file1, sys.getfilesystemencoding()),
1775 bytes(self.file2, sys.getfilesystemencoding()))
1776
Brian Curtinf498b752010-11-30 15:54:04 +00001777 def test_unicode_name(self):
Brian Curtin43f0c272010-11-30 15:40:04 +00001778 try:
Brian Curtinf498b752010-11-30 15:54:04 +00001779 os.fsencode("\xf1")
Brian Curtin43f0c272010-11-30 15:40:04 +00001780 except UnicodeError:
1781 raise unittest.SkipTest("Unable to encode for this platform.")
1782
Brian Curtinf498b752010-11-30 15:54:04 +00001783 self.file1 += "\xf1"
Brian Curtinfc889c42010-11-28 23:59:46 +00001784 self.file2 = self.file1 + "2"
1785 self._test_link(self.file1, self.file2)
1786
Serhiy Storchaka43767632013-11-03 21:31:38 +02001787@unittest.skipIf(sys.platform == "win32", "Posix specific tests")
1788class PosixUidGidTests(unittest.TestCase):
1789 @unittest.skipUnless(hasattr(os, 'setuid'), 'test needs os.setuid()')
1790 def test_setuid(self):
1791 if os.getuid() != 0:
1792 self.assertRaises(OSError, os.setuid, 0)
1793 self.assertRaises(OverflowError, os.setuid, 1<<32)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001794
Serhiy Storchaka43767632013-11-03 21:31:38 +02001795 @unittest.skipUnless(hasattr(os, 'setgid'), 'test needs os.setgid()')
1796 def test_setgid(self):
1797 if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
1798 self.assertRaises(OSError, os.setgid, 0)
1799 self.assertRaises(OverflowError, os.setgid, 1<<32)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001800
Serhiy Storchaka43767632013-11-03 21:31:38 +02001801 @unittest.skipUnless(hasattr(os, 'seteuid'), 'test needs os.seteuid()')
1802 def test_seteuid(self):
1803 if os.getuid() != 0:
1804 self.assertRaises(OSError, os.seteuid, 0)
1805 self.assertRaises(OverflowError, os.seteuid, 1<<32)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001806
Serhiy Storchaka43767632013-11-03 21:31:38 +02001807 @unittest.skipUnless(hasattr(os, 'setegid'), 'test needs os.setegid()')
1808 def test_setegid(self):
1809 if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
1810 self.assertRaises(OSError, os.setegid, 0)
1811 self.assertRaises(OverflowError, os.setegid, 1<<32)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001812
Serhiy Storchaka43767632013-11-03 21:31:38 +02001813 @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()')
1814 def test_setreuid(self):
1815 if os.getuid() != 0:
1816 self.assertRaises(OSError, os.setreuid, 0, 0)
1817 self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
1818 self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001819
Serhiy Storchaka43767632013-11-03 21:31:38 +02001820 @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()')
1821 def test_setreuid_neg1(self):
1822 # Needs to accept -1. We run this in a subprocess to avoid
1823 # altering the test runner's process state (issue8045).
1824 subprocess.check_call([
1825 sys.executable, '-c',
1826 'import os,sys;os.setreuid(-1,-1);sys.exit(0)'])
Benjamin Petersonebe87ba2010-03-06 20:34:24 +00001827
Serhiy Storchaka43767632013-11-03 21:31:38 +02001828 @unittest.skipUnless(hasattr(os, 'setregid'), 'test needs os.setregid()')
1829 def test_setregid(self):
1830 if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
1831 self.assertRaises(OSError, os.setregid, 0, 0)
1832 self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
1833 self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001834
Serhiy Storchaka43767632013-11-03 21:31:38 +02001835 @unittest.skipUnless(hasattr(os, 'setregid'), 'test needs os.setregid()')
1836 def test_setregid_neg1(self):
1837 # Needs to accept -1. We run this in a subprocess to avoid
1838 # altering the test runner's process state (issue8045).
1839 subprocess.check_call([
1840 sys.executable, '-c',
1841 'import os,sys;os.setregid(-1,-1);sys.exit(0)'])
Benjamin Petersonebe87ba2010-03-06 20:34:24 +00001842
Serhiy Storchaka43767632013-11-03 21:31:38 +02001843@unittest.skipIf(sys.platform == "win32", "Posix specific tests")
1844class Pep383Tests(unittest.TestCase):
1845 def setUp(self):
1846 if support.TESTFN_UNENCODABLE:
1847 self.dir = support.TESTFN_UNENCODABLE
1848 elif support.TESTFN_NONASCII:
1849 self.dir = support.TESTFN_NONASCII
1850 else:
1851 self.dir = support.TESTFN
1852 self.bdir = os.fsencode(self.dir)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001853
Serhiy Storchaka43767632013-11-03 21:31:38 +02001854 bytesfn = []
1855 def add_filename(fn):
Victor Stinnerd91df1a2010-08-18 10:56:19 +00001856 try:
Serhiy Storchaka43767632013-11-03 21:31:38 +02001857 fn = os.fsencode(fn)
1858 except UnicodeEncodeError:
1859 return
1860 bytesfn.append(fn)
1861 add_filename(support.TESTFN_UNICODE)
1862 if support.TESTFN_UNENCODABLE:
1863 add_filename(support.TESTFN_UNENCODABLE)
1864 if support.TESTFN_NONASCII:
1865 add_filename(support.TESTFN_NONASCII)
1866 if not bytesfn:
1867 self.skipTest("couldn't create any non-ascii filename")
Martin v. Löwis011e8422009-05-05 04:43:17 +00001868
Serhiy Storchaka43767632013-11-03 21:31:38 +02001869 self.unicodefn = set()
1870 os.mkdir(self.dir)
1871 try:
1872 for fn in bytesfn:
1873 support.create_empty_file(os.path.join(self.bdir, fn))
1874 fn = os.fsdecode(fn)
1875 if fn in self.unicodefn:
1876 raise ValueError("duplicate filename")
1877 self.unicodefn.add(fn)
1878 except:
Martin v. Löwis011e8422009-05-05 04:43:17 +00001879 shutil.rmtree(self.dir)
Serhiy Storchaka43767632013-11-03 21:31:38 +02001880 raise
Martin v. Löwis011e8422009-05-05 04:43:17 +00001881
Serhiy Storchaka43767632013-11-03 21:31:38 +02001882 def tearDown(self):
1883 shutil.rmtree(self.dir)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001884
Serhiy Storchaka43767632013-11-03 21:31:38 +02001885 def test_listdir(self):
1886 expected = self.unicodefn
1887 found = set(os.listdir(self.dir))
1888 self.assertEqual(found, expected)
1889 # test listdir without arguments
1890 current_directory = os.getcwd()
1891 try:
1892 os.chdir(os.sep)
1893 self.assertEqual(set(os.listdir()), set(os.listdir(os.sep)))
1894 finally:
1895 os.chdir(current_directory)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001896
Serhiy Storchaka43767632013-11-03 21:31:38 +02001897 def test_open(self):
1898 for fn in self.unicodefn:
1899 f = open(os.path.join(self.dir, fn), 'rb')
1900 f.close()
Victor Stinnere4110dc2013-01-01 23:05:55 +01001901
Serhiy Storchaka43767632013-11-03 21:31:38 +02001902 @unittest.skipUnless(hasattr(os, 'statvfs'),
1903 "need os.statvfs()")
1904 def test_statvfs(self):
1905 # issue #9645
1906 for fn in self.unicodefn:
1907 # should not fail with file not found error
1908 fullname = os.path.join(self.dir, fn)
1909 os.statvfs(fullname)
1910
1911 def test_stat(self):
1912 for fn in self.unicodefn:
1913 os.stat(os.path.join(self.dir, fn))
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001914
Brian Curtineb24d742010-04-12 17:16:38 +00001915@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
1916class Win32KillTests(unittest.TestCase):
Brian Curtinc3acbc32010-05-28 16:08:40 +00001917 def _kill(self, sig):
1918 # Start sys.executable as a subprocess and communicate from the
1919 # subprocess to the parent that the interpreter is ready. When it
1920 # becomes ready, send *sig* via os.kill to the subprocess and check
1921 # that the return code is equal to *sig*.
1922 import ctypes
1923 from ctypes import wintypes
1924 import msvcrt
1925
1926 # Since we can't access the contents of the process' stdout until the
1927 # process has exited, use PeekNamedPipe to see what's inside stdout
1928 # without waiting. This is done so we can tell that the interpreter
1929 # is started and running at a point where it could handle a signal.
1930 PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe
1931 PeekNamedPipe.restype = wintypes.BOOL
1932 PeekNamedPipe.argtypes = (wintypes.HANDLE, # Pipe handle
1933 ctypes.POINTER(ctypes.c_char), # stdout buf
1934 wintypes.DWORD, # Buffer size
1935 ctypes.POINTER(wintypes.DWORD), # bytes read
1936 ctypes.POINTER(wintypes.DWORD), # bytes avail
1937 ctypes.POINTER(wintypes.DWORD)) # bytes left
1938 msg = "running"
1939 proc = subprocess.Popen([sys.executable, "-c",
1940 "import sys;"
1941 "sys.stdout.write('{}');"
1942 "sys.stdout.flush();"
1943 "input()".format(msg)],
1944 stdout=subprocess.PIPE,
1945 stderr=subprocess.PIPE,
1946 stdin=subprocess.PIPE)
Brian Curtin43ec5772010-11-05 15:17:11 +00001947 self.addCleanup(proc.stdout.close)
1948 self.addCleanup(proc.stderr.close)
1949 self.addCleanup(proc.stdin.close)
Brian Curtinc3acbc32010-05-28 16:08:40 +00001950
1951 count, max = 0, 100
1952 while count < max and proc.poll() is None:
1953 # Create a string buffer to store the result of stdout from the pipe
1954 buf = ctypes.create_string_buffer(len(msg))
1955 # Obtain the text currently in proc.stdout
1956 # Bytes read/avail/left are left as NULL and unused
1957 rslt = PeekNamedPipe(msvcrt.get_osfhandle(proc.stdout.fileno()),
1958 buf, ctypes.sizeof(buf), None, None, None)
1959 self.assertNotEqual(rslt, 0, "PeekNamedPipe failed")
1960 if buf.value:
1961 self.assertEqual(msg, buf.value.decode())
1962 break
1963 time.sleep(0.1)
1964 count += 1
1965 else:
1966 self.fail("Did not receive communication from the subprocess")
1967
Brian Curtineb24d742010-04-12 17:16:38 +00001968 os.kill(proc.pid, sig)
1969 self.assertEqual(proc.wait(), sig)
1970
1971 def test_kill_sigterm(self):
1972 # SIGTERM doesn't mean anything special, but make sure it works
Brian Curtinc3acbc32010-05-28 16:08:40 +00001973 self._kill(signal.SIGTERM)
Brian Curtineb24d742010-04-12 17:16:38 +00001974
1975 def test_kill_int(self):
1976 # os.kill on Windows can take an int which gets set as the exit code
Brian Curtinc3acbc32010-05-28 16:08:40 +00001977 self._kill(100)
Brian Curtineb24d742010-04-12 17:16:38 +00001978
1979 def _kill_with_event(self, event, name):
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001980 tagname = "test_os_%s" % uuid.uuid1()
1981 m = mmap.mmap(-1, 1, tagname)
1982 m[0] = 0
Brian Curtineb24d742010-04-12 17:16:38 +00001983 # Run a script which has console control handling enabled.
1984 proc = subprocess.Popen([sys.executable,
1985 os.path.join(os.path.dirname(__file__),
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001986 "win_console_handler.py"), tagname],
Brian Curtineb24d742010-04-12 17:16:38 +00001987 creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
1988 # Let the interpreter startup before we send signals. See #3137.
Hirokazu Yamamoto8e9fe9f2010-12-05 02:41:46 +00001989 count, max = 0, 100
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001990 while count < max and proc.poll() is None:
Brian Curtinf668df52010-10-15 14:21:06 +00001991 if m[0] == 1:
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001992 break
Hirokazu Yamamoto8e9fe9f2010-12-05 02:41:46 +00001993 time.sleep(0.1)
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001994 count += 1
1995 else:
Hirokazu Yamamoto8e9fe9f2010-12-05 02:41:46 +00001996 # Forcefully kill the process if we weren't able to signal it.
1997 os.kill(proc.pid, signal.SIGINT)
Hirokazu Yamamoto54c950f2010-10-08 08:38:15 +00001998 self.fail("Subprocess didn't finish initialization")
Brian Curtineb24d742010-04-12 17:16:38 +00001999 os.kill(proc.pid, event)
2000 # proc.send_signal(event) could also be done here.
2001 # Allow time for the signal to be passed and the process to exit.
2002 time.sleep(0.5)
2003 if not proc.poll():
2004 # Forcefully kill the process if we weren't able to signal it.
2005 os.kill(proc.pid, signal.SIGINT)
2006 self.fail("subprocess did not stop on {}".format(name))
2007
Serhiy Storchaka0424eaf2015-09-12 17:45:25 +03002008 @unittest.skip("subprocesses aren't inheriting Ctrl+C property")
Brian Curtineb24d742010-04-12 17:16:38 +00002009 def test_CTRL_C_EVENT(self):
2010 from ctypes import wintypes
2011 import ctypes
2012
2013 # Make a NULL value by creating a pointer with no argument.
2014 NULL = ctypes.POINTER(ctypes.c_int)()
2015 SetConsoleCtrlHandler = ctypes.windll.kernel32.SetConsoleCtrlHandler
2016 SetConsoleCtrlHandler.argtypes = (ctypes.POINTER(ctypes.c_int),
2017 wintypes.BOOL)
2018 SetConsoleCtrlHandler.restype = wintypes.BOOL
2019
2020 # Calling this with NULL and FALSE causes the calling process to
Serhiy Storchaka0424eaf2015-09-12 17:45:25 +03002021 # handle Ctrl+C, rather than ignore it. This property is inherited
Brian Curtineb24d742010-04-12 17:16:38 +00002022 # by subprocesses.
2023 SetConsoleCtrlHandler(NULL, 0)
2024
2025 self._kill_with_event(signal.CTRL_C_EVENT, "CTRL_C_EVENT")
2026
2027 def test_CTRL_BREAK_EVENT(self):
2028 self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT")
2029
2030
Brian Curtind40e6f72010-07-08 21:39:08 +00002031@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
Tim Golden781bbeb2013-10-25 20:24:06 +01002032class Win32ListdirTests(unittest.TestCase):
2033 """Test listdir on Windows."""
2034
2035 def setUp(self):
2036 self.created_paths = []
2037 for i in range(2):
2038 dir_name = 'SUB%d' % i
2039 dir_path = os.path.join(support.TESTFN, dir_name)
2040 file_name = 'FILE%d' % i
2041 file_path = os.path.join(support.TESTFN, file_name)
2042 os.makedirs(dir_path)
2043 with open(file_path, 'w') as f:
2044 f.write("I'm %s and proud of it. Blame test_os.\n" % file_path)
2045 self.created_paths.extend([dir_name, file_name])
2046 self.created_paths.sort()
2047
2048 def tearDown(self):
2049 shutil.rmtree(support.TESTFN)
2050
2051 def test_listdir_no_extended_path(self):
2052 """Test when the path is not an "extended" path."""
2053 # unicode
2054 self.assertEqual(
2055 sorted(os.listdir(support.TESTFN)),
2056 self.created_paths)
Victor Stinner923590e2016-03-24 09:11:48 +01002057
Tim Golden781bbeb2013-10-25 20:24:06 +01002058 # bytes
Steve Dowercc16be82016-09-08 10:35:16 -07002059 self.assertEqual(
2060 sorted(os.listdir(os.fsencode(support.TESTFN))),
2061 [os.fsencode(path) for path in self.created_paths])
Tim Golden781bbeb2013-10-25 20:24:06 +01002062
2063 def test_listdir_extended_path(self):
2064 """Test when the path starts with '\\\\?\\'."""
Tim Golden1cc35402013-10-25 21:26:06 +01002065 # See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
Tim Golden781bbeb2013-10-25 20:24:06 +01002066 # unicode
2067 path = '\\\\?\\' + os.path.abspath(support.TESTFN)
2068 self.assertEqual(
2069 sorted(os.listdir(path)),
2070 self.created_paths)
Victor Stinner923590e2016-03-24 09:11:48 +01002071
Tim Golden781bbeb2013-10-25 20:24:06 +01002072 # bytes
Steve Dowercc16be82016-09-08 10:35:16 -07002073 path = b'\\\\?\\' + os.fsencode(os.path.abspath(support.TESTFN))
2074 self.assertEqual(
2075 sorted(os.listdir(path)),
2076 [os.fsencode(path) for path in self.created_paths])
Tim Golden781bbeb2013-10-25 20:24:06 +01002077
2078
2079@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
Brian Curtin3b4499c2010-12-28 14:31:47 +00002080@support.skip_unless_symlink
Brian Curtind40e6f72010-07-08 21:39:08 +00002081class Win32SymlinkTests(unittest.TestCase):
2082 filelink = 'filelinktest'
2083 filelink_target = os.path.abspath(__file__)
2084 dirlink = 'dirlinktest'
2085 dirlink_target = os.path.dirname(filelink_target)
2086 missing_link = 'missing link'
2087
2088 def setUp(self):
2089 assert os.path.exists(self.dirlink_target)
2090 assert os.path.exists(self.filelink_target)
2091 assert not os.path.exists(self.dirlink)
2092 assert not os.path.exists(self.filelink)
2093 assert not os.path.exists(self.missing_link)
2094
2095 def tearDown(self):
2096 if os.path.exists(self.filelink):
2097 os.remove(self.filelink)
2098 if os.path.exists(self.dirlink):
2099 os.rmdir(self.dirlink)
2100 if os.path.lexists(self.missing_link):
2101 os.remove(self.missing_link)
2102
2103 def test_directory_link(self):
Jason R. Coombs3a092862013-05-27 23:21:28 -04002104 os.symlink(self.dirlink_target, self.dirlink)
Brian Curtind40e6f72010-07-08 21:39:08 +00002105 self.assertTrue(os.path.exists(self.dirlink))
2106 self.assertTrue(os.path.isdir(self.dirlink))
2107 self.assertTrue(os.path.islink(self.dirlink))
2108 self.check_stat(self.dirlink, self.dirlink_target)
2109
2110 def test_file_link(self):
2111 os.symlink(self.filelink_target, self.filelink)
2112 self.assertTrue(os.path.exists(self.filelink))
2113 self.assertTrue(os.path.isfile(self.filelink))
2114 self.assertTrue(os.path.islink(self.filelink))
2115 self.check_stat(self.filelink, self.filelink_target)
2116
2117 def _create_missing_dir_link(self):
2118 'Create a "directory" link to a non-existent target'
2119 linkname = self.missing_link
2120 if os.path.lexists(linkname):
2121 os.remove(linkname)
2122 target = r'c:\\target does not exist.29r3c740'
2123 assert not os.path.exists(target)
2124 target_is_dir = True
2125 os.symlink(target, linkname, target_is_dir)
2126
2127 def test_remove_directory_link_to_missing_target(self):
2128 self._create_missing_dir_link()
2129 # For compatibility with Unix, os.remove will check the
2130 # directory status and call RemoveDirectory if the symlink
2131 # was created with target_is_dir==True.
2132 os.remove(self.missing_link)
2133
2134 @unittest.skip("currently fails; consider for improvement")
2135 def test_isdir_on_directory_link_to_missing_target(self):
2136 self._create_missing_dir_link()
2137 # consider having isdir return true for directory links
2138 self.assertTrue(os.path.isdir(self.missing_link))
2139
2140 @unittest.skip("currently fails; consider for improvement")
2141 def test_rmdir_on_directory_link_to_missing_target(self):
2142 self._create_missing_dir_link()
2143 # consider allowing rmdir to remove directory links
2144 os.rmdir(self.missing_link)
2145
2146 def check_stat(self, link, target):
2147 self.assertEqual(os.stat(link), os.stat(target))
2148 self.assertNotEqual(os.lstat(link), os.stat(link))
2149
Brian Curtind25aef52011-06-13 15:16:04 -05002150 bytes_link = os.fsencode(link)
Steve Dowercc16be82016-09-08 10:35:16 -07002151 self.assertEqual(os.stat(bytes_link), os.stat(target))
2152 self.assertNotEqual(os.lstat(bytes_link), os.stat(bytes_link))
Brian Curtind25aef52011-06-13 15:16:04 -05002153
2154 def test_12084(self):
2155 level1 = os.path.abspath(support.TESTFN)
2156 level2 = os.path.join(level1, "level2")
2157 level3 = os.path.join(level2, "level3")
Victor Stinnerae39d232016-03-24 17:12:55 +01002158 self.addCleanup(support.rmtree, level1)
2159
2160 os.mkdir(level1)
2161 os.mkdir(level2)
2162 os.mkdir(level3)
2163
2164 file1 = os.path.abspath(os.path.join(level1, "file1"))
2165 create_file(file1)
2166
2167 orig_dir = os.getcwd()
Brian Curtind25aef52011-06-13 15:16:04 -05002168 try:
Victor Stinnerae39d232016-03-24 17:12:55 +01002169 os.chdir(level2)
2170 link = os.path.join(level2, "link")
2171 os.symlink(os.path.relpath(file1), "link")
2172 self.assertIn("link", os.listdir(os.getcwd()))
Brian Curtind25aef52011-06-13 15:16:04 -05002173
Victor Stinnerae39d232016-03-24 17:12:55 +01002174 # Check os.stat calls from the same dir as the link
2175 self.assertEqual(os.stat(file1), os.stat("link"))
Brian Curtind25aef52011-06-13 15:16:04 -05002176
Victor Stinnerae39d232016-03-24 17:12:55 +01002177 # Check os.stat calls from a dir below the link
2178 os.chdir(level1)
2179 self.assertEqual(os.stat(file1),
2180 os.stat(os.path.relpath(link)))
Brian Curtind25aef52011-06-13 15:16:04 -05002181
Victor Stinnerae39d232016-03-24 17:12:55 +01002182 # Check os.stat calls from a dir above the link
2183 os.chdir(level3)
2184 self.assertEqual(os.stat(file1),
2185 os.stat(os.path.relpath(link)))
Brian Curtind25aef52011-06-13 15:16:04 -05002186 finally:
Victor Stinnerae39d232016-03-24 17:12:55 +01002187 os.chdir(orig_dir)
Brian Curtind25aef52011-06-13 15:16:04 -05002188
Brian Curtind40e6f72010-07-08 21:39:08 +00002189
Tim Golden0321cf22014-05-05 19:46:17 +01002190@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
2191class Win32JunctionTests(unittest.TestCase):
2192 junction = 'junctiontest'
2193 junction_target = os.path.dirname(os.path.abspath(__file__))
2194
2195 def setUp(self):
2196 assert os.path.exists(self.junction_target)
2197 assert not os.path.exists(self.junction)
2198
2199 def tearDown(self):
2200 if os.path.exists(self.junction):
2201 # os.rmdir delegates to Windows' RemoveDirectoryW,
2202 # which removes junction points safely.
2203 os.rmdir(self.junction)
2204
2205 def test_create_junction(self):
2206 _winapi.CreateJunction(self.junction_target, self.junction)
2207 self.assertTrue(os.path.exists(self.junction))
2208 self.assertTrue(os.path.isdir(self.junction))
2209
2210 # Junctions are not recognized as links.
2211 self.assertFalse(os.path.islink(self.junction))
2212
2213 def test_unlink_removes_junction(self):
2214 _winapi.CreateJunction(self.junction_target, self.junction)
2215 self.assertTrue(os.path.exists(self.junction))
2216
2217 os.unlink(self.junction)
2218 self.assertFalse(os.path.exists(self.junction))
2219
2220
Jason R. Coombs3a092862013-05-27 23:21:28 -04002221@support.skip_unless_symlink
2222class NonLocalSymlinkTests(unittest.TestCase):
2223
2224 def setUp(self):
R David Murray44b548d2016-09-08 13:59:53 -04002225 r"""
Jason R. Coombs3a092862013-05-27 23:21:28 -04002226 Create this structure:
2227
2228 base
2229 \___ some_dir
2230 """
2231 os.makedirs('base/some_dir')
2232
2233 def tearDown(self):
2234 shutil.rmtree('base')
2235
2236 def test_directory_link_nonlocal(self):
2237 """
2238 The symlink target should resolve relative to the link, not relative
2239 to the current directory.
2240
2241 Then, link base/some_link -> base/some_dir and ensure that some_link
2242 is resolved as a directory.
2243
2244 In issue13772, it was discovered that directory detection failed if
2245 the symlink target was not specified relative to the current
2246 directory, which was a defect in the implementation.
2247 """
2248 src = os.path.join('base', 'some_link')
2249 os.symlink('some_dir', src)
2250 assert os.path.isdir(src)
2251
2252
Victor Stinnere8d51452010-08-19 01:05:19 +00002253class FSEncodingTests(unittest.TestCase):
2254 def test_nop(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +00002255 self.assertEqual(os.fsencode(b'abc\xff'), b'abc\xff')
2256 self.assertEqual(os.fsdecode('abc\u0141'), 'abc\u0141')
Benjamin Peterson31191a92010-05-09 03:22:58 +00002257
Victor Stinnere8d51452010-08-19 01:05:19 +00002258 def test_identity(self):
2259 # assert fsdecode(fsencode(x)) == x
2260 for fn in ('unicode\u0141', 'latin\xe9', 'ascii'):
2261 try:
2262 bytesfn = os.fsencode(fn)
2263 except UnicodeEncodeError:
2264 continue
Ezio Melottib3aedd42010-11-20 19:04:17 +00002265 self.assertEqual(os.fsdecode(bytesfn), fn)
Victor Stinnere8d51452010-08-19 01:05:19 +00002266
Victor Stinnerbf9bcab2010-05-09 03:15:33 +00002267
Brett Cannonefb00c02012-02-29 18:31:31 -05002268
2269class DeviceEncodingTests(unittest.TestCase):
2270
2271 def test_bad_fd(self):
2272 # Return None when an fd doesn't actually exist.
2273 self.assertIsNone(os.device_encoding(123456))
2274
Philip Jenveye308b7c2012-02-29 16:16:15 -08002275 @unittest.skipUnless(os.isatty(0) and (sys.platform.startswith('win') or
2276 (hasattr(locale, 'nl_langinfo') and hasattr(locale, 'CODESET'))),
Philip Jenveyd7aff2d2012-02-29 16:21:25 -08002277 'test requires a tty and either Windows or nl_langinfo(CODESET)')
Brett Cannonefb00c02012-02-29 18:31:31 -05002278 def test_device_encoding(self):
2279 encoding = os.device_encoding(0)
2280 self.assertIsNotNone(encoding)
2281 self.assertTrue(codecs.lookup(encoding))
2282
2283
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00002284class PidTests(unittest.TestCase):
2285 @unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid")
2286 def test_getppid(self):
2287 p = subprocess.Popen([sys.executable, '-c',
2288 'import os; print(os.getppid())'],
2289 stdout=subprocess.PIPE)
2290 stdout, _ = p.communicate()
2291 # We are the parent of our subprocess
2292 self.assertEqual(int(stdout), os.getpid())
2293
Victor Stinnerd3ffd322015-09-15 10:11:03 +02002294 def test_waitpid(self):
2295 args = [sys.executable, '-c', 'pass']
Brett Cannonec6ce872016-09-06 15:50:29 -07002296 # Add an implicit test for PyUnicode_FSConverter().
2297 pid = os.spawnv(os.P_NOWAIT, _PathLike(args[0]), args)
Victor Stinnerd3ffd322015-09-15 10:11:03 +02002298 status = os.waitpid(pid, 0)
2299 self.assertEqual(status, (pid, 0))
2300
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00002301
Victor Stinner4659ccf2016-09-14 10:57:00 +02002302class SpawnTests(unittest.TestCase):
Berker Peksag47e70622016-09-15 20:23:55 +03002303 def create_args(self, *, with_env=False, use_bytes=False):
Victor Stinner4659ccf2016-09-14 10:57:00 +02002304 self.exitcode = 17
2305
2306 filename = support.TESTFN
2307 self.addCleanup(support.unlink, filename)
2308
2309 if not with_env:
2310 code = 'import sys; sys.exit(%s)' % self.exitcode
2311 else:
2312 self.env = dict(os.environ)
2313 # create an unique key
2314 self.key = str(uuid.uuid4())
2315 self.env[self.key] = self.key
2316 # read the variable from os.environ to check that it exists
2317 code = ('import sys, os; magic = os.environ[%r]; sys.exit(%s)'
2318 % (self.key, self.exitcode))
2319
2320 with open(filename, "w") as fp:
2321 fp.write(code)
2322
Berker Peksag81816462016-09-15 20:19:47 +03002323 args = [sys.executable, filename]
2324 if use_bytes:
2325 args = [os.fsencode(a) for a in args]
2326 self.env = {os.fsencode(k): os.fsencode(v)
2327 for k, v in self.env.items()}
2328
2329 return args
Victor Stinner4659ccf2016-09-14 10:57:00 +02002330
Berker Peksag4af23d72016-09-15 20:32:44 +03002331 @requires_os_func('spawnl')
Victor Stinner4659ccf2016-09-14 10:57:00 +02002332 def test_spawnl(self):
2333 args = self.create_args()
2334 exitcode = os.spawnl(os.P_WAIT, args[0], *args)
2335 self.assertEqual(exitcode, self.exitcode)
2336
Berker Peksag4af23d72016-09-15 20:32:44 +03002337 @requires_os_func('spawnle')
Victor Stinner4659ccf2016-09-14 10:57:00 +02002338 def test_spawnle(self):
Berker Peksag47e70622016-09-15 20:23:55 +03002339 args = self.create_args(with_env=True)
Victor Stinner4659ccf2016-09-14 10:57:00 +02002340 exitcode = os.spawnle(os.P_WAIT, args[0], *args, self.env)
2341 self.assertEqual(exitcode, self.exitcode)
2342
Berker Peksag4af23d72016-09-15 20:32:44 +03002343 @requires_os_func('spawnlp')
Victor Stinner4659ccf2016-09-14 10:57:00 +02002344 def test_spawnlp(self):
2345 args = self.create_args()
2346 exitcode = os.spawnlp(os.P_WAIT, args[0], *args)
2347 self.assertEqual(exitcode, self.exitcode)
2348
Berker Peksag4af23d72016-09-15 20:32:44 +03002349 @requires_os_func('spawnlpe')
Victor Stinner4659ccf2016-09-14 10:57:00 +02002350 def test_spawnlpe(self):
Berker Peksag47e70622016-09-15 20:23:55 +03002351 args = self.create_args(with_env=True)
Victor Stinner4659ccf2016-09-14 10:57:00 +02002352 exitcode = os.spawnlpe(os.P_WAIT, args[0], *args, self.env)
2353 self.assertEqual(exitcode, self.exitcode)
2354
Berker Peksag4af23d72016-09-15 20:32:44 +03002355 @requires_os_func('spawnv')
Victor Stinner4659ccf2016-09-14 10:57:00 +02002356 def test_spawnv(self):
2357 args = self.create_args()
2358 exitcode = os.spawnv(os.P_WAIT, args[0], args)
2359 self.assertEqual(exitcode, self.exitcode)
2360
Berker Peksag4af23d72016-09-15 20:32:44 +03002361 @requires_os_func('spawnve')
Victor Stinner4659ccf2016-09-14 10:57:00 +02002362 def test_spawnve(self):
Berker Peksag47e70622016-09-15 20:23:55 +03002363 args = self.create_args(with_env=True)
Victor Stinner4659ccf2016-09-14 10:57:00 +02002364 exitcode = os.spawnve(os.P_WAIT, args[0], args, self.env)
2365 self.assertEqual(exitcode, self.exitcode)
2366
Berker Peksag4af23d72016-09-15 20:32:44 +03002367 @requires_os_func('spawnvp')
Victor Stinner4659ccf2016-09-14 10:57:00 +02002368 def test_spawnvp(self):
2369 args = self.create_args()
2370 exitcode = os.spawnvp(os.P_WAIT, args[0], args)
2371 self.assertEqual(exitcode, self.exitcode)
2372
Berker Peksag4af23d72016-09-15 20:32:44 +03002373 @requires_os_func('spawnvpe')
Victor Stinner4659ccf2016-09-14 10:57:00 +02002374 def test_spawnvpe(self):
Berker Peksag47e70622016-09-15 20:23:55 +03002375 args = self.create_args(with_env=True)
Victor Stinner4659ccf2016-09-14 10:57:00 +02002376 exitcode = os.spawnvpe(os.P_WAIT, args[0], args, self.env)
2377 self.assertEqual(exitcode, self.exitcode)
2378
Berker Peksag4af23d72016-09-15 20:32:44 +03002379 @requires_os_func('spawnv')
Victor Stinner4659ccf2016-09-14 10:57:00 +02002380 def test_nowait(self):
2381 args = self.create_args()
2382 pid = os.spawnv(os.P_NOWAIT, args[0], args)
2383 result = os.waitpid(pid, 0)
2384 self.assertEqual(result[0], pid)
2385 status = result[1]
2386 if hasattr(os, 'WIFEXITED'):
2387 self.assertTrue(os.WIFEXITED(status))
2388 self.assertEqual(os.WEXITSTATUS(status), self.exitcode)
2389 else:
2390 self.assertEqual(status, self.exitcode << 8)
2391
Berker Peksag4af23d72016-09-15 20:32:44 +03002392 @requires_os_func('spawnve')
Berker Peksag81816462016-09-15 20:19:47 +03002393 def test_spawnve_bytes(self):
2394 # Test bytes handling in parse_arglist and parse_envlist (#28114)
2395 args = self.create_args(with_env=True, use_bytes=True)
2396 exitcode = os.spawnve(os.P_WAIT, args[0], args, self.env)
2397 self.assertEqual(exitcode, self.exitcode)
2398
Steve Dower859fd7b2016-11-19 18:53:19 -08002399 @requires_os_func('spawnl')
2400 def test_spawnl_noargs(self):
2401 args = self.create_args()
2402 self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, args[0])
Steve Dowerbce26262016-11-19 19:17:26 -08002403 self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, args[0], '')
Steve Dower859fd7b2016-11-19 18:53:19 -08002404
2405 @requires_os_func('spawnle')
Steve Dowerbce26262016-11-19 19:17:26 -08002406 def test_spawnle_noargs(self):
Steve Dower859fd7b2016-11-19 18:53:19 -08002407 args = self.create_args()
2408 self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, args[0], {})
Steve Dowerbce26262016-11-19 19:17:26 -08002409 self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, args[0], '', {})
Steve Dower859fd7b2016-11-19 18:53:19 -08002410
2411 @requires_os_func('spawnv')
2412 def test_spawnv_noargs(self):
2413 args = self.create_args()
2414 self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], ())
2415 self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], [])
Steve Dowerbce26262016-11-19 19:17:26 -08002416 self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], ('',))
2417 self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], [''])
Steve Dower859fd7b2016-11-19 18:53:19 -08002418
2419 @requires_os_func('spawnve')
Steve Dowerbce26262016-11-19 19:17:26 -08002420 def test_spawnve_noargs(self):
Steve Dower859fd7b2016-11-19 18:53:19 -08002421 args = self.create_args()
2422 self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], (), {})
2423 self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], [], {})
Steve Dowerbce26262016-11-19 19:17:26 -08002424 self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], ('',), {})
2425 self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], [''], {})
Victor Stinner4659ccf2016-09-14 10:57:00 +02002426
Serhiy Storchakaaf5392f2017-06-25 09:48:54 +03002427 def _test_invalid_env(self, spawn):
Serhiy Storchaka77703942017-06-25 07:33:01 +03002428 args = [sys.executable, '-c', 'pass']
Serhiy Storchakaaf5392f2017-06-25 09:48:54 +03002429
Ville Skyttä49b27342017-08-03 09:00:59 +03002430 # null character in the environment variable name
Serhiy Storchaka77703942017-06-25 07:33:01 +03002431 newenv = os.environ.copy()
2432 newenv["FRUIT\0VEGETABLE"] = "cabbage"
2433 try:
Serhiy Storchakaaf5392f2017-06-25 09:48:54 +03002434 exitcode = spawn(os.P_WAIT, args[0], args, newenv)
Serhiy Storchaka77703942017-06-25 07:33:01 +03002435 except ValueError:
2436 pass
2437 else:
2438 self.assertEqual(exitcode, 127)
2439
Ville Skyttä49b27342017-08-03 09:00:59 +03002440 # null character in the environment variable value
Serhiy Storchaka77703942017-06-25 07:33:01 +03002441 newenv = os.environ.copy()
2442 newenv["FRUIT"] = "orange\0VEGETABLE=cabbage"
2443 try:
Serhiy Storchakaaf5392f2017-06-25 09:48:54 +03002444 exitcode = spawn(os.P_WAIT, args[0], args, newenv)
Serhiy Storchaka77703942017-06-25 07:33:01 +03002445 except ValueError:
2446 pass
2447 else:
2448 self.assertEqual(exitcode, 127)
2449
Ville Skyttä49b27342017-08-03 09:00:59 +03002450 # equal character in the environment variable name
Serhiy Storchaka77703942017-06-25 07:33:01 +03002451 newenv = os.environ.copy()
2452 newenv["FRUIT=ORANGE"] = "lemon"
2453 try:
Serhiy Storchakaaf5392f2017-06-25 09:48:54 +03002454 exitcode = spawn(os.P_WAIT, args[0], args, newenv)
Serhiy Storchaka77703942017-06-25 07:33:01 +03002455 except ValueError:
2456 pass
2457 else:
2458 self.assertEqual(exitcode, 127)
2459
Ville Skyttä49b27342017-08-03 09:00:59 +03002460 # equal character in the environment variable value
Serhiy Storchaka77703942017-06-25 07:33:01 +03002461 filename = support.TESTFN
2462 self.addCleanup(support.unlink, filename)
2463 with open(filename, "w") as fp:
2464 fp.write('import sys, os\n'
2465 'if os.getenv("FRUIT") != "orange=lemon":\n'
2466 ' raise AssertionError')
2467 args = [sys.executable, filename]
2468 newenv = os.environ.copy()
2469 newenv["FRUIT"] = "orange=lemon"
Serhiy Storchakaaf5392f2017-06-25 09:48:54 +03002470 exitcode = spawn(os.P_WAIT, args[0], args, newenv)
Serhiy Storchaka77703942017-06-25 07:33:01 +03002471 self.assertEqual(exitcode, 0)
2472
Serhiy Storchakaaf5392f2017-06-25 09:48:54 +03002473 @requires_os_func('spawnve')
2474 def test_spawnve_invalid_env(self):
2475 self._test_invalid_env(os.spawnve)
2476
2477 @requires_os_func('spawnvpe')
2478 def test_spawnvpe_invalid_env(self):
2479 self._test_invalid_env(os.spawnvpe)
2480
Serhiy Storchaka77703942017-06-25 07:33:01 +03002481
Brian Curtin0151b8e2010-09-24 13:43:43 +00002482# The introduction of this TestCase caused at least two different errors on
2483# *nix buildbots. Temporarily skip this to let the buildbots move along.
2484@unittest.skip("Skip due to platform/environment differences on *NIX buildbots")
Brian Curtine8e4b3b2010-09-23 20:04:14 +00002485@unittest.skipUnless(hasattr(os, 'getlogin'), "test needs os.getlogin")
2486class LoginTests(unittest.TestCase):
2487 def test_getlogin(self):
2488 user_name = os.getlogin()
2489 self.assertNotEqual(len(user_name), 0)
2490
2491
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00002492@unittest.skipUnless(hasattr(os, 'getpriority') and hasattr(os, 'setpriority'),
2493 "needs os.getpriority and os.setpriority")
2494class ProgramPriorityTests(unittest.TestCase):
2495 """Tests for os.getpriority() and os.setpriority()."""
2496
2497 def test_set_get_priority(self):
Giampaolo Rodolàcfbcec32011-02-28 19:27:16 +00002498
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00002499 base = os.getpriority(os.PRIO_PROCESS, os.getpid())
2500 os.setpriority(os.PRIO_PROCESS, os.getpid(), base + 1)
2501 try:
Giampaolo Rodolàcfbcec32011-02-28 19:27:16 +00002502 new_prio = os.getpriority(os.PRIO_PROCESS, os.getpid())
2503 if base >= 19 and new_prio <= 19:
Victor Stinnerae39d232016-03-24 17:12:55 +01002504 raise unittest.SkipTest("unable to reliably test setpriority "
2505 "at current nice level of %s" % base)
Giampaolo Rodolàcfbcec32011-02-28 19:27:16 +00002506 else:
2507 self.assertEqual(new_prio, base + 1)
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00002508 finally:
2509 try:
2510 os.setpriority(os.PRIO_PROCESS, os.getpid(), base)
2511 except OSError as err:
Antoine Pitrou692f0382011-02-26 00:22:25 +00002512 if err.errno != errno.EACCES:
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00002513 raise
2514
2515
Antoine Pitroua6a4dc82017-09-07 18:56:24 +02002516class SendfileTestServer(asyncore.dispatcher, threading.Thread):
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002517
Antoine Pitroua6a4dc82017-09-07 18:56:24 +02002518 class Handler(asynchat.async_chat):
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002519
Antoine Pitroua6a4dc82017-09-07 18:56:24 +02002520 def __init__(self, conn):
2521 asynchat.async_chat.__init__(self, conn)
2522 self.in_buffer = []
2523 self.closed = False
2524 self.push(b"220 ready\r\n")
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002525
Antoine Pitroua6a4dc82017-09-07 18:56:24 +02002526 def handle_read(self):
2527 data = self.recv(4096)
2528 self.in_buffer.append(data)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002529
Antoine Pitroua6a4dc82017-09-07 18:56:24 +02002530 def get_data(self):
2531 return b''.join(self.in_buffer)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002532
Antoine Pitroua6a4dc82017-09-07 18:56:24 +02002533 def handle_close(self):
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002534 self.close()
Antoine Pitroua6a4dc82017-09-07 18:56:24 +02002535 self.closed = True
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002536
2537 def handle_error(self):
2538 raise
2539
Antoine Pitroua6a4dc82017-09-07 18:56:24 +02002540 def __init__(self, address):
2541 threading.Thread.__init__(self)
2542 asyncore.dispatcher.__init__(self)
2543 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
2544 self.bind(address)
2545 self.listen(5)
2546 self.host, self.port = self.socket.getsockname()[:2]
2547 self.handler_instance = None
2548 self._active = False
2549 self._active_lock = threading.Lock()
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002550
Antoine Pitroua6a4dc82017-09-07 18:56:24 +02002551 # --- public API
2552
2553 @property
2554 def running(self):
2555 return self._active
2556
2557 def start(self):
2558 assert not self.running
2559 self.__flag = threading.Event()
2560 threading.Thread.start(self)
2561 self.__flag.wait()
2562
2563 def stop(self):
2564 assert self.running
2565 self._active = False
2566 self.join()
2567
2568 def wait(self):
2569 # wait for handler connection to be closed, then stop the server
2570 while not getattr(self.handler_instance, "closed", False):
2571 time.sleep(0.001)
2572 self.stop()
2573
2574 # --- internals
2575
2576 def run(self):
2577 self._active = True
2578 self.__flag.set()
2579 while self._active and asyncore.socket_map:
2580 self._active_lock.acquire()
2581 asyncore.loop(timeout=0.001, count=1)
2582 self._active_lock.release()
2583 asyncore.close_all()
2584
2585 def handle_accept(self):
2586 conn, addr = self.accept()
2587 self.handler_instance = self.Handler(conn)
2588
2589 def handle_connect(self):
2590 self.close()
2591 handle_read = handle_connect
2592
2593 def writable(self):
2594 return 0
2595
2596 def handle_error(self):
2597 raise
2598
2599
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002600@unittest.skipUnless(hasattr(os, 'sendfile'), "test needs os.sendfile()")
2601class TestSendfile(unittest.TestCase):
2602
Antoine Pitrou18dd0df2011-02-26 14:29:24 +00002603 DATA = b"12345abcde" * 16 * 1024 # 160 KB
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002604 SUPPORT_HEADERS_TRAILERS = not sys.platform.startswith("linux") and \
Giampaolo Rodolà4bc68572011-02-25 21:46:01 +00002605 not sys.platform.startswith("solaris") and \
2606 not sys.platform.startswith("sunos")
Serhiy Storchaka43767632013-11-03 21:31:38 +02002607 requires_headers_trailers = unittest.skipUnless(SUPPORT_HEADERS_TRAILERS,
2608 'requires headers and trailers support')
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002609
2610 @classmethod
2611 def setUpClass(cls):
R David Murrayf2ad1732014-12-25 18:36:56 -05002612 cls.key = support.threading_setup()
Victor Stinnerae39d232016-03-24 17:12:55 +01002613 create_file(support.TESTFN, cls.DATA)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002614
2615 @classmethod
2616 def tearDownClass(cls):
R David Murrayf2ad1732014-12-25 18:36:56 -05002617 support.threading_cleanup(*cls.key)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002618 support.unlink(support.TESTFN)
2619
2620 def setUp(self):
2621 self.server = SendfileTestServer((support.HOST, 0))
2622 self.server.start()
2623 self.client = socket.socket()
2624 self.client.connect((self.server.host, self.server.port))
2625 self.client.settimeout(1)
2626 # synchronize by waiting for "220 ready" response
2627 self.client.recv(1024)
2628 self.sockno = self.client.fileno()
2629 self.file = open(support.TESTFN, 'rb')
2630 self.fileno = self.file.fileno()
2631
2632 def tearDown(self):
2633 self.file.close()
2634 self.client.close()
2635 if self.server.running:
2636 self.server.stop()
Victor Stinnerd1cc0372017-07-12 16:05:43 +02002637 self.server = None
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002638
2639 def sendfile_wrapper(self, sock, file, offset, nbytes, headers=[], trailers=[]):
2640 """A higher level wrapper representing how an application is
2641 supposed to use sendfile().
2642 """
2643 while 1:
2644 try:
2645 if self.SUPPORT_HEADERS_TRAILERS:
2646 return os.sendfile(sock, file, offset, nbytes, headers,
2647 trailers)
2648 else:
2649 return os.sendfile(sock, file, offset, nbytes)
2650 except OSError as err:
2651 if err.errno == errno.ECONNRESET:
2652 # disconnected
2653 raise
2654 elif err.errno in (errno.EAGAIN, errno.EBUSY):
2655 # we have to retry send data
2656 continue
2657 else:
2658 raise
2659
2660 def test_send_whole_file(self):
2661 # normal send
2662 total_sent = 0
2663 offset = 0
2664 nbytes = 4096
Antoine Pitrou18dd0df2011-02-26 14:29:24 +00002665 while total_sent < len(self.DATA):
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002666 sent = self.sendfile_wrapper(self.sockno, self.fileno, offset, nbytes)
2667 if sent == 0:
2668 break
2669 offset += sent
2670 total_sent += sent
2671 self.assertTrue(sent <= nbytes)
2672 self.assertEqual(offset, total_sent)
2673
2674 self.assertEqual(total_sent, len(self.DATA))
Antoine Pitrou2de51ff2011-02-26 17:52:50 +00002675 self.client.shutdown(socket.SHUT_RDWR)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002676 self.client.close()
2677 self.server.wait()
2678 data = self.server.handler_instance.get_data()
Antoine Pitrou2de51ff2011-02-26 17:52:50 +00002679 self.assertEqual(len(data), len(self.DATA))
Antoine Pitrou18dd0df2011-02-26 14:29:24 +00002680 self.assertEqual(data, self.DATA)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002681
2682 def test_send_at_certain_offset(self):
2683 # start sending a file at a certain offset
2684 total_sent = 0
Antoine Pitrou18dd0df2011-02-26 14:29:24 +00002685 offset = len(self.DATA) // 2
2686 must_send = len(self.DATA) - offset
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002687 nbytes = 4096
Antoine Pitrou18dd0df2011-02-26 14:29:24 +00002688 while total_sent < must_send:
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002689 sent = self.sendfile_wrapper(self.sockno, self.fileno, offset, nbytes)
2690 if sent == 0:
2691 break
2692 offset += sent
2693 total_sent += sent
2694 self.assertTrue(sent <= nbytes)
2695
Antoine Pitrou2de51ff2011-02-26 17:52:50 +00002696 self.client.shutdown(socket.SHUT_RDWR)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002697 self.client.close()
2698 self.server.wait()
2699 data = self.server.handler_instance.get_data()
Antoine Pitrou18dd0df2011-02-26 14:29:24 +00002700 expected = self.DATA[len(self.DATA) // 2:]
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002701 self.assertEqual(total_sent, len(expected))
Antoine Pitrou2de51ff2011-02-26 17:52:50 +00002702 self.assertEqual(len(data), len(expected))
Antoine Pitrou18dd0df2011-02-26 14:29:24 +00002703 self.assertEqual(data, expected)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002704
2705 def test_offset_overflow(self):
2706 # specify an offset > file size
2707 offset = len(self.DATA) + 4096
Antoine Pitrou18dd0df2011-02-26 14:29:24 +00002708 try:
2709 sent = os.sendfile(self.sockno, self.fileno, offset, 4096)
2710 except OSError as e:
2711 # Solaris can raise EINVAL if offset >= file length, ignore.
2712 if e.errno != errno.EINVAL:
2713 raise
2714 else:
2715 self.assertEqual(sent, 0)
Antoine Pitrou2de51ff2011-02-26 17:52:50 +00002716 self.client.shutdown(socket.SHUT_RDWR)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002717 self.client.close()
2718 self.server.wait()
2719 data = self.server.handler_instance.get_data()
2720 self.assertEqual(data, b'')
2721
2722 def test_invalid_offset(self):
2723 with self.assertRaises(OSError) as cm:
2724 os.sendfile(self.sockno, self.fileno, -1, 4096)
2725 self.assertEqual(cm.exception.errno, errno.EINVAL)
2726
Martin Panterbf19d162015-09-09 01:01:13 +00002727 def test_keywords(self):
2728 # Keyword arguments should be supported
2729 os.sendfile(out=self.sockno, offset=0, count=4096,
2730 **{'in': self.fileno})
2731 if self.SUPPORT_HEADERS_TRAILERS:
2732 os.sendfile(self.sockno, self.fileno, offset=0, count=4096,
Martin Panter94994132015-09-09 05:29:24 +00002733 headers=(), trailers=(), flags=0)
Martin Panterbf19d162015-09-09 01:01:13 +00002734
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002735 # --- headers / trailers tests
2736
Serhiy Storchaka43767632013-11-03 21:31:38 +02002737 @requires_headers_trailers
2738 def test_headers(self):
2739 total_sent = 0
2740 sent = os.sendfile(self.sockno, self.fileno, 0, 4096,
2741 headers=[b"x" * 512])
2742 total_sent += sent
2743 offset = 4096
2744 nbytes = 4096
2745 while 1:
2746 sent = self.sendfile_wrapper(self.sockno, self.fileno,
2747 offset, nbytes)
2748 if sent == 0:
2749 break
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002750 total_sent += sent
Serhiy Storchaka43767632013-11-03 21:31:38 +02002751 offset += sent
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002752
Serhiy Storchaka43767632013-11-03 21:31:38 +02002753 expected_data = b"x" * 512 + self.DATA
2754 self.assertEqual(total_sent, len(expected_data))
2755 self.client.close()
2756 self.server.wait()
2757 data = self.server.handler_instance.get_data()
2758 self.assertEqual(hash(data), hash(expected_data))
2759
2760 @requires_headers_trailers
2761 def test_trailers(self):
2762 TESTFN2 = support.TESTFN + "2"
2763 file_data = b"abcdef"
Victor Stinnerae39d232016-03-24 17:12:55 +01002764
2765 self.addCleanup(support.unlink, TESTFN2)
2766 create_file(TESTFN2, file_data)
2767
2768 with open(TESTFN2, 'rb') as f:
Serhiy Storchaka43767632013-11-03 21:31:38 +02002769 os.sendfile(self.sockno, f.fileno(), 0, len(file_data),
2770 trailers=[b"1234"])
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002771 self.client.close()
2772 self.server.wait()
2773 data = self.server.handler_instance.get_data()
Serhiy Storchaka43767632013-11-03 21:31:38 +02002774 self.assertEqual(data, b"abcdef1234")
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002775
Serhiy Storchaka43767632013-11-03 21:31:38 +02002776 @requires_headers_trailers
2777 @unittest.skipUnless(hasattr(os, 'SF_NODISKIO'),
2778 'test needs os.SF_NODISKIO')
2779 def test_flags(self):
2780 try:
2781 os.sendfile(self.sockno, self.fileno, 0, 4096,
2782 flags=os.SF_NODISKIO)
2783 except OSError as err:
2784 if err.errno not in (errno.EBUSY, errno.EAGAIN):
2785 raise
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002786
2787
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788def supports_extended_attributes():
2789 if not hasattr(os, "setxattr"):
2790 return False
Victor Stinnerae39d232016-03-24 17:12:55 +01002791
Larry Hastings9cf065c2012-06-22 16:30:09 -07002792 try:
Victor Stinnerae39d232016-03-24 17:12:55 +01002793 with open(support.TESTFN, "xb", 0) as fp:
Larry Hastings9cf065c2012-06-22 16:30:09 -07002794 try:
2795 os.setxattr(fp.fileno(), b"user.test", b"")
2796 except OSError:
2797 return False
2798 finally:
2799 support.unlink(support.TESTFN)
Victor Stinnerf95a19b2016-03-24 16:50:41 +01002800
2801 return True
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802
2803
2804@unittest.skipUnless(supports_extended_attributes(),
2805 "no non-broken extended attribute support")
Victor Stinnerf95a19b2016-03-24 16:50:41 +01002806# Kernels < 2.6.39 don't respect setxattr flags.
2807@support.requires_linux_version(2, 6, 39)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002808class ExtendedAttributeTests(unittest.TestCase):
2809
Larry Hastings9cf065c2012-06-22 16:30:09 -07002810 def _check_xattrs_str(self, s, getxattr, setxattr, removexattr, listxattr, **kwargs):
Benjamin Peterson799bd802011-08-31 22:15:17 -04002811 fn = support.TESTFN
Victor Stinnerae39d232016-03-24 17:12:55 +01002812 self.addCleanup(support.unlink, fn)
2813 create_file(fn)
2814
Benjamin Peterson799bd802011-08-31 22:15:17 -04002815 with self.assertRaises(OSError) as cm:
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816 getxattr(fn, s("user.test"), **kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002817 self.assertEqual(cm.exception.errno, errno.ENODATA)
Victor Stinnerae39d232016-03-24 17:12:55 +01002818
Victor Stinnerf12e5062011-10-16 22:12:03 +02002819 init_xattr = listxattr(fn)
2820 self.assertIsInstance(init_xattr, list)
Victor Stinnerae39d232016-03-24 17:12:55 +01002821
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822 setxattr(fn, s("user.test"), b"", **kwargs)
Victor Stinnerf12e5062011-10-16 22:12:03 +02002823 xattr = set(init_xattr)
2824 xattr.add("user.test")
2825 self.assertEqual(set(listxattr(fn)), xattr)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002826 self.assertEqual(getxattr(fn, b"user.test", **kwargs), b"")
2827 setxattr(fn, s("user.test"), b"hello", os.XATTR_REPLACE, **kwargs)
2828 self.assertEqual(getxattr(fn, b"user.test", **kwargs), b"hello")
Victor Stinnerae39d232016-03-24 17:12:55 +01002829
Benjamin Peterson799bd802011-08-31 22:15:17 -04002830 with self.assertRaises(OSError) as cm:
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831 setxattr(fn, s("user.test"), b"bye", os.XATTR_CREATE, **kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002832 self.assertEqual(cm.exception.errno, errno.EEXIST)
Victor Stinnerae39d232016-03-24 17:12:55 +01002833
Benjamin Peterson799bd802011-08-31 22:15:17 -04002834 with self.assertRaises(OSError) as cm:
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 setxattr(fn, s("user.test2"), b"bye", os.XATTR_REPLACE, **kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002836 self.assertEqual(cm.exception.errno, errno.ENODATA)
Victor Stinnerae39d232016-03-24 17:12:55 +01002837
Larry Hastings9cf065c2012-06-22 16:30:09 -07002838 setxattr(fn, s("user.test2"), b"foo", os.XATTR_CREATE, **kwargs)
Victor Stinnerf12e5062011-10-16 22:12:03 +02002839 xattr.add("user.test2")
2840 self.assertEqual(set(listxattr(fn)), xattr)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002841 removexattr(fn, s("user.test"), **kwargs)
Victor Stinnerae39d232016-03-24 17:12:55 +01002842
Benjamin Peterson799bd802011-08-31 22:15:17 -04002843 with self.assertRaises(OSError) as cm:
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844 getxattr(fn, s("user.test"), **kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002845 self.assertEqual(cm.exception.errno, errno.ENODATA)
Victor Stinnerae39d232016-03-24 17:12:55 +01002846
Victor Stinnerf12e5062011-10-16 22:12:03 +02002847 xattr.remove("user.test")
2848 self.assertEqual(set(listxattr(fn)), xattr)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002849 self.assertEqual(getxattr(fn, s("user.test2"), **kwargs), b"foo")
2850 setxattr(fn, s("user.test"), b"a"*1024, **kwargs)
2851 self.assertEqual(getxattr(fn, s("user.test"), **kwargs), b"a"*1024)
2852 removexattr(fn, s("user.test"), **kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002853 many = sorted("user.test{}".format(i) for i in range(100))
2854 for thing in many:
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 setxattr(fn, thing, b"x", **kwargs)
Victor Stinnerf12e5062011-10-16 22:12:03 +02002856 self.assertEqual(set(listxattr(fn)), set(init_xattr) | set(many))
Benjamin Peterson799bd802011-08-31 22:15:17 -04002857
Larry Hastings9cf065c2012-06-22 16:30:09 -07002858 def _check_xattrs(self, *args, **kwargs):
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859 self._check_xattrs_str(str, *args, **kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002860 support.unlink(support.TESTFN)
Victor Stinnerae39d232016-03-24 17:12:55 +01002861
2862 self._check_xattrs_str(os.fsencode, *args, **kwargs)
2863 support.unlink(support.TESTFN)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002864
2865 def test_simple(self):
2866 self._check_xattrs(os.getxattr, os.setxattr, os.removexattr,
2867 os.listxattr)
2868
2869 def test_lpath(self):
Larry Hastings9cf065c2012-06-22 16:30:09 -07002870 self._check_xattrs(os.getxattr, os.setxattr, os.removexattr,
2871 os.listxattr, follow_symlinks=False)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002872
2873 def test_fds(self):
2874 def getxattr(path, *args):
2875 with open(path, "rb") as fp:
Larry Hastings9cf065c2012-06-22 16:30:09 -07002876 return os.getxattr(fp.fileno(), *args)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002877 def setxattr(path, *args):
Victor Stinnerae39d232016-03-24 17:12:55 +01002878 with open(path, "wb", 0) as fp:
Larry Hastings9cf065c2012-06-22 16:30:09 -07002879 os.setxattr(fp.fileno(), *args)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002880 def removexattr(path, *args):
Victor Stinnerae39d232016-03-24 17:12:55 +01002881 with open(path, "wb", 0) as fp:
Larry Hastings9cf065c2012-06-22 16:30:09 -07002882 os.removexattr(fp.fileno(), *args)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002883 def listxattr(path, *args):
2884 with open(path, "rb") as fp:
Larry Hastings9cf065c2012-06-22 16:30:09 -07002885 return os.listxattr(fp.fileno(), *args)
Benjamin Peterson799bd802011-08-31 22:15:17 -04002886 self._check_xattrs(getxattr, setxattr, removexattr, listxattr)
2887
2888
Antoine Pitroubcf2b592012-02-08 23:28:36 +01002889@unittest.skipUnless(hasattr(os, 'get_terminal_size'), "requires os.get_terminal_size")
2890class TermsizeTests(unittest.TestCase):
2891 def test_does_not_crash(self):
2892 """Check if get_terminal_size() returns a meaningful value.
2893
2894 There's no easy portable way to actually check the size of the
2895 terminal, so let's check if it returns something sensible instead.
2896 """
2897 try:
2898 size = os.get_terminal_size()
2899 except OSError as e:
Antoine Pitrou81a1fa52012-02-09 00:11:00 +01002900 if sys.platform == "win32" or e.errno in (errno.EINVAL, errno.ENOTTY):
Antoine Pitroubcf2b592012-02-08 23:28:36 +01002901 # Under win32 a generic OSError can be thrown if the
2902 # handle cannot be retrieved
2903 self.skipTest("failed to query terminal size")
2904 raise
2905
Antoine Pitroucfade362012-02-08 23:48:59 +01002906 self.assertGreaterEqual(size.columns, 0)
2907 self.assertGreaterEqual(size.lines, 0)
Antoine Pitroubcf2b592012-02-08 23:28:36 +01002908
2909 def test_stty_match(self):
2910 """Check if stty returns the same results
2911
2912 stty actually tests stdin, so get_terminal_size is invoked on
2913 stdin explicitly. If stty succeeded, then get_terminal_size()
2914 should work too.
2915 """
2916 try:
2917 size = subprocess.check_output(['stty', 'size']).decode().split()
2918 except (FileNotFoundError, subprocess.CalledProcessError):
2919 self.skipTest("stty invocation failed")
2920 expected = (int(size[1]), int(size[0])) # reversed order
2921
Antoine Pitrou81a1fa52012-02-09 00:11:00 +01002922 try:
2923 actual = os.get_terminal_size(sys.__stdin__.fileno())
2924 except OSError as e:
2925 if sys.platform == "win32" or e.errno in (errno.EINVAL, errno.ENOTTY):
2926 # Under win32 a generic OSError can be thrown if the
2927 # handle cannot be retrieved
2928 self.skipTest("failed to query terminal size")
2929 raise
Antoine Pitroubcf2b592012-02-08 23:28:36 +01002930 self.assertEqual(expected, actual)
2931
2932
Victor Stinner292c8352012-10-30 02:17:38 +01002933class OSErrorTests(unittest.TestCase):
2934 def setUp(self):
2935 class Str(str):
2936 pass
2937
Victor Stinnerafe17062012-10-31 22:47:43 +01002938 self.bytes_filenames = []
2939 self.unicode_filenames = []
Victor Stinner292c8352012-10-30 02:17:38 +01002940 if support.TESTFN_UNENCODABLE is not None:
2941 decoded = support.TESTFN_UNENCODABLE
2942 else:
2943 decoded = support.TESTFN
Victor Stinnerafe17062012-10-31 22:47:43 +01002944 self.unicode_filenames.append(decoded)
2945 self.unicode_filenames.append(Str(decoded))
Victor Stinner292c8352012-10-30 02:17:38 +01002946 if support.TESTFN_UNDECODABLE is not None:
2947 encoded = support.TESTFN_UNDECODABLE
2948 else:
2949 encoded = os.fsencode(support.TESTFN)
Victor Stinnerafe17062012-10-31 22:47:43 +01002950 self.bytes_filenames.append(encoded)
Serhiy Storchakad73c3182016-08-06 23:22:08 +03002951 self.bytes_filenames.append(bytearray(encoded))
Victor Stinnerafe17062012-10-31 22:47:43 +01002952 self.bytes_filenames.append(memoryview(encoded))
2953
2954 self.filenames = self.bytes_filenames + self.unicode_filenames
Victor Stinner292c8352012-10-30 02:17:38 +01002955
2956 def test_oserror_filename(self):
2957 funcs = [
Victor Stinnerafe17062012-10-31 22:47:43 +01002958 (self.filenames, os.chdir,),
2959 (self.filenames, os.chmod, 0o777),
Victor Stinnerafe17062012-10-31 22:47:43 +01002960 (self.filenames, os.lstat,),
2961 (self.filenames, os.open, os.O_RDONLY),
2962 (self.filenames, os.rmdir,),
2963 (self.filenames, os.stat,),
2964 (self.filenames, os.unlink,),
Victor Stinner292c8352012-10-30 02:17:38 +01002965 ]
2966 if sys.platform == "win32":
2967 funcs.extend((
Victor Stinnerafe17062012-10-31 22:47:43 +01002968 (self.bytes_filenames, os.rename, b"dst"),
2969 (self.bytes_filenames, os.replace, b"dst"),
2970 (self.unicode_filenames, os.rename, "dst"),
2971 (self.unicode_filenames, os.replace, "dst"),
Steve Dowercc16be82016-09-08 10:35:16 -07002972 (self.unicode_filenames, os.listdir, ),
Victor Stinner292c8352012-10-30 02:17:38 +01002973 ))
Victor Stinnerafe17062012-10-31 22:47:43 +01002974 else:
2975 funcs.extend((
Victor Stinner64e039a2012-11-07 00:10:14 +01002976 (self.filenames, os.listdir,),
Victor Stinnerafe17062012-10-31 22:47:43 +01002977 (self.filenames, os.rename, "dst"),
2978 (self.filenames, os.replace, "dst"),
2979 ))
2980 if hasattr(os, "chown"):
2981 funcs.append((self.filenames, os.chown, 0, 0))
2982 if hasattr(os, "lchown"):
2983 funcs.append((self.filenames, os.lchown, 0, 0))
2984 if hasattr(os, "truncate"):
2985 funcs.append((self.filenames, os.truncate, 0))
Victor Stinner292c8352012-10-30 02:17:38 +01002986 if hasattr(os, "chflags"):
Victor Stinneree36c242012-11-13 09:31:51 +01002987 funcs.append((self.filenames, os.chflags, 0))
2988 if hasattr(os, "lchflags"):
2989 funcs.append((self.filenames, os.lchflags, 0))
Victor Stinner292c8352012-10-30 02:17:38 +01002990 if hasattr(os, "chroot"):
Victor Stinnerafe17062012-10-31 22:47:43 +01002991 funcs.append((self.filenames, os.chroot,))
Victor Stinner292c8352012-10-30 02:17:38 +01002992 if hasattr(os, "link"):
Victor Stinnerafe17062012-10-31 22:47:43 +01002993 if sys.platform == "win32":
2994 funcs.append((self.bytes_filenames, os.link, b"dst"))
2995 funcs.append((self.unicode_filenames, os.link, "dst"))
2996 else:
2997 funcs.append((self.filenames, os.link, "dst"))
Victor Stinner292c8352012-10-30 02:17:38 +01002998 if hasattr(os, "listxattr"):
2999 funcs.extend((
Victor Stinnerafe17062012-10-31 22:47:43 +01003000 (self.filenames, os.listxattr,),
3001 (self.filenames, os.getxattr, "user.test"),
3002 (self.filenames, os.setxattr, "user.test", b'user'),
3003 (self.filenames, os.removexattr, "user.test"),
Victor Stinner292c8352012-10-30 02:17:38 +01003004 ))
3005 if hasattr(os, "lchmod"):
Victor Stinnerafe17062012-10-31 22:47:43 +01003006 funcs.append((self.filenames, os.lchmod, 0o777))
Victor Stinner292c8352012-10-30 02:17:38 +01003007 if hasattr(os, "readlink"):
Victor Stinnerafe17062012-10-31 22:47:43 +01003008 if sys.platform == "win32":
3009 funcs.append((self.unicode_filenames, os.readlink,))
3010 else:
3011 funcs.append((self.filenames, os.readlink,))
Victor Stinner292c8352012-10-30 02:17:38 +01003012
Steve Dowercc16be82016-09-08 10:35:16 -07003013
Victor Stinnerafe17062012-10-31 22:47:43 +01003014 for filenames, func, *func_args in funcs:
3015 for name in filenames:
Victor Stinner292c8352012-10-30 02:17:38 +01003016 try:
Steve Dowercc16be82016-09-08 10:35:16 -07003017 if isinstance(name, (str, bytes)):
Victor Stinner923590e2016-03-24 09:11:48 +01003018 func(name, *func_args)
Serhiy Storchakad73c3182016-08-06 23:22:08 +03003019 else:
3020 with self.assertWarnsRegex(DeprecationWarning, 'should be'):
3021 func(name, *func_args)
Victor Stinnerbd54f0e2012-10-31 01:12:55 +01003022 except OSError as err:
Steve Dowercc16be82016-09-08 10:35:16 -07003023 self.assertIs(err.filename, name, str(func))
Steve Dower78057b42016-11-06 19:35:08 -08003024 except UnicodeDecodeError:
3025 pass
Victor Stinner292c8352012-10-30 02:17:38 +01003026 else:
3027 self.fail("No exception thrown by {}".format(func))
3028
Charles-Francois Natali44feda32013-05-20 14:40:46 +02003029class CPUCountTests(unittest.TestCase):
3030 def test_cpu_count(self):
3031 cpus = os.cpu_count()
3032 if cpus is not None:
3033 self.assertIsInstance(cpus, int)
3034 self.assertGreater(cpus, 0)
3035 else:
3036 self.skipTest("Could not determine the number of CPUs")
3037
Victor Stinnerdaf45552013-08-28 00:53:59 +02003038
3039class FDInheritanceTests(unittest.TestCase):
Victor Stinner7ba6b0f2013-09-08 11:47:54 +02003040 def test_get_set_inheritable(self):
Victor Stinnerdaf45552013-08-28 00:53:59 +02003041 fd = os.open(__file__, os.O_RDONLY)
3042 self.addCleanup(os.close, fd)
Victor Stinner7ba6b0f2013-09-08 11:47:54 +02003043 self.assertEqual(os.get_inheritable(fd), False)
Victor Stinnerdaf45552013-08-28 00:53:59 +02003044
Victor Stinnerdaf45552013-08-28 00:53:59 +02003045 os.set_inheritable(fd, True)
3046 self.assertEqual(os.get_inheritable(fd), True)
3047
Victor Stinner4f7a36f2013-09-08 14:14:38 +02003048 @unittest.skipIf(fcntl is None, "need fcntl")
3049 def test_get_inheritable_cloexec(self):
3050 fd = os.open(__file__, os.O_RDONLY)
3051 self.addCleanup(os.close, fd)
3052 self.assertEqual(os.get_inheritable(fd), False)
Victor Stinner7ba6b0f2013-09-08 11:47:54 +02003053
Victor Stinner4f7a36f2013-09-08 14:14:38 +02003054 # clear FD_CLOEXEC flag
3055 flags = fcntl.fcntl(fd, fcntl.F_GETFD)
3056 flags &= ~fcntl.FD_CLOEXEC
3057 fcntl.fcntl(fd, fcntl.F_SETFD, flags)
Victor Stinner7ba6b0f2013-09-08 11:47:54 +02003058
Victor Stinner4f7a36f2013-09-08 14:14:38 +02003059 self.assertEqual(os.get_inheritable(fd), True)
Victor Stinner7ba6b0f2013-09-08 11:47:54 +02003060
Victor Stinner4f7a36f2013-09-08 14:14:38 +02003061 @unittest.skipIf(fcntl is None, "need fcntl")
3062 def test_set_inheritable_cloexec(self):
3063 fd = os.open(__file__, os.O_RDONLY)
3064 self.addCleanup(os.close, fd)
3065 self.assertEqual(fcntl.fcntl(fd, fcntl.F_GETFD) & fcntl.FD_CLOEXEC,
3066 fcntl.FD_CLOEXEC)
Victor Stinner7ba6b0f2013-09-08 11:47:54 +02003067
Victor Stinner4f7a36f2013-09-08 14:14:38 +02003068 os.set_inheritable(fd, True)
3069 self.assertEqual(fcntl.fcntl(fd, fcntl.F_GETFD) & fcntl.FD_CLOEXEC,
3070 0)
Victor Stinner7ba6b0f2013-09-08 11:47:54 +02003071
Victor Stinnerdaf45552013-08-28 00:53:59 +02003072 def test_open(self):
3073 fd = os.open(__file__, os.O_RDONLY)
3074 self.addCleanup(os.close, fd)
3075 self.assertEqual(os.get_inheritable(fd), False)
3076
3077 @unittest.skipUnless(hasattr(os, 'pipe'), "need os.pipe()")
3078 def test_pipe(self):
3079 rfd, wfd = os.pipe()
3080 self.addCleanup(os.close, rfd)
3081 self.addCleanup(os.close, wfd)
3082 self.assertEqual(os.get_inheritable(rfd), False)
3083 self.assertEqual(os.get_inheritable(wfd), False)
3084
3085 def test_dup(self):
3086 fd1 = os.open(__file__, os.O_RDONLY)
3087 self.addCleanup(os.close, fd1)
3088
3089 fd2 = os.dup(fd1)
3090 self.addCleanup(os.close, fd2)
3091 self.assertEqual(os.get_inheritable(fd2), False)
3092
3093 @unittest.skipUnless(hasattr(os, 'dup2'), "need os.dup2()")
3094 def test_dup2(self):
3095 fd = os.open(__file__, os.O_RDONLY)
3096 self.addCleanup(os.close, fd)
3097
3098 # inheritable by default
3099 fd2 = os.open(__file__, os.O_RDONLY)
3100 try:
3101 os.dup2(fd, fd2)
3102 self.assertEqual(os.get_inheritable(fd2), True)
3103 finally:
3104 os.close(fd2)
3105
3106 # force non-inheritable
3107 fd3 = os.open(__file__, os.O_RDONLY)
3108 try:
3109 os.dup2(fd, fd3, inheritable=False)
3110 self.assertEqual(os.get_inheritable(fd3), False)
3111 finally:
3112 os.close(fd3)
3113
3114 @unittest.skipUnless(hasattr(os, 'openpty'), "need os.openpty()")
3115 def test_openpty(self):
3116 master_fd, slave_fd = os.openpty()
3117 self.addCleanup(os.close, master_fd)
3118 self.addCleanup(os.close, slave_fd)
3119 self.assertEqual(os.get_inheritable(master_fd), False)
3120 self.assertEqual(os.get_inheritable(slave_fd), False)
3121
3122
Brett Cannon3f9183b2016-08-26 14:44:48 -07003123class PathTConverterTests(unittest.TestCase):
3124 # tuples of (function name, allows fd arguments, additional arguments to
3125 # function, cleanup function)
3126 functions = [
3127 ('stat', True, (), None),
3128 ('lstat', False, (), None),
Benjamin Petersona9ab1652016-09-05 15:40:59 -07003129 ('access', False, (os.F_OK,), None),
Brett Cannon3f9183b2016-08-26 14:44:48 -07003130 ('chflags', False, (0,), None),
3131 ('lchflags', False, (0,), None),
3132 ('open', False, (0,), getattr(os, 'close', None)),
3133 ]
3134
3135 def test_path_t_converter(self):
Brett Cannon3f9183b2016-08-26 14:44:48 -07003136 str_filename = support.TESTFN
Brett Cannon3ce2fd42016-08-27 09:42:40 -07003137 if os.name == 'nt':
3138 bytes_fspath = bytes_filename = None
3139 else:
3140 bytes_filename = support.TESTFN.encode('ascii')
Brett Cannonec6ce872016-09-06 15:50:29 -07003141 bytes_fspath = _PathLike(bytes_filename)
3142 fd = os.open(_PathLike(str_filename), os.O_WRONLY|os.O_CREAT)
Brett Cannon3f9183b2016-08-26 14:44:48 -07003143 self.addCleanup(support.unlink, support.TESTFN)
Berker Peksagd0f5bab2016-08-27 21:26:35 +03003144 self.addCleanup(os.close, fd)
Brett Cannon3f9183b2016-08-26 14:44:48 -07003145
Brett Cannonec6ce872016-09-06 15:50:29 -07003146 int_fspath = _PathLike(fd)
3147 str_fspath = _PathLike(str_filename)
Brett Cannon3f9183b2016-08-26 14:44:48 -07003148
3149 for name, allow_fd, extra_args, cleanup_fn in self.functions:
3150 with self.subTest(name=name):
3151 try:
3152 fn = getattr(os, name)
3153 except AttributeError:
3154 continue
3155
Brett Cannon8f96a302016-08-26 19:30:11 -07003156 for path in (str_filename, bytes_filename, str_fspath,
3157 bytes_fspath):
Brett Cannon3ce2fd42016-08-27 09:42:40 -07003158 if path is None:
3159 continue
Brett Cannon3f9183b2016-08-26 14:44:48 -07003160 with self.subTest(name=name, path=path):
3161 result = fn(path, *extra_args)
3162 if cleanup_fn is not None:
3163 cleanup_fn(result)
3164
3165 with self.assertRaisesRegex(
3166 TypeError, 'should be string, bytes'):
3167 fn(int_fspath, *extra_args)
Brett Cannon3f9183b2016-08-26 14:44:48 -07003168
3169 if allow_fd:
3170 result = fn(fd, *extra_args) # should not fail
3171 if cleanup_fn is not None:
3172 cleanup_fn(result)
3173 else:
3174 with self.assertRaisesRegex(
3175 TypeError,
3176 'os.PathLike'):
3177 fn(fd, *extra_args)
3178
3179
Victor Stinner1db9e7b2014-07-29 22:32:47 +02003180@unittest.skipUnless(hasattr(os, 'get_blocking'),
3181 'needs os.get_blocking() and os.set_blocking()')
3182class BlockingTests(unittest.TestCase):
3183 def test_blocking(self):
3184 fd = os.open(__file__, os.O_RDONLY)
3185 self.addCleanup(os.close, fd)
3186 self.assertEqual(os.get_blocking(fd), True)
3187
3188 os.set_blocking(fd, False)
3189 self.assertEqual(os.get_blocking(fd), False)
3190
3191 os.set_blocking(fd, True)
3192 self.assertEqual(os.get_blocking(fd), True)
3193
3194
Yury Selivanov97e2e062014-09-26 12:33:06 -04003195
3196class ExportsTests(unittest.TestCase):
3197 def test_os_all(self):
3198 self.assertIn('open', os.__all__)
3199 self.assertIn('walk', os.__all__)
3200
3201
Victor Stinner6036e442015-03-08 01:58:04 +01003202class TestScandir(unittest.TestCase):
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +02003203 check_no_resource_warning = support.check_no_resource_warning
3204
Victor Stinner6036e442015-03-08 01:58:04 +01003205 def setUp(self):
3206 self.path = os.path.realpath(support.TESTFN)
Brett Cannon96881cd2016-06-10 14:37:21 -07003207 self.bytes_path = os.fsencode(self.path)
Victor Stinner6036e442015-03-08 01:58:04 +01003208 self.addCleanup(support.rmtree, self.path)
3209 os.mkdir(self.path)
3210
3211 def create_file(self, name="file.txt"):
Brett Cannon96881cd2016-06-10 14:37:21 -07003212 path = self.bytes_path if isinstance(name, bytes) else self.path
3213 filename = os.path.join(path, name)
Victor Stinnerae39d232016-03-24 17:12:55 +01003214 create_file(filename, b'python')
Victor Stinner6036e442015-03-08 01:58:04 +01003215 return filename
3216
3217 def get_entries(self, names):
3218 entries = dict((entry.name, entry)
3219 for entry in os.scandir(self.path))
3220 self.assertEqual(sorted(entries.keys()), names)
3221 return entries
3222
3223 def assert_stat_equal(self, stat1, stat2, skip_fields):
3224 if skip_fields:
3225 for attr in dir(stat1):
3226 if not attr.startswith("st_"):
3227 continue
3228 if attr in ("st_dev", "st_ino", "st_nlink"):
3229 continue
3230 self.assertEqual(getattr(stat1, attr),
3231 getattr(stat2, attr),
3232 (stat1, stat2, attr))
3233 else:
3234 self.assertEqual(stat1, stat2)
3235
3236 def check_entry(self, entry, name, is_dir, is_file, is_symlink):
Brett Cannona32c4d02016-06-24 14:14:44 -07003237 self.assertIsInstance(entry, os.DirEntry)
Victor Stinner6036e442015-03-08 01:58:04 +01003238 self.assertEqual(entry.name, name)
3239 self.assertEqual(entry.path, os.path.join(self.path, name))
3240 self.assertEqual(entry.inode(),
3241 os.stat(entry.path, follow_symlinks=False).st_ino)
3242
3243 entry_stat = os.stat(entry.path)
3244 self.assertEqual(entry.is_dir(),
3245 stat.S_ISDIR(entry_stat.st_mode))
3246 self.assertEqual(entry.is_file(),
3247 stat.S_ISREG(entry_stat.st_mode))
3248 self.assertEqual(entry.is_symlink(),
3249 os.path.islink(entry.path))
3250
3251 entry_lstat = os.stat(entry.path, follow_symlinks=False)
3252 self.assertEqual(entry.is_dir(follow_symlinks=False),
3253 stat.S_ISDIR(entry_lstat.st_mode))
3254 self.assertEqual(entry.is_file(follow_symlinks=False),
3255 stat.S_ISREG(entry_lstat.st_mode))
3256
3257 self.assert_stat_equal(entry.stat(),
3258 entry_stat,
3259 os.name == 'nt' and not is_symlink)
3260 self.assert_stat_equal(entry.stat(follow_symlinks=False),
3261 entry_lstat,
3262 os.name == 'nt')
3263
3264 def test_attributes(self):
3265 link = hasattr(os, 'link')
3266 symlink = support.can_symlink()
3267
3268 dirname = os.path.join(self.path, "dir")
3269 os.mkdir(dirname)
3270 filename = self.create_file("file.txt")
3271 if link:
3272 os.link(filename, os.path.join(self.path, "link_file.txt"))
3273 if symlink:
3274 os.symlink(dirname, os.path.join(self.path, "symlink_dir"),
3275 target_is_directory=True)
3276 os.symlink(filename, os.path.join(self.path, "symlink_file.txt"))
3277
3278 names = ['dir', 'file.txt']
3279 if link:
3280 names.append('link_file.txt')
3281 if symlink:
3282 names.extend(('symlink_dir', 'symlink_file.txt'))
3283 entries = self.get_entries(names)
3284
3285 entry = entries['dir']
3286 self.check_entry(entry, 'dir', True, False, False)
3287
3288 entry = entries['file.txt']
3289 self.check_entry(entry, 'file.txt', False, True, False)
3290
3291 if link:
3292 entry = entries['link_file.txt']
3293 self.check_entry(entry, 'link_file.txt', False, True, False)
3294
3295 if symlink:
3296 entry = entries['symlink_dir']
3297 self.check_entry(entry, 'symlink_dir', True, False, True)
3298
3299 entry = entries['symlink_file.txt']
3300 self.check_entry(entry, 'symlink_file.txt', False, True, True)
3301
3302 def get_entry(self, name):
Brett Cannon96881cd2016-06-10 14:37:21 -07003303 path = self.bytes_path if isinstance(name, bytes) else self.path
3304 entries = list(os.scandir(path))
Victor Stinner6036e442015-03-08 01:58:04 +01003305 self.assertEqual(len(entries), 1)
3306
3307 entry = entries[0]
3308 self.assertEqual(entry.name, name)
3309 return entry
3310
Brett Cannon96881cd2016-06-10 14:37:21 -07003311 def create_file_entry(self, name='file.txt'):
3312 filename = self.create_file(name=name)
Victor Stinner6036e442015-03-08 01:58:04 +01003313 return self.get_entry(os.path.basename(filename))
3314
3315 def test_current_directory(self):
3316 filename = self.create_file()
3317 old_dir = os.getcwd()
3318 try:
3319 os.chdir(self.path)
3320
3321 # call scandir() without parameter: it must list the content
3322 # of the current directory
3323 entries = dict((entry.name, entry) for entry in os.scandir())
3324 self.assertEqual(sorted(entries.keys()),
3325 [os.path.basename(filename)])
3326 finally:
3327 os.chdir(old_dir)
3328
3329 def test_repr(self):
3330 entry = self.create_file_entry()
3331 self.assertEqual(repr(entry), "<DirEntry 'file.txt'>")
3332
Brett Cannon96881cd2016-06-10 14:37:21 -07003333 def test_fspath_protocol(self):
3334 entry = self.create_file_entry()
3335 self.assertEqual(os.fspath(entry), os.path.join(self.path, 'file.txt'))
3336
3337 def test_fspath_protocol_bytes(self):
3338 bytes_filename = os.fsencode('bytesfile.txt')
3339 bytes_entry = self.create_file_entry(name=bytes_filename)
3340 fspath = os.fspath(bytes_entry)
3341 self.assertIsInstance(fspath, bytes)
3342 self.assertEqual(fspath,
3343 os.path.join(os.fsencode(self.path),bytes_filename))
3344
Victor Stinner6036e442015-03-08 01:58:04 +01003345 def test_removed_dir(self):
3346 path = os.path.join(self.path, 'dir')
3347
3348 os.mkdir(path)
3349 entry = self.get_entry('dir')
3350 os.rmdir(path)
3351
3352 # On POSIX, is_dir() result depends if scandir() filled d_type or not
3353 if os.name == 'nt':
3354 self.assertTrue(entry.is_dir())
3355 self.assertFalse(entry.is_file())
3356 self.assertFalse(entry.is_symlink())
3357 if os.name == 'nt':
3358 self.assertRaises(FileNotFoundError, entry.inode)
3359 # don't fail
3360 entry.stat()
3361 entry.stat(follow_symlinks=False)
3362 else:
3363 self.assertGreater(entry.inode(), 0)
3364 self.assertRaises(FileNotFoundError, entry.stat)
3365 self.assertRaises(FileNotFoundError, entry.stat, follow_symlinks=False)
3366
3367 def test_removed_file(self):
3368 entry = self.create_file_entry()
3369 os.unlink(entry.path)
3370
3371 self.assertFalse(entry.is_dir())
3372 # On POSIX, is_dir() result depends if scandir() filled d_type or not
3373 if os.name == 'nt':
3374 self.assertTrue(entry.is_file())
3375 self.assertFalse(entry.is_symlink())
3376 if os.name == 'nt':
3377 self.assertRaises(FileNotFoundError, entry.inode)
3378 # don't fail
3379 entry.stat()
3380 entry.stat(follow_symlinks=False)
3381 else:
3382 self.assertGreater(entry.inode(), 0)
3383 self.assertRaises(FileNotFoundError, entry.stat)
3384 self.assertRaises(FileNotFoundError, entry.stat, follow_symlinks=False)
3385
3386 def test_broken_symlink(self):
3387 if not support.can_symlink():
3388 return self.skipTest('cannot create symbolic link')
3389
3390 filename = self.create_file("file.txt")
3391 os.symlink(filename,
3392 os.path.join(self.path, "symlink.txt"))
3393 entries = self.get_entries(['file.txt', 'symlink.txt'])
3394 entry = entries['symlink.txt']
3395 os.unlink(filename)
3396
3397 self.assertGreater(entry.inode(), 0)
3398 self.assertFalse(entry.is_dir())
3399 self.assertFalse(entry.is_file()) # broken symlink returns False
3400 self.assertFalse(entry.is_dir(follow_symlinks=False))
3401 self.assertFalse(entry.is_file(follow_symlinks=False))
3402 self.assertTrue(entry.is_symlink())
3403 self.assertRaises(FileNotFoundError, entry.stat)
3404 # don't fail
3405 entry.stat(follow_symlinks=False)
3406
3407 def test_bytes(self):
Victor Stinner6036e442015-03-08 01:58:04 +01003408 self.create_file("file.txt")
3409
3410 path_bytes = os.fsencode(self.path)
3411 entries = list(os.scandir(path_bytes))
3412 self.assertEqual(len(entries), 1, entries)
3413 entry = entries[0]
3414
3415 self.assertEqual(entry.name, b'file.txt')
3416 self.assertEqual(entry.path,
3417 os.fsencode(os.path.join(self.path, 'file.txt')))
3418
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003419 def test_bytes_like(self):
3420 self.create_file("file.txt")
3421
3422 for cls in bytearray, memoryview:
3423 path_bytes = cls(os.fsencode(self.path))
3424 with self.assertWarns(DeprecationWarning):
3425 entries = list(os.scandir(path_bytes))
3426 self.assertEqual(len(entries), 1, entries)
3427 entry = entries[0]
3428
3429 self.assertEqual(entry.name, b'file.txt')
3430 self.assertEqual(entry.path,
3431 os.fsencode(os.path.join(self.path, 'file.txt')))
3432 self.assertIs(type(entry.name), bytes)
3433 self.assertIs(type(entry.path), bytes)
3434
Serhiy Storchakaea720fe2017-03-30 09:12:31 +03003435 @unittest.skipUnless(os.listdir in os.supports_fd,
3436 'fd support for listdir required for this test.')
3437 def test_fd(self):
3438 self.assertIn(os.scandir, os.supports_fd)
3439 self.create_file('file.txt')
3440 expected_names = ['file.txt']
3441 if support.can_symlink():
3442 os.symlink('file.txt', os.path.join(self.path, 'link'))
3443 expected_names.append('link')
3444
3445 fd = os.open(self.path, os.O_RDONLY)
3446 try:
3447 with os.scandir(fd) as it:
3448 entries = list(it)
3449 names = [entry.name for entry in entries]
3450 self.assertEqual(sorted(names), expected_names)
3451 self.assertEqual(names, os.listdir(fd))
3452 for entry in entries:
3453 self.assertEqual(entry.path, entry.name)
3454 self.assertEqual(os.fspath(entry), entry.name)
3455 self.assertEqual(entry.is_symlink(), entry.name == 'link')
3456 if os.stat in os.supports_dir_fd:
3457 st = os.stat(entry.name, dir_fd=fd)
3458 self.assertEqual(entry.stat(), st)
3459 st = os.stat(entry.name, dir_fd=fd, follow_symlinks=False)
3460 self.assertEqual(entry.stat(follow_symlinks=False), st)
3461 finally:
3462 os.close(fd)
3463
Victor Stinner6036e442015-03-08 01:58:04 +01003464 def test_empty_path(self):
3465 self.assertRaises(FileNotFoundError, os.scandir, '')
3466
3467 def test_consume_iterator_twice(self):
3468 self.create_file("file.txt")
3469 iterator = os.scandir(self.path)
3470
3471 entries = list(iterator)
3472 self.assertEqual(len(entries), 1, entries)
3473
3474 # check than consuming the iterator twice doesn't raise exception
3475 entries2 = list(iterator)
3476 self.assertEqual(len(entries2), 0, entries2)
3477
3478 def test_bad_path_type(self):
Serhiy Storchakaea720fe2017-03-30 09:12:31 +03003479 for obj in [1.234, {}, []]:
Victor Stinner6036e442015-03-08 01:58:04 +01003480 self.assertRaises(TypeError, os.scandir, obj)
3481
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +02003482 def test_close(self):
3483 self.create_file("file.txt")
3484 self.create_file("file2.txt")
3485 iterator = os.scandir(self.path)
3486 next(iterator)
3487 iterator.close()
3488 # multiple closes
3489 iterator.close()
3490 with self.check_no_resource_warning():
3491 del iterator
3492
3493 def test_context_manager(self):
3494 self.create_file("file.txt")
3495 self.create_file("file2.txt")
3496 with os.scandir(self.path) as iterator:
3497 next(iterator)
3498 with self.check_no_resource_warning():
3499 del iterator
3500
3501 def test_context_manager_close(self):
3502 self.create_file("file.txt")
3503 self.create_file("file2.txt")
3504 with os.scandir(self.path) as iterator:
3505 next(iterator)
3506 iterator.close()
3507
3508 def test_context_manager_exception(self):
3509 self.create_file("file.txt")
3510 self.create_file("file2.txt")
3511 with self.assertRaises(ZeroDivisionError):
3512 with os.scandir(self.path) as iterator:
3513 next(iterator)
3514 1/0
3515 with self.check_no_resource_warning():
3516 del iterator
3517
3518 def test_resource_warning(self):
3519 self.create_file("file.txt")
3520 self.create_file("file2.txt")
3521 iterator = os.scandir(self.path)
3522 next(iterator)
3523 with self.assertWarns(ResourceWarning):
3524 del iterator
3525 support.gc_collect()
3526 # exhausted iterator
3527 iterator = os.scandir(self.path)
3528 list(iterator)
3529 with self.check_no_resource_warning():
3530 del iterator
3531
Victor Stinner6036e442015-03-08 01:58:04 +01003532
Ethan Furmancdc08792016-06-02 15:06:09 -07003533class TestPEP519(unittest.TestCase):
Brett Cannonc78ca1e2016-06-24 12:03:43 -07003534
3535 # Abstracted so it can be overridden to test pure Python implementation
3536 # if a C version is provided.
3537 fspath = staticmethod(os.fspath)
3538
Ethan Furmancdc08792016-06-02 15:06:09 -07003539 def test_return_bytes(self):
3540 for b in b'hello', b'goodbye', b'some/path/and/file':
Brett Cannonc78ca1e2016-06-24 12:03:43 -07003541 self.assertEqual(b, self.fspath(b))
Ethan Furmancdc08792016-06-02 15:06:09 -07003542
3543 def test_return_string(self):
3544 for s in 'hello', 'goodbye', 'some/path/and/file':
Brett Cannonc78ca1e2016-06-24 12:03:43 -07003545 self.assertEqual(s, self.fspath(s))
Ethan Furmancdc08792016-06-02 15:06:09 -07003546
Brett Cannonc78ca1e2016-06-24 12:03:43 -07003547 def test_fsencode_fsdecode(self):
Ethan Furmanc1cbeed2016-06-04 10:19:27 -07003548 for p in "path/like/object", b"path/like/object":
Brett Cannonec6ce872016-09-06 15:50:29 -07003549 pathlike = _PathLike(p)
Ethan Furmanc1cbeed2016-06-04 10:19:27 -07003550
Brett Cannonc78ca1e2016-06-24 12:03:43 -07003551 self.assertEqual(p, self.fspath(pathlike))
Ethan Furmanc1cbeed2016-06-04 10:19:27 -07003552 self.assertEqual(b"path/like/object", os.fsencode(pathlike))
3553 self.assertEqual("path/like/object", os.fsdecode(pathlike))
3554
Brett Cannonc78ca1e2016-06-24 12:03:43 -07003555 def test_pathlike(self):
Brett Cannonec6ce872016-09-06 15:50:29 -07003556 self.assertEqual('#feelthegil', self.fspath(_PathLike('#feelthegil')))
3557 self.assertTrue(issubclass(_PathLike, os.PathLike))
3558 self.assertTrue(isinstance(_PathLike(), os.PathLike))
Ethan Furman410ef8e2016-06-04 12:06:26 -07003559
Ethan Furmancdc08792016-06-02 15:06:09 -07003560 def test_garbage_in_exception_out(self):
3561 vapor = type('blah', (), {})
3562 for o in int, type, os, vapor():
Brett Cannonc78ca1e2016-06-24 12:03:43 -07003563 self.assertRaises(TypeError, self.fspath, o)
Ethan Furmancdc08792016-06-02 15:06:09 -07003564
3565 def test_argument_required(self):
Brett Cannon044283a2016-07-15 10:41:49 -07003566 self.assertRaises(TypeError, self.fspath)
Brett Cannonc78ca1e2016-06-24 12:03:43 -07003567
Brett Cannon044283a2016-07-15 10:41:49 -07003568 def test_bad_pathlike(self):
3569 # __fspath__ returns a value other than str or bytes.
Brett Cannonec6ce872016-09-06 15:50:29 -07003570 self.assertRaises(TypeError, self.fspath, _PathLike(42))
Brett Cannon044283a2016-07-15 10:41:49 -07003571 # __fspath__ attribute that is not callable.
3572 c = type('foo', (), {})
3573 c.__fspath__ = 1
3574 self.assertRaises(TypeError, self.fspath, c())
3575 # __fspath__ raises an exception.
Brett Cannon044283a2016-07-15 10:41:49 -07003576 self.assertRaises(ZeroDivisionError, self.fspath,
Brett Cannonec6ce872016-09-06 15:50:29 -07003577 _PathLike(ZeroDivisionError()))
Brett Cannonc78ca1e2016-06-24 12:03:43 -07003578
3579# Only test if the C version is provided, otherwise TestPEP519 already tested
3580# the pure Python implementation.
3581if hasattr(os, "_fspath"):
3582 class TestPEP519PurePython(TestPEP519):
3583
3584 """Explicitly test the pure Python implementation of os.fspath()."""
3585
3586 fspath = staticmethod(os._fspath)
Ethan Furmancdc08792016-06-02 15:06:09 -07003587
3588
Fred Drake2e2be372001-09-20 21:33:42 +00003589if __name__ == "__main__":
R David Murrayf2ad1732014-12-25 18:36:56 -05003590 unittest.main()