blob: 9c2cac394fbdf2c9aa7e287b29a3e9cd648a6424 [file] [log] [blame]
Neal Norwitze241ce82003-02-17 18:17:05 +00001"Test posix functions"
2
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003from test import support
R. David Murrayeb3615d2009-04-22 02:24:39 +00004
5# Skip these tests if there is no posix module.
6posix = support.import_module('posix')
Neal Norwitze241ce82003-02-17 18:17:05 +00007
Antoine Pitroub7572f02009-12-02 20:46:48 +00008import errno
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00009import sys
Neal Norwitze241ce82003-02-17 18:17:05 +000010import time
11import os
Charles-François Natali1e045b12011-05-22 20:42:32 +020012import fcntl
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000013import pwd
Benjamin Petersondcf97b92008-07-02 17:30:14 +000014import shutil
Benjamin Peterson052a02b2010-08-17 01:27:09 +000015import stat
Neal Norwitze241ce82003-02-17 18:17:05 +000016import unittest
17import warnings
R. David Murraya21e4ca2009-03-31 23:16:50 +000018
Neal Norwitze241ce82003-02-17 18:17:05 +000019
20class PosixTester(unittest.TestCase):
21
22 def setUp(self):
23 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000024 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000025 fp.close()
Brett Cannonc8d502e2010-03-20 21:53:28 +000026 self._warnings_manager = support.check_warnings()
27 self._warnings_manager.__enter__()
28 warnings.filterwarnings('ignore', '.* potential security risk .*',
29 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000030
31 def tearDown(self):
Neal Norwitzc34177c2008-08-25 01:04:16 +000032 support.unlink(support.TESTFN)
Brett Cannonc8d502e2010-03-20 21:53:28 +000033 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000034
35 def testNoArgFunctions(self):
36 # test posix functions which take no arguments and have
37 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000038 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000039 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000040 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020041 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000042 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000043
Neal Norwitze241ce82003-02-17 18:17:05 +000044 for name in NO_ARG_FUNCTIONS:
45 posix_func = getattr(posix, name, None)
46 if posix_func is not None:
47 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000048 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000049
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000050 if hasattr(posix, 'getresuid'):
51 def test_getresuid(self):
52 user_ids = posix.getresuid()
53 self.assertEqual(len(user_ids), 3)
54 for val in user_ids:
55 self.assertGreaterEqual(val, 0)
56
57 if hasattr(posix, 'getresgid'):
58 def test_getresgid(self):
59 group_ids = posix.getresgid()
60 self.assertEqual(len(group_ids), 3)
61 for val in group_ids:
62 self.assertGreaterEqual(val, 0)
63
64 if hasattr(posix, 'setresuid'):
65 def test_setresuid(self):
66 current_user_ids = posix.getresuid()
67 self.assertIsNone(posix.setresuid(*current_user_ids))
68 # -1 means don't change that value.
69 self.assertIsNone(posix.setresuid(-1, -1, -1))
70
71 def test_setresuid_exception(self):
72 # Don't do this test if someone is silly enough to run us as root.
73 current_user_ids = posix.getresuid()
74 if 0 not in current_user_ids:
75 new_user_ids = (current_user_ids[0]+1, -1, -1)
76 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
77
78 if hasattr(posix, 'setresgid'):
79 def test_setresgid(self):
80 current_group_ids = posix.getresgid()
81 self.assertIsNone(posix.setresgid(*current_group_ids))
82 # -1 means don't change that value.
83 self.assertIsNone(posix.setresgid(-1, -1, -1))
84
85 def test_setresgid_exception(self):
86 # Don't do this test if someone is silly enough to run us as root.
87 current_group_ids = posix.getresgid()
88 if 0 not in current_group_ids:
89 new_group_ids = (current_group_ids[0]+1, -1, -1)
90 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
91
Antoine Pitroub7572f02009-12-02 20:46:48 +000092 @unittest.skipUnless(hasattr(posix, 'initgroups'),
93 "test needs os.initgroups()")
94 def test_initgroups(self):
95 # It takes a string and an integer; check that it raises a TypeError
96 # for other argument lists.
97 self.assertRaises(TypeError, posix.initgroups)
98 self.assertRaises(TypeError, posix.initgroups, None)
99 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
100 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
101
102 # If a non-privileged user invokes it, it should fail with OSError
103 # EPERM.
104 if os.getuid() != 0:
105 name = pwd.getpwuid(posix.getuid()).pw_name
106 try:
107 posix.initgroups(name, 13)
108 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000109 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000110 else:
111 self.fail("Expected OSError to be raised by initgroups")
112
Neal Norwitze241ce82003-02-17 18:17:05 +0000113 def test_statvfs(self):
114 if hasattr(posix, 'statvfs'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000115 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000116
117 def test_fstatvfs(self):
118 if hasattr(posix, 'fstatvfs'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000119 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000120 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000121 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000122 finally:
123 fp.close()
124
125 def test_ftruncate(self):
126 if hasattr(posix, 'ftruncate'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000127 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000128 try:
129 # we need to have some data to truncate
130 fp.write('test')
131 fp.flush()
132 posix.ftruncate(fp.fileno(), 0)
133 finally:
134 fp.close()
135
Ross Lagerwall7807c352011-03-17 20:20:30 +0200136 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
137 def test_truncate(self):
138 with open(support.TESTFN, 'w') as fp:
139 fp.write('test')
140 fp.flush()
141 posix.truncate(support.TESTFN, 0)
142
143 @unittest.skipUnless(hasattr(posix, 'fexecve'), "test needs posix.fexecve()")
144 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200145 @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200146 def test_fexecve(self):
147 fp = os.open(sys.executable, os.O_RDONLY)
148 try:
149 pid = os.fork()
150 if pid == 0:
151 os.chdir(os.path.split(sys.executable)[0])
152 posix.fexecve(fp, [sys.executable, '-c', 'pass'], os.environ)
153 else:
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200154 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
Ross Lagerwall7807c352011-03-17 20:20:30 +0200155 finally:
156 os.close(fp)
157
158 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
159 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
160 def test_waitid(self):
161 pid = os.fork()
162 if pid == 0:
163 os.chdir(os.path.split(sys.executable)[0])
164 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
165 else:
166 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
167 self.assertEqual(pid, res.si_pid)
168
169 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
170 def test_lockf(self):
171 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
172 try:
173 os.write(fd, b'test')
174 os.lseek(fd, 0, os.SEEK_SET)
175 posix.lockf(fd, posix.F_LOCK, 4)
176 # section is locked
177 posix.lockf(fd, posix.F_ULOCK, 4)
178 finally:
179 os.close(fd)
180
181 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
182 def test_pread(self):
183 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
184 try:
185 os.write(fd, b'test')
186 os.lseek(fd, 0, os.SEEK_SET)
187 self.assertEqual(b'es', posix.pread(fd, 2, 1))
188 # the first pread() shoudn't disturb the file offset
189 self.assertEqual(b'te', posix.read(fd, 2))
190 finally:
191 os.close(fd)
192
193 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
194 def test_pwrite(self):
195 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
196 try:
197 os.write(fd, b'test')
198 os.lseek(fd, 0, os.SEEK_SET)
199 posix.pwrite(fd, b'xx', 1)
200 self.assertEqual(b'txxt', posix.read(fd, 4))
201 finally:
202 os.close(fd)
203
204 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
205 "test needs posix.posix_fallocate()")
206 def test_posix_fallocate(self):
207 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
208 try:
209 posix.posix_fallocate(fd, 0, 10)
210 except OSError as inst:
211 # issue10812, ZFS doesn't appear to support posix_fallocate,
212 # so skip Solaris-based since they are likely to have ZFS.
213 if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
214 raise
215 finally:
216 os.close(fd)
217
218 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
219 "test needs posix.posix_fadvise()")
220 def test_posix_fadvise(self):
221 fd = os.open(support.TESTFN, os.O_RDONLY)
222 try:
223 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
224 finally:
225 os.close(fd)
226
227 @unittest.skipUnless(hasattr(posix, 'futimes'), "test needs posix.futimes()")
228 def test_futimes(self):
229 now = time.time()
230 fd = os.open(support.TESTFN, os.O_RDONLY)
231 try:
232 posix.futimes(fd, None)
233 self.assertRaises(TypeError, posix.futimes, fd, (None, None))
234 self.assertRaises(TypeError, posix.futimes, fd, (now, None))
235 self.assertRaises(TypeError, posix.futimes, fd, (None, now))
236 posix.futimes(fd, (int(now), int(now)))
237 posix.futimes(fd, (now, now))
238 finally:
239 os.close(fd)
240
241 @unittest.skipUnless(hasattr(posix, 'lutimes'), "test needs posix.lutimes()")
242 def test_lutimes(self):
243 now = time.time()
244 posix.lutimes(support.TESTFN, None)
245 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, None))
246 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (now, None))
247 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, now))
248 posix.lutimes(support.TESTFN, (int(now), int(now)))
249 posix.lutimes(support.TESTFN, (now, now))
250
251 @unittest.skipUnless(hasattr(posix, 'futimens'), "test needs posix.futimens()")
252 def test_futimens(self):
253 now = time.time()
254 fd = os.open(support.TESTFN, os.O_RDONLY)
255 try:
256 self.assertRaises(TypeError, posix.futimens, fd, (None, None), (None, None))
257 self.assertRaises(TypeError, posix.futimens, fd, (now, 0), None)
258 self.assertRaises(TypeError, posix.futimens, fd, None, (now, 0))
259 posix.futimens(fd, (int(now), int((now - int(now)) * 1e9)),
260 (int(now), int((now - int(now)) * 1e9)))
261 finally:
262 os.close(fd)
263
264 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
265 def test_writev(self):
266 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
267 try:
268 os.writev(fd, (b'test1', b'tt2', b't3'))
269 os.lseek(fd, 0, os.SEEK_SET)
270 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
271 finally:
272 os.close(fd)
273
274 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
275 def test_readv(self):
276 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
277 try:
278 os.write(fd, b'test1tt2t3')
279 os.lseek(fd, 0, os.SEEK_SET)
280 buf = [bytearray(i) for i in [5, 3, 2]]
281 self.assertEqual(posix.readv(fd, buf), 10)
282 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
283 finally:
284 os.close(fd)
285
Neal Norwitze241ce82003-02-17 18:17:05 +0000286 def test_dup(self):
287 if hasattr(posix, 'dup'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000288 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000289 try:
290 fd = posix.dup(fp.fileno())
Ezio Melottie9615932010-01-24 19:26:24 +0000291 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000292 os.close(fd)
293 finally:
294 fp.close()
295
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000296 def test_confstr(self):
297 if hasattr(posix, 'confstr'):
298 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
299 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
300
Neal Norwitze241ce82003-02-17 18:17:05 +0000301 def test_dup2(self):
302 if hasattr(posix, 'dup2'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000303 fp1 = open(support.TESTFN)
304 fp2 = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000305 try:
306 posix.dup2(fp1.fileno(), fp2.fileno())
307 finally:
308 fp1.close()
309 fp2.close()
310
Charles-François Natali1e045b12011-05-22 20:42:32 +0200311 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
312 def test_oscloexec(self):
313 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
314 self.addCleanup(os.close, fd)
315 self.assertTrue(fcntl.fcntl(fd, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
316
Skip Montanaro98470002005-06-17 01:14:49 +0000317 def test_osexlock(self):
318 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000319 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000320 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000321 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000322 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
323 os.close(fd)
324
325 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000326 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000327 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000328 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000329 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
330 os.close(fd)
331
332 def test_osshlock(self):
333 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000334 fd1 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000335 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000336 fd2 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000337 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
338 os.close(fd2)
339 os.close(fd1)
340
341 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000342 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000343 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000344 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000345 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
346 os.close(fd)
347
Neal Norwitze241ce82003-02-17 18:17:05 +0000348 def test_fstat(self):
349 if hasattr(posix, 'fstat'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000350 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000351 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000352 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000353 finally:
354 fp.close()
355
356 def test_stat(self):
357 if hasattr(posix, 'stat'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000358 self.assertTrue(posix.stat(support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000359
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000360 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
361 def test_mkfifo(self):
362 support.unlink(support.TESTFN)
363 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
364 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
365
366 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
367 "don't have mknod()/S_IFIFO")
368 def test_mknod(self):
369 # Test using mknod() to create a FIFO (the only use specified
370 # by POSIX).
371 support.unlink(support.TESTFN)
372 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
373 try:
374 posix.mknod(support.TESTFN, mode, 0)
375 except OSError as e:
376 # Some old systems don't allow unprivileged users to use
377 # mknod(), or only support creating device nodes.
378 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
379 else:
380 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
381
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000382 def _test_all_chown_common(self, chown_func, first_param):
383 """Common code for chown, fchown and lchown tests."""
384 if os.getuid() == 0:
385 try:
386 # Many linux distros have a nfsnobody user as MAX_UID-2
387 # that makes a good test case for signedness issues.
388 # http://bugs.python.org/issue1747858
389 # This part of the test only runs when run as root.
390 # Only scary people run their tests as root.
391 ent = pwd.getpwnam('nfsnobody')
392 chown_func(first_param, ent.pw_uid, ent.pw_gid)
393 except KeyError:
394 pass
395 else:
396 # non-root cannot chown to root, raises OSError
397 self.assertRaises(OSError, chown_func,
398 first_param, 0, 0)
399 # test a successful chown call
400 chown_func(first_param, os.getuid(), os.getgid())
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000401
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000402 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
403 def test_chown(self):
404 # raise an OSError if the file does not exist
405 os.unlink(support.TESTFN)
406 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000407
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000408 # re-create the file
409 open(support.TESTFN, 'w').close()
410 self._test_all_chown_common(posix.chown, support.TESTFN)
411
412 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
413 def test_fchown(self):
414 os.unlink(support.TESTFN)
415
416 # re-create the file
417 test_file = open(support.TESTFN, 'w')
418 try:
419 fd = test_file.fileno()
420 self._test_all_chown_common(posix.fchown, fd)
421 finally:
422 test_file.close()
423
424 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
425 def test_lchown(self):
426 os.unlink(support.TESTFN)
427 # create a symlink
428 os.symlink('/tmp/dummy-symlink-target', support.TESTFN)
429 self._test_all_chown_common(posix.lchown, support.TESTFN)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000430
Neal Norwitze241ce82003-02-17 18:17:05 +0000431 def test_chdir(self):
432 if hasattr(posix, 'chdir'):
433 posix.chdir(os.curdir)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000434 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000435
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000436 def test_listdir(self):
437 if hasattr(posix, 'listdir'):
438 self.assertTrue(support.TESTFN in posix.listdir(os.curdir))
439
440 def test_listdir_default(self):
441 # When listdir is called without argument, it's the same as listdir(os.curdir)
442 if hasattr(posix, 'listdir'):
443 self.assertTrue(support.TESTFN in posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000444
Antoine Pitrou8250e232011-02-25 23:41:16 +0000445 @unittest.skipUnless(hasattr(posix, 'fdlistdir'), "test needs posix.fdlistdir()")
446 def test_fdlistdir(self):
447 f = posix.open(posix.getcwd(), posix.O_RDONLY)
448 self.assertEqual(
449 sorted(posix.listdir('.')),
450 sorted(posix.fdlistdir(f))
451 )
452 # Check the fd was closed by fdlistdir
453 with self.assertRaises(OSError) as ctx:
454 posix.close(f)
455 self.assertEqual(ctx.exception.errno, errno.EBADF)
456
Neal Norwitze241ce82003-02-17 18:17:05 +0000457 def test_access(self):
458 if hasattr(posix, 'access'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000459 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000460
461 def test_umask(self):
462 if hasattr(posix, 'umask'):
463 old_mask = posix.umask(0)
Ezio Melottie9615932010-01-24 19:26:24 +0000464 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000465 posix.umask(old_mask)
466
467 def test_strerror(self):
468 if hasattr(posix, 'strerror'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000469 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000470
471 def test_pipe(self):
472 if hasattr(posix, 'pipe'):
473 reader, writer = posix.pipe()
474 os.close(reader)
475 os.close(writer)
476
Neal Norwitze241ce82003-02-17 18:17:05 +0000477 def test_utime(self):
478 if hasattr(posix, 'utime'):
479 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000480 posix.utime(support.TESTFN, None)
481 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
482 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
483 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
484 posix.utime(support.TESTFN, (int(now), int(now)))
485 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000486
Thomas Wouterscf297e42007-02-23 15:07:44 +0000487 def test_chflags(self):
488 if hasattr(posix, 'chflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000489 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000490 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000491 posix.chflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000492
493 def test_lchflags(self):
494 if hasattr(posix, 'lchflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000495 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000496 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000497 posix.lchflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000498
Guido van Rossum98297ee2007-11-06 21:34:58 +0000499 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000500 if os.name == "nt":
501 item_type = str
502 else:
503 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000504 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000505 self.assertEqual(type(k), item_type)
506 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000507
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000508 def test_getcwd_long_pathnames(self):
509 if hasattr(posix, 'getcwd'):
510 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
511 curdir = os.getcwd()
512 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
513
514 try:
515 os.mkdir(base_path)
516 os.chdir(base_path)
517 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000518# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000519# because the test results in Error in that case.
520# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000521# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000522 return
523
524 def _create_and_do_getcwd(dirname, current_path_length = 0):
525 try:
526 os.mkdir(dirname)
527 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000528 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000529
530 os.chdir(dirname)
531 try:
532 os.getcwd()
533 if current_path_length < 1027:
534 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
535 finally:
536 os.chdir('..')
537 os.rmdir(dirname)
538
539 _create_and_do_getcwd(dirname)
540
541 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000542 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000543 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000544
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000545 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000546 def test_getgroups(self):
547 with os.popen('id -G') as idg:
548 groups = idg.read().strip()
549
550 if not groups:
551 raise unittest.SkipTest("need working 'id -G'")
552
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000553 # 'id -G' and 'os.getgroups()' should return the same
554 # groups, ignoring order and duplicates.
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000555 # #10822 - it is implementation defined whether posix.getgroups()
556 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussorencb615e62010-07-24 14:15:19 +0000557 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000558 set([int(x) for x in groups.split()]),
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000559 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000560
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000561 # tests for the posix *at functions follow
562
563 @unittest.skipUnless(hasattr(posix, 'faccessat'), "test needs posix.faccessat()")
564 def test_faccessat(self):
565 f = posix.open(posix.getcwd(), posix.O_RDONLY)
566 try:
567 self.assertTrue(posix.faccessat(f, support.TESTFN, os.R_OK))
568 finally:
569 posix.close(f)
570
571 @unittest.skipUnless(hasattr(posix, 'fchmodat'), "test needs posix.fchmodat()")
572 def test_fchmodat(self):
573 os.chmod(support.TESTFN, stat.S_IRUSR)
574
575 f = posix.open(posix.getcwd(), posix.O_RDONLY)
576 try:
577 posix.fchmodat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
578
579 s = posix.stat(support.TESTFN)
580 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
581 finally:
582 posix.close(f)
583
584 @unittest.skipUnless(hasattr(posix, 'fchownat'), "test needs posix.fchownat()")
585 def test_fchownat(self):
586 support.unlink(support.TESTFN)
587 open(support.TESTFN, 'w').close()
588
589 f = posix.open(posix.getcwd(), posix.O_RDONLY)
590 try:
591 posix.fchownat(f, support.TESTFN, os.getuid(), os.getgid())
592 finally:
593 posix.close(f)
594
595 @unittest.skipUnless(hasattr(posix, 'fstatat'), "test needs posix.fstatat()")
596 def test_fstatat(self):
597 support.unlink(support.TESTFN)
598 with open(support.TESTFN, 'w') as outfile:
599 outfile.write("testline\n")
600
601 f = posix.open(posix.getcwd(), posix.O_RDONLY)
602 try:
603 s1 = posix.stat(support.TESTFN)
604 s2 = posix.fstatat(f, support.TESTFN)
605 self.assertEqual(s1, s2)
606 finally:
607 posix.close(f)
608
609 @unittest.skipUnless(hasattr(posix, 'futimesat'), "test needs posix.futimesat()")
610 def test_futimesat(self):
611 f = posix.open(posix.getcwd(), posix.O_RDONLY)
612 try:
613 now = time.time()
614 posix.futimesat(f, support.TESTFN, None)
615 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, None))
616 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (now, None))
617 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, now))
618 posix.futimesat(f, support.TESTFN, (int(now), int(now)))
619 posix.futimesat(f, support.TESTFN, (now, now))
620 finally:
621 posix.close(f)
622
623 @unittest.skipUnless(hasattr(posix, 'linkat'), "test needs posix.linkat()")
624 def test_linkat(self):
625 f = posix.open(posix.getcwd(), posix.O_RDONLY)
626 try:
627 posix.linkat(f, support.TESTFN, f, support.TESTFN + 'link')
628 # should have same inodes
629 self.assertEqual(posix.stat(support.TESTFN)[1],
630 posix.stat(support.TESTFN + 'link')[1])
631 finally:
632 posix.close(f)
633 support.unlink(support.TESTFN + 'link')
634
635 @unittest.skipUnless(hasattr(posix, 'mkdirat'), "test needs posix.mkdirat()")
636 def test_mkdirat(self):
637 f = posix.open(posix.getcwd(), posix.O_RDONLY)
638 try:
639 posix.mkdirat(f, support.TESTFN + 'dir')
640 posix.stat(support.TESTFN + 'dir') # should not raise exception
641 finally:
642 posix.close(f)
643 support.rmtree(support.TESTFN + 'dir')
644
645 @unittest.skipUnless(hasattr(posix, 'mknodat') and hasattr(stat, 'S_IFIFO'),
646 "don't have mknodat()/S_IFIFO")
647 def test_mknodat(self):
648 # Test using mknodat() to create a FIFO (the only use specified
649 # by POSIX).
650 support.unlink(support.TESTFN)
651 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
652 f = posix.open(posix.getcwd(), posix.O_RDONLY)
653 try:
654 posix.mknodat(f, support.TESTFN, mode, 0)
655 except OSError as e:
656 # Some old systems don't allow unprivileged users to use
657 # mknod(), or only support creating device nodes.
658 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
659 else:
660 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
661 finally:
662 posix.close(f)
663
664 @unittest.skipUnless(hasattr(posix, 'openat'), "test needs posix.openat()")
665 def test_openat(self):
666 support.unlink(support.TESTFN)
667 with open(support.TESTFN, 'w') as outfile:
668 outfile.write("testline\n")
669 a = posix.open(posix.getcwd(), posix.O_RDONLY)
670 b = posix.openat(a, support.TESTFN, posix.O_RDONLY)
671 try:
672 res = posix.read(b, 9).decode(encoding="utf-8")
673 self.assertEqual("testline\n", res)
674 finally:
675 posix.close(a)
676 posix.close(b)
677
678 @unittest.skipUnless(hasattr(posix, 'readlinkat'), "test needs posix.readlinkat()")
679 def test_readlinkat(self):
680 os.symlink(support.TESTFN, support.TESTFN + 'link')
681 f = posix.open(posix.getcwd(), posix.O_RDONLY)
682 try:
683 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
684 posix.readlinkat(f, support.TESTFN + 'link'))
685 finally:
686 support.unlink(support.TESTFN + 'link')
687 posix.close(f)
688
689 @unittest.skipUnless(hasattr(posix, 'renameat'), "test needs posix.renameat()")
690 def test_renameat(self):
691 support.unlink(support.TESTFN)
692 open(support.TESTFN + 'ren', 'w').close()
693 f = posix.open(posix.getcwd(), posix.O_RDONLY)
694 try:
695 posix.renameat(f, support.TESTFN + 'ren', f, support.TESTFN)
696 except:
697 posix.rename(support.TESTFN + 'ren', support.TESTFN)
698 raise
699 else:
700 posix.stat(support.TESTFN) # should not throw exception
701 finally:
702 posix.close(f)
703
704 @unittest.skipUnless(hasattr(posix, 'symlinkat'), "test needs posix.symlinkat()")
705 def test_symlinkat(self):
706 f = posix.open(posix.getcwd(), posix.O_RDONLY)
707 try:
708 posix.symlinkat(support.TESTFN, f, support.TESTFN + 'link')
709 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
710 finally:
711 posix.close(f)
712 support.unlink(support.TESTFN + 'link')
713
714 @unittest.skipUnless(hasattr(posix, 'unlinkat'), "test needs posix.unlinkat()")
715 def test_unlinkat(self):
716 f = posix.open(posix.getcwd(), posix.O_RDONLY)
717 open(support.TESTFN + 'del', 'w').close()
718 posix.stat(support.TESTFN + 'del') # should not throw exception
719 try:
720 posix.unlinkat(f, support.TESTFN + 'del')
721 except:
722 support.unlink(support.TESTFN + 'del')
723 raise
724 else:
725 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
726 finally:
727 posix.close(f)
728
729 @unittest.skipUnless(hasattr(posix, 'utimensat'), "test needs posix.utimensat()")
730 def test_utimensat(self):
731 f = posix.open(posix.getcwd(), posix.O_RDONLY)
732 try:
733 now = time.time()
734 posix.utimensat(f, support.TESTFN, None, None)
735 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (None, None), (None, None))
736 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (now, 0), None)
737 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, None, (now, 0))
738 posix.utimensat(f, support.TESTFN, (int(now), int((now - int(now)) * 1e9)),
739 (int(now), int((now - int(now)) * 1e9)))
740 finally:
741 posix.close(f)
742
743 @unittest.skipUnless(hasattr(posix, 'mkfifoat'), "don't have mkfifoat()")
744 def test_mkfifoat(self):
745 support.unlink(support.TESTFN)
746 f = posix.open(posix.getcwd(), posix.O_RDONLY)
747 try:
748 posix.mkfifoat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
749 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
750 finally:
751 posix.close(f)
752
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000753class PosixGroupsTester(unittest.TestCase):
754
755 def setUp(self):
756 if posix.getuid() != 0:
757 raise unittest.SkipTest("not enough privileges")
758 if not hasattr(posix, 'getgroups'):
759 raise unittest.SkipTest("need posix.getgroups")
760 if sys.platform == 'darwin':
761 raise unittest.SkipTest("getgroups(2) is broken on OSX")
762 self.saved_groups = posix.getgroups()
763
764 def tearDown(self):
765 if hasattr(posix, 'setgroups'):
766 posix.setgroups(self.saved_groups)
767 elif hasattr(posix, 'initgroups'):
768 name = pwd.getpwuid(posix.getuid()).pw_name
769 posix.initgroups(name, self.saved_groups[0])
770
771 @unittest.skipUnless(hasattr(posix, 'initgroups'),
772 "test needs posix.initgroups()")
773 def test_initgroups(self):
774 # find missing group
775
Antoine Pitroue5a91012010-09-04 17:32:06 +0000776 g = max(self.saved_groups) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000777 name = pwd.getpwuid(posix.getuid()).pw_name
778 posix.initgroups(name, g)
779 self.assertIn(g, posix.getgroups())
780
781 @unittest.skipUnless(hasattr(posix, 'setgroups'),
782 "test needs posix.setgroups()")
783 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +0000784 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000785 posix.setgroups(groups)
786 self.assertListEqual(groups, posix.getgroups())
787
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000788
Neal Norwitze241ce82003-02-17 18:17:05 +0000789def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +0100790 try:
791 support.run_unittest(PosixTester, PosixGroupsTester)
792 finally:
793 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +0000794
795if __name__ == '__main__':
796 test_main()