blob: 142dddd09b6238e4a304a7f5c393c62c627cddb6 [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
Charles-François Nataliab2d58e2012-04-17 19:48:35 +020013import platform
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000014import pwd
Benjamin Petersondcf97b92008-07-02 17:30:14 +000015import shutil
Benjamin Peterson052a02b2010-08-17 01:27:09 +000016import stat
Ned Deilyba2eab22011-07-26 13:53:55 -070017import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000018import unittest
19import warnings
R. David Murraya21e4ca2009-03-31 23:16:50 +000020
Ned Deilyba2eab22011-07-26 13:53:55 -070021_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
22 support.TESTFN + '-dummy-symlink')
Neal Norwitze241ce82003-02-17 18:17:05 +000023
24class PosixTester(unittest.TestCase):
25
26 def setUp(self):
27 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000028 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000029 fp.close()
Ned Deily3eb67d52011-06-28 00:00:28 -070030 self.teardown_files = [ support.TESTFN ]
Brett Cannonc8d502e2010-03-20 21:53:28 +000031 self._warnings_manager = support.check_warnings()
32 self._warnings_manager.__enter__()
33 warnings.filterwarnings('ignore', '.* potential security risk .*',
34 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000035
36 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070037 for teardown_file in self.teardown_files:
38 support.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000039 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000040
41 def testNoArgFunctions(self):
42 # test posix functions which take no arguments and have
43 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000044 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000045 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000046 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020047 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000048 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000049
Neal Norwitze241ce82003-02-17 18:17:05 +000050 for name in NO_ARG_FUNCTIONS:
51 posix_func = getattr(posix, name, None)
52 if posix_func is not None:
53 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000054 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000055
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000056 if hasattr(posix, 'getresuid'):
57 def test_getresuid(self):
58 user_ids = posix.getresuid()
59 self.assertEqual(len(user_ids), 3)
60 for val in user_ids:
61 self.assertGreaterEqual(val, 0)
62
63 if hasattr(posix, 'getresgid'):
64 def test_getresgid(self):
65 group_ids = posix.getresgid()
66 self.assertEqual(len(group_ids), 3)
67 for val in group_ids:
68 self.assertGreaterEqual(val, 0)
69
70 if hasattr(posix, 'setresuid'):
71 def test_setresuid(self):
72 current_user_ids = posix.getresuid()
73 self.assertIsNone(posix.setresuid(*current_user_ids))
74 # -1 means don't change that value.
75 self.assertIsNone(posix.setresuid(-1, -1, -1))
76
77 def test_setresuid_exception(self):
78 # Don't do this test if someone is silly enough to run us as root.
79 current_user_ids = posix.getresuid()
80 if 0 not in current_user_ids:
81 new_user_ids = (current_user_ids[0]+1, -1, -1)
82 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
83
84 if hasattr(posix, 'setresgid'):
85 def test_setresgid(self):
86 current_group_ids = posix.getresgid()
87 self.assertIsNone(posix.setresgid(*current_group_ids))
88 # -1 means don't change that value.
89 self.assertIsNone(posix.setresgid(-1, -1, -1))
90
91 def test_setresgid_exception(self):
92 # Don't do this test if someone is silly enough to run us as root.
93 current_group_ids = posix.getresgid()
94 if 0 not in current_group_ids:
95 new_group_ids = (current_group_ids[0]+1, -1, -1)
96 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
97
Antoine Pitroub7572f02009-12-02 20:46:48 +000098 @unittest.skipUnless(hasattr(posix, 'initgroups'),
99 "test needs os.initgroups()")
100 def test_initgroups(self):
101 # It takes a string and an integer; check that it raises a TypeError
102 # for other argument lists.
103 self.assertRaises(TypeError, posix.initgroups)
104 self.assertRaises(TypeError, posix.initgroups, None)
105 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
106 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
107
108 # If a non-privileged user invokes it, it should fail with OSError
109 # EPERM.
110 if os.getuid() != 0:
111 name = pwd.getpwuid(posix.getuid()).pw_name
112 try:
113 posix.initgroups(name, 13)
114 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000115 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000116 else:
117 self.fail("Expected OSError to be raised by initgroups")
118
Neal Norwitze241ce82003-02-17 18:17:05 +0000119 def test_statvfs(self):
120 if hasattr(posix, 'statvfs'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000121 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000122
123 def test_fstatvfs(self):
124 if hasattr(posix, 'fstatvfs'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000125 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000126 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000127 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000128 finally:
129 fp.close()
130
131 def test_ftruncate(self):
132 if hasattr(posix, 'ftruncate'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000133 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000134 try:
135 # we need to have some data to truncate
136 fp.write('test')
137 fp.flush()
138 posix.ftruncate(fp.fileno(), 0)
139 finally:
140 fp.close()
141
Ross Lagerwall7807c352011-03-17 20:20:30 +0200142 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
143 def test_truncate(self):
144 with open(support.TESTFN, 'w') as fp:
145 fp.write('test')
146 fp.flush()
147 posix.truncate(support.TESTFN, 0)
148
149 @unittest.skipUnless(hasattr(posix, 'fexecve'), "test needs posix.fexecve()")
150 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200151 @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200152 def test_fexecve(self):
153 fp = os.open(sys.executable, os.O_RDONLY)
154 try:
155 pid = os.fork()
156 if pid == 0:
157 os.chdir(os.path.split(sys.executable)[0])
158 posix.fexecve(fp, [sys.executable, '-c', 'pass'], os.environ)
159 else:
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200160 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
Ross Lagerwall7807c352011-03-17 20:20:30 +0200161 finally:
162 os.close(fp)
163
164 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
165 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
166 def test_waitid(self):
167 pid = os.fork()
168 if pid == 0:
169 os.chdir(os.path.split(sys.executable)[0])
170 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
171 else:
172 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
173 self.assertEqual(pid, res.si_pid)
174
175 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
176 def test_lockf(self):
177 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
178 try:
179 os.write(fd, b'test')
180 os.lseek(fd, 0, os.SEEK_SET)
181 posix.lockf(fd, posix.F_LOCK, 4)
182 # section is locked
183 posix.lockf(fd, posix.F_ULOCK, 4)
184 finally:
185 os.close(fd)
186
187 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
188 def test_pread(self):
189 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
190 try:
191 os.write(fd, b'test')
192 os.lseek(fd, 0, os.SEEK_SET)
193 self.assertEqual(b'es', posix.pread(fd, 2, 1))
Florent Xiclunae41f0de2011-11-11 19:39:25 +0100194 # the first pread() shouldn't disturb the file offset
Ross Lagerwall7807c352011-03-17 20:20:30 +0200195 self.assertEqual(b'te', posix.read(fd, 2))
196 finally:
197 os.close(fd)
198
199 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
200 def test_pwrite(self):
201 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
202 try:
203 os.write(fd, b'test')
204 os.lseek(fd, 0, os.SEEK_SET)
205 posix.pwrite(fd, b'xx', 1)
206 self.assertEqual(b'txxt', posix.read(fd, 4))
207 finally:
208 os.close(fd)
209
210 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
211 "test needs posix.posix_fallocate()")
212 def test_posix_fallocate(self):
213 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
214 try:
215 posix.posix_fallocate(fd, 0, 10)
216 except OSError as inst:
217 # issue10812, ZFS doesn't appear to support posix_fallocate,
218 # so skip Solaris-based since they are likely to have ZFS.
219 if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
220 raise
221 finally:
222 os.close(fd)
223
224 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
225 "test needs posix.posix_fadvise()")
226 def test_posix_fadvise(self):
227 fd = os.open(support.TESTFN, os.O_RDONLY)
228 try:
229 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
230 finally:
231 os.close(fd)
232
233 @unittest.skipUnless(hasattr(posix, 'futimes'), "test needs posix.futimes()")
234 def test_futimes(self):
235 now = time.time()
236 fd = os.open(support.TESTFN, os.O_RDONLY)
237 try:
238 posix.futimes(fd, None)
Brian Curtinc1b65d12011-11-07 14:18:54 -0600239 posix.futimes(fd)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200240 self.assertRaises(TypeError, posix.futimes, fd, (None, None))
241 self.assertRaises(TypeError, posix.futimes, fd, (now, None))
242 self.assertRaises(TypeError, posix.futimes, fd, (None, now))
243 posix.futimes(fd, (int(now), int(now)))
244 posix.futimes(fd, (now, now))
245 finally:
246 os.close(fd)
247
248 @unittest.skipUnless(hasattr(posix, 'lutimes'), "test needs posix.lutimes()")
249 def test_lutimes(self):
250 now = time.time()
251 posix.lutimes(support.TESTFN, None)
252 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, None))
253 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (now, None))
254 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, now))
255 posix.lutimes(support.TESTFN, (int(now), int(now)))
256 posix.lutimes(support.TESTFN, (now, now))
Brian Curtinc1b65d12011-11-07 14:18:54 -0600257 posix.lutimes(support.TESTFN)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200258
259 @unittest.skipUnless(hasattr(posix, 'futimens'), "test needs posix.futimens()")
260 def test_futimens(self):
261 now = time.time()
262 fd = os.open(support.TESTFN, os.O_RDONLY)
263 try:
264 self.assertRaises(TypeError, posix.futimens, fd, (None, None), (None, None))
265 self.assertRaises(TypeError, posix.futimens, fd, (now, 0), None)
266 self.assertRaises(TypeError, posix.futimens, fd, None, (now, 0))
267 posix.futimens(fd, (int(now), int((now - int(now)) * 1e9)),
268 (int(now), int((now - int(now)) * 1e9)))
Brian Curtinc1b65d12011-11-07 14:18:54 -0600269 posix.futimens(fd)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200270 finally:
271 os.close(fd)
272
273 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
274 def test_writev(self):
275 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
276 try:
277 os.writev(fd, (b'test1', b'tt2', b't3'))
278 os.lseek(fd, 0, os.SEEK_SET)
279 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
280 finally:
281 os.close(fd)
282
283 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
284 def test_readv(self):
285 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
286 try:
287 os.write(fd, b'test1tt2t3')
288 os.lseek(fd, 0, os.SEEK_SET)
289 buf = [bytearray(i) for i in [5, 3, 2]]
290 self.assertEqual(posix.readv(fd, buf), 10)
291 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
292 finally:
293 os.close(fd)
294
Neal Norwitze241ce82003-02-17 18:17:05 +0000295 def test_dup(self):
296 if hasattr(posix, 'dup'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000297 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000298 try:
299 fd = posix.dup(fp.fileno())
Ezio Melottie9615932010-01-24 19:26:24 +0000300 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000301 os.close(fd)
302 finally:
303 fp.close()
304
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000305 def test_confstr(self):
306 if hasattr(posix, 'confstr'):
307 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
308 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
309
Neal Norwitze241ce82003-02-17 18:17:05 +0000310 def test_dup2(self):
311 if hasattr(posix, 'dup2'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000312 fp1 = open(support.TESTFN)
313 fp2 = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000314 try:
315 posix.dup2(fp1.fileno(), fp2.fileno())
316 finally:
317 fp1.close()
318 fp2.close()
319
Charles-François Natali1e045b12011-05-22 20:42:32 +0200320 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200321 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200322 def test_oscloexec(self):
323 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
324 self.addCleanup(os.close, fd)
Victor Stinnere36f3752011-05-24 00:29:43 +0200325 self.assertTrue(fcntl.fcntl(fd, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200326
Skip Montanaro98470002005-06-17 01:14:49 +0000327 def test_osexlock(self):
328 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000329 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000330 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000331 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000332 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
333 os.close(fd)
334
335 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000336 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000337 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000338 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000339 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
340 os.close(fd)
341
342 def test_osshlock(self):
343 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000344 fd1 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000345 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000346 fd2 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000347 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
348 os.close(fd2)
349 os.close(fd1)
350
351 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000352 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000353 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000354 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000355 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
356 os.close(fd)
357
Neal Norwitze241ce82003-02-17 18:17:05 +0000358 def test_fstat(self):
359 if hasattr(posix, 'fstat'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000360 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000361 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000362 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000363 finally:
364 fp.close()
365
366 def test_stat(self):
367 if hasattr(posix, 'stat'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000368 self.assertTrue(posix.stat(support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000369
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000370 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
371 def test_mkfifo(self):
372 support.unlink(support.TESTFN)
373 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
374 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
375
376 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
377 "don't have mknod()/S_IFIFO")
378 def test_mknod(self):
379 # Test using mknod() to create a FIFO (the only use specified
380 # by POSIX).
381 support.unlink(support.TESTFN)
382 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
383 try:
384 posix.mknod(support.TESTFN, mode, 0)
385 except OSError as e:
386 # Some old systems don't allow unprivileged users to use
387 # mknod(), or only support creating device nodes.
388 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
389 else:
390 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
391
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000392 def _test_all_chown_common(self, chown_func, first_param):
393 """Common code for chown, fchown and lchown tests."""
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200394 # test a successful chown call
395 chown_func(first_param, os.getuid(), os.getgid())
396
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000397 if os.getuid() == 0:
398 try:
399 # Many linux distros have a nfsnobody user as MAX_UID-2
400 # that makes a good test case for signedness issues.
401 # http://bugs.python.org/issue1747858
402 # This part of the test only runs when run as root.
403 # Only scary people run their tests as root.
404 ent = pwd.getpwnam('nfsnobody')
405 chown_func(first_param, ent.pw_uid, ent.pw_gid)
406 except KeyError:
407 pass
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200408 elif platform.system() in ('HP-UX', 'SunOS'):
409 # HP-UX and Solaris can allow a non-root user to chown() to root
410 # (issue #5113)
411 raise unittest.SkipTest("Skipping because of non-standard chown() "
412 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000413 else:
414 # non-root cannot chown to root, raises OSError
415 self.assertRaises(OSError, chown_func,
416 first_param, 0, 0)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000417
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000418 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
419 def test_chown(self):
420 # raise an OSError if the file does not exist
421 os.unlink(support.TESTFN)
422 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000423
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000424 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200425 support.create_empty_file(support.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000426 self._test_all_chown_common(posix.chown, support.TESTFN)
427
428 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
429 def test_fchown(self):
430 os.unlink(support.TESTFN)
431
432 # re-create the file
433 test_file = open(support.TESTFN, 'w')
434 try:
435 fd = test_file.fileno()
436 self._test_all_chown_common(posix.fchown, fd)
437 finally:
438 test_file.close()
439
440 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
441 def test_lchown(self):
442 os.unlink(support.TESTFN)
443 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700444 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000445 self._test_all_chown_common(posix.lchown, support.TESTFN)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000446
Neal Norwitze241ce82003-02-17 18:17:05 +0000447 def test_chdir(self):
448 if hasattr(posix, 'chdir'):
449 posix.chdir(os.curdir)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000450 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000451
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000452 def test_listdir(self):
453 if hasattr(posix, 'listdir'):
454 self.assertTrue(support.TESTFN in posix.listdir(os.curdir))
455
456 def test_listdir_default(self):
457 # When listdir is called without argument, it's the same as listdir(os.curdir)
458 if hasattr(posix, 'listdir'):
459 self.assertTrue(support.TESTFN in posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000460
Charles-François Natali77940902012-02-06 19:54:48 +0100461 @unittest.skipUnless(hasattr(posix, 'flistdir'), "test needs posix.flistdir()")
462 def test_flistdir(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000463 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100464 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000465 self.assertEqual(
466 sorted(posix.listdir('.')),
Charles-François Natali77940902012-02-06 19:54:48 +0100467 sorted(posix.flistdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000468 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100469 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100470 self.assertEqual(
471 sorted(posix.listdir('.')),
Charles-François Natali77940902012-02-06 19:54:48 +0100472 sorted(posix.flistdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100473 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000474
Neal Norwitze241ce82003-02-17 18:17:05 +0000475 def test_access(self):
476 if hasattr(posix, 'access'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000477 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000478
479 def test_umask(self):
480 if hasattr(posix, 'umask'):
481 old_mask = posix.umask(0)
Ezio Melottie9615932010-01-24 19:26:24 +0000482 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000483 posix.umask(old_mask)
484
485 def test_strerror(self):
486 if hasattr(posix, 'strerror'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000487 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000488
489 def test_pipe(self):
490 if hasattr(posix, 'pipe'):
491 reader, writer = posix.pipe()
492 os.close(reader)
493 os.close(writer)
494
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200495 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200496 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200497 def test_pipe2(self):
498 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
499 self.assertRaises(TypeError, os.pipe2, 0, 0)
500
Charles-François Natali368f34b2011-06-06 19:49:47 +0200501 # try calling with flags = 0, like os.pipe()
502 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200503 os.close(r)
504 os.close(w)
505
506 # test flags
507 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
508 self.addCleanup(os.close, r)
509 self.addCleanup(os.close, w)
510 self.assertTrue(fcntl.fcntl(r, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
511 self.assertTrue(fcntl.fcntl(w, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
512 # try reading from an empty pipe: this should fail, not block
513 self.assertRaises(OSError, os.read, r, 1)
514 # try a write big enough to fill-up the pipe: this should either
515 # fail or perform a partial write, not block
516 try:
517 os.write(w, b'x' * support.PIPE_MAX_SIZE)
518 except OSError:
519 pass
520
Neal Norwitze241ce82003-02-17 18:17:05 +0000521 def test_utime(self):
522 if hasattr(posix, 'utime'):
523 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000524 posix.utime(support.TESTFN, None)
525 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
526 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
527 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
528 posix.utime(support.TESTFN, (int(now), int(now)))
529 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000530
Ned Deily3eb67d52011-06-28 00:00:28 -0700531 def _test_chflags_regular_file(self, chflags_func, target_file):
532 st = os.stat(target_file)
533 self.assertTrue(hasattr(st, 'st_flags'))
534 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
535 try:
536 new_st = os.stat(target_file)
537 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
538 try:
539 fd = open(target_file, 'w+')
540 except IOError as e:
541 self.assertEqual(e.errno, errno.EPERM)
542 finally:
543 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000544
Ned Deily3eb67d52011-06-28 00:00:28 -0700545 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
546 def test_chflags(self):
547 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
548
549 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
550 def test_lchflags_regular_file(self):
551 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
552
553 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
554 def test_lchflags_symlink(self):
555 testfn_st = os.stat(support.TESTFN)
556
557 self.assertTrue(hasattr(testfn_st, 'st_flags'))
558
559 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
560 self.teardown_files.append(_DUMMY_SYMLINK)
561 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
562
563 posix.lchflags(_DUMMY_SYMLINK,
564 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
565 try:
566 new_testfn_st = os.stat(support.TESTFN)
567 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
568
569 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
570 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
571 new_dummy_symlink_st.st_flags)
572 finally:
573 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000574
Guido van Rossum98297ee2007-11-06 21:34:58 +0000575 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000576 if os.name == "nt":
577 item_type = str
578 else:
579 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000580 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000581 self.assertEqual(type(k), item_type)
582 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000583
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000584 def test_getcwd_long_pathnames(self):
585 if hasattr(posix, 'getcwd'):
586 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
587 curdir = os.getcwd()
588 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
589
590 try:
591 os.mkdir(base_path)
592 os.chdir(base_path)
593 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000594# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000595# because the test results in Error in that case.
596# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000597# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000598 return
599
600 def _create_and_do_getcwd(dirname, current_path_length = 0):
601 try:
602 os.mkdir(dirname)
603 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000604 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000605
606 os.chdir(dirname)
607 try:
608 os.getcwd()
609 if current_path_length < 1027:
610 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
611 finally:
612 os.chdir('..')
613 os.rmdir(dirname)
614
615 _create_and_do_getcwd(dirname)
616
617 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000618 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000619 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000620
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200621 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
622 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
623 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
624 def test_getgrouplist(self):
625 with os.popen('id -G') as idg:
626 groups = idg.read().strip()
627
628 if not groups:
629 raise unittest.SkipTest("need working 'id -G'")
630
631 self.assertEqual(
632 set([int(x) for x in groups.split()]),
633 set(posix.getgrouplist(pwd.getpwuid(os.getuid())[0],
634 pwd.getpwuid(os.getuid())[3])))
635
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000636 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000637 def test_getgroups(self):
638 with os.popen('id -G') as idg:
639 groups = idg.read().strip()
640
641 if not groups:
642 raise unittest.SkipTest("need working 'id -G'")
643
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000644 # 'id -G' and 'os.getgroups()' should return the same
645 # groups, ignoring order and duplicates.
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000646 # #10822 - it is implementation defined whether posix.getgroups()
647 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussorencb615e62010-07-24 14:15:19 +0000648 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000649 set([int(x) for x in groups.split()]),
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000650 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000651
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000652 # tests for the posix *at functions follow
653
654 @unittest.skipUnless(hasattr(posix, 'faccessat'), "test needs posix.faccessat()")
655 def test_faccessat(self):
656 f = posix.open(posix.getcwd(), posix.O_RDONLY)
657 try:
658 self.assertTrue(posix.faccessat(f, support.TESTFN, os.R_OK))
659 finally:
660 posix.close(f)
661
662 @unittest.skipUnless(hasattr(posix, 'fchmodat'), "test needs posix.fchmodat()")
663 def test_fchmodat(self):
664 os.chmod(support.TESTFN, stat.S_IRUSR)
665
666 f = posix.open(posix.getcwd(), posix.O_RDONLY)
667 try:
668 posix.fchmodat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
669
670 s = posix.stat(support.TESTFN)
671 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
672 finally:
673 posix.close(f)
674
675 @unittest.skipUnless(hasattr(posix, 'fchownat'), "test needs posix.fchownat()")
676 def test_fchownat(self):
677 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +0200678 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000679
680 f = posix.open(posix.getcwd(), posix.O_RDONLY)
681 try:
682 posix.fchownat(f, support.TESTFN, os.getuid(), os.getgid())
683 finally:
684 posix.close(f)
685
686 @unittest.skipUnless(hasattr(posix, 'fstatat'), "test needs posix.fstatat()")
687 def test_fstatat(self):
688 support.unlink(support.TESTFN)
689 with open(support.TESTFN, 'w') as outfile:
690 outfile.write("testline\n")
691
692 f = posix.open(posix.getcwd(), posix.O_RDONLY)
693 try:
694 s1 = posix.stat(support.TESTFN)
695 s2 = posix.fstatat(f, support.TESTFN)
696 self.assertEqual(s1, s2)
697 finally:
698 posix.close(f)
699
700 @unittest.skipUnless(hasattr(posix, 'futimesat'), "test needs posix.futimesat()")
701 def test_futimesat(self):
702 f = posix.open(posix.getcwd(), posix.O_RDONLY)
703 try:
704 now = time.time()
705 posix.futimesat(f, support.TESTFN, None)
Brian Curtinc1b65d12011-11-07 14:18:54 -0600706 posix.futimesat(f, support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000707 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, None))
708 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (now, None))
709 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, now))
710 posix.futimesat(f, support.TESTFN, (int(now), int(now)))
711 posix.futimesat(f, support.TESTFN, (now, now))
712 finally:
713 posix.close(f)
714
715 @unittest.skipUnless(hasattr(posix, 'linkat'), "test needs posix.linkat()")
716 def test_linkat(self):
717 f = posix.open(posix.getcwd(), posix.O_RDONLY)
718 try:
719 posix.linkat(f, support.TESTFN, f, support.TESTFN + 'link')
720 # should have same inodes
721 self.assertEqual(posix.stat(support.TESTFN)[1],
722 posix.stat(support.TESTFN + 'link')[1])
723 finally:
724 posix.close(f)
725 support.unlink(support.TESTFN + 'link')
726
727 @unittest.skipUnless(hasattr(posix, 'mkdirat'), "test needs posix.mkdirat()")
728 def test_mkdirat(self):
729 f = posix.open(posix.getcwd(), posix.O_RDONLY)
730 try:
731 posix.mkdirat(f, support.TESTFN + 'dir')
732 posix.stat(support.TESTFN + 'dir') # should not raise exception
733 finally:
734 posix.close(f)
735 support.rmtree(support.TESTFN + 'dir')
736
737 @unittest.skipUnless(hasattr(posix, 'mknodat') and hasattr(stat, 'S_IFIFO'),
738 "don't have mknodat()/S_IFIFO")
739 def test_mknodat(self):
740 # Test using mknodat() to create a FIFO (the only use specified
741 # by POSIX).
742 support.unlink(support.TESTFN)
743 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
744 f = posix.open(posix.getcwd(), posix.O_RDONLY)
745 try:
746 posix.mknodat(f, support.TESTFN, mode, 0)
747 except OSError as e:
748 # Some old systems don't allow unprivileged users to use
749 # mknod(), or only support creating device nodes.
750 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
751 else:
752 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
753 finally:
754 posix.close(f)
755
756 @unittest.skipUnless(hasattr(posix, 'openat'), "test needs posix.openat()")
757 def test_openat(self):
758 support.unlink(support.TESTFN)
759 with open(support.TESTFN, 'w') as outfile:
760 outfile.write("testline\n")
761 a = posix.open(posix.getcwd(), posix.O_RDONLY)
762 b = posix.openat(a, support.TESTFN, posix.O_RDONLY)
763 try:
764 res = posix.read(b, 9).decode(encoding="utf-8")
765 self.assertEqual("testline\n", res)
766 finally:
767 posix.close(a)
768 posix.close(b)
769
770 @unittest.skipUnless(hasattr(posix, 'readlinkat'), "test needs posix.readlinkat()")
771 def test_readlinkat(self):
772 os.symlink(support.TESTFN, support.TESTFN + 'link')
773 f = posix.open(posix.getcwd(), posix.O_RDONLY)
774 try:
775 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
776 posix.readlinkat(f, support.TESTFN + 'link'))
777 finally:
778 support.unlink(support.TESTFN + 'link')
779 posix.close(f)
780
781 @unittest.skipUnless(hasattr(posix, 'renameat'), "test needs posix.renameat()")
782 def test_renameat(self):
783 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +0200784 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000785 f = posix.open(posix.getcwd(), posix.O_RDONLY)
786 try:
787 posix.renameat(f, support.TESTFN + 'ren', f, support.TESTFN)
788 except:
789 posix.rename(support.TESTFN + 'ren', support.TESTFN)
790 raise
791 else:
792 posix.stat(support.TESTFN) # should not throw exception
793 finally:
794 posix.close(f)
795
796 @unittest.skipUnless(hasattr(posix, 'symlinkat'), "test needs posix.symlinkat()")
797 def test_symlinkat(self):
798 f = posix.open(posix.getcwd(), posix.O_RDONLY)
799 try:
800 posix.symlinkat(support.TESTFN, f, support.TESTFN + 'link')
801 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
802 finally:
803 posix.close(f)
804 support.unlink(support.TESTFN + 'link')
805
806 @unittest.skipUnless(hasattr(posix, 'unlinkat'), "test needs posix.unlinkat()")
807 def test_unlinkat(self):
808 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +0200809 support.create_empty_file(support.TESTFN + 'del')
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000810 posix.stat(support.TESTFN + 'del') # should not throw exception
811 try:
812 posix.unlinkat(f, support.TESTFN + 'del')
813 except:
814 support.unlink(support.TESTFN + 'del')
815 raise
816 else:
817 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
818 finally:
819 posix.close(f)
820
821 @unittest.skipUnless(hasattr(posix, 'utimensat'), "test needs posix.utimensat()")
822 def test_utimensat(self):
823 f = posix.open(posix.getcwd(), posix.O_RDONLY)
824 try:
825 now = time.time()
826 posix.utimensat(f, support.TESTFN, None, None)
Brian Curtin569b4942011-11-07 16:09:20 -0600827 posix.utimensat(f, support.TESTFN)
828 posix.utimensat(f, support.TESTFN, flags=os.AT_SYMLINK_NOFOLLOW)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000829 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (None, None), (None, None))
830 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (now, 0), None)
831 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, None, (now, 0))
832 posix.utimensat(f, support.TESTFN, (int(now), int((now - int(now)) * 1e9)),
833 (int(now), int((now - int(now)) * 1e9)))
Brian Curtin569b4942011-11-07 16:09:20 -0600834 posix.utimensat(dirfd=f, path=support.TESTFN,
835 atime=(int(now), int((now - int(now)) * 1e9)),
836 mtime=(int(now), int((now - int(now)) * 1e9)))
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000837 finally:
838 posix.close(f)
839
840 @unittest.skipUnless(hasattr(posix, 'mkfifoat'), "don't have mkfifoat()")
841 def test_mkfifoat(self):
842 support.unlink(support.TESTFN)
843 f = posix.open(posix.getcwd(), posix.O_RDONLY)
844 try:
845 posix.mkfifoat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
846 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
847 finally:
848 posix.close(f)
849
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500850 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
851 "don't have scheduling support")
Benjamin Peterson2740af82011-08-02 17:41:34 -0500852 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'cpu_set'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -0500853 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500854
855 @requires_sched_h
856 def test_sched_yield(self):
857 # This has no error conditions (at least on Linux).
858 posix.sched_yield()
859
860 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +0200861 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
862 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500863 def test_sched_priority(self):
864 # Round-robin usually has interesting priorities.
865 pol = posix.SCHED_RR
866 lo = posix.sched_get_priority_min(pol)
867 hi = posix.sched_get_priority_max(pol)
868 self.assertIsInstance(lo, int)
869 self.assertIsInstance(hi, int)
870 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -0500871 # OSX evidently just returns 15 without checking the argument.
872 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -0500873 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
874 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500875
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -0500876 @unittest.skipUnless(hasattr(posix, 'sched_setscheduler'), "can't change scheduler")
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500877 def test_get_and_set_scheduler_and_param(self):
878 possible_schedulers = [sched for name, sched in posix.__dict__.items()
879 if name.startswith("SCHED_")]
880 mine = posix.sched_getscheduler(0)
881 self.assertIn(mine, possible_schedulers)
882 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +0200883 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500884 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +0200885 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500886 raise
887 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +0200888 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500889 self.assertRaises(OSError, posix.sched_getscheduler, -1)
890 self.assertRaises(OSError, posix.sched_getparam, -1)
891 param = posix.sched_getparam(0)
892 self.assertIsInstance(param.sched_priority, int)
Benjamin Peterson18592ca2011-08-02 18:48:59 -0500893 try:
894 posix.sched_setscheduler(0, mine, param)
895 except OSError as e:
896 if e.errno != errno.EPERM:
897 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +0200898
899 # POSIX states that calling sched_setparam() on a process with a
900 # scheduling policy other than SCHED_FIFO or SCHED_RR is
901 # implementation-defined: FreeBSD returns EINVAL.
902 if not sys.platform.startswith('freebsd'):
903 posix.sched_setparam(0, param)
904 self.assertRaises(OSError, posix.sched_setparam, -1, param)
905
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500906 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
907 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
908 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
909 param = posix.sched_param(None)
910 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
911 large = 214748364700
912 param = posix.sched_param(large)
913 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
914 param = posix.sched_param(sched_priority=-large)
915 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
916
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -0500917 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500918 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -0500919 try:
920 interval = posix.sched_rr_get_interval(0)
921 except OSError as e:
922 # This likely means that sched_rr_get_interval is only valid for
923 # processes with the SCHED_RR scheduler in effect.
924 if e.errno != errno.EINVAL:
925 raise
926 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500927 self.assertIsInstance(interval, float)
928 # Reasonable constraints, I think.
929 self.assertGreaterEqual(interval, 0.)
930 self.assertLess(interval, 1.)
931
Benjamin Peterson2740af82011-08-02 17:41:34 -0500932 @requires_sched_affinity
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500933 def test_sched_affinity(self):
934 mask = posix.sched_getaffinity(0, 1024)
935 self.assertGreaterEqual(mask.count(), 1)
936 self.assertIsInstance(mask, posix.cpu_set)
937 self.assertRaises(OSError, posix.sched_getaffinity, -1, 1024)
938 empty = posix.cpu_set(10)
939 posix.sched_setaffinity(0, mask)
940 self.assertRaises(OSError, posix.sched_setaffinity, 0, empty)
941 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
942
Benjamin Peterson2740af82011-08-02 17:41:34 -0500943 @requires_sched_affinity
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500944 def test_cpu_set_basic(self):
945 s = posix.cpu_set(10)
946 self.assertEqual(len(s), 10)
947 self.assertEqual(s.count(), 0)
948 s.set(0)
949 s.set(9)
950 self.assertTrue(s.isset(0))
951 self.assertTrue(s.isset(9))
952 self.assertFalse(s.isset(5))
953 self.assertEqual(s.count(), 2)
954 s.clear(0)
955 self.assertFalse(s.isset(0))
956 self.assertEqual(s.count(), 1)
957 s.zero()
958 self.assertFalse(s.isset(0))
959 self.assertFalse(s.isset(9))
960 self.assertEqual(s.count(), 0)
961 self.assertRaises(ValueError, s.set, -1)
962 self.assertRaises(ValueError, s.set, 10)
963 self.assertRaises(ValueError, s.clear, -1)
964 self.assertRaises(ValueError, s.clear, 10)
965 self.assertRaises(ValueError, s.isset, -1)
966 self.assertRaises(ValueError, s.isset, 10)
967
Benjamin Peterson2740af82011-08-02 17:41:34 -0500968 @requires_sched_affinity
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500969 def test_cpu_set_cmp(self):
970 self.assertNotEqual(posix.cpu_set(11), posix.cpu_set(12))
971 l = posix.cpu_set(10)
972 r = posix.cpu_set(10)
973 self.assertEqual(l, r)
974 l.set(1)
975 self.assertNotEqual(l, r)
976 r.set(1)
977 self.assertEqual(l, r)
978
Benjamin Peterson2740af82011-08-02 17:41:34 -0500979 @requires_sched_affinity
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500980 def test_cpu_set_bitwise(self):
981 l = posix.cpu_set(5)
982 l.set(0)
983 l.set(1)
984 r = posix.cpu_set(5)
985 r.set(1)
986 r.set(2)
987 b = l & r
988 self.assertEqual(b.count(), 1)
989 self.assertTrue(b.isset(1))
990 b = l | r
991 self.assertEqual(b.count(), 3)
992 self.assertTrue(b.isset(0))
993 self.assertTrue(b.isset(1))
994 self.assertTrue(b.isset(2))
995 b = l ^ r
996 self.assertEqual(b.count(), 2)
997 self.assertTrue(b.isset(0))
998 self.assertFalse(b.isset(1))
999 self.assertTrue(b.isset(2))
1000 b = l
1001 b |= r
1002 self.assertIs(b, l)
1003 self.assertEqual(l.count(), 3)
1004
Victor Stinner8b905bd2011-10-25 13:34:04 +02001005 def test_rtld_constants(self):
1006 # check presence of major RTLD_* constants
1007 posix.RTLD_LAZY
1008 posix.RTLD_NOW
1009 posix.RTLD_GLOBAL
1010 posix.RTLD_LOCAL
1011
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001012class PosixGroupsTester(unittest.TestCase):
1013
1014 def setUp(self):
1015 if posix.getuid() != 0:
1016 raise unittest.SkipTest("not enough privileges")
1017 if not hasattr(posix, 'getgroups'):
1018 raise unittest.SkipTest("need posix.getgroups")
1019 if sys.platform == 'darwin':
1020 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1021 self.saved_groups = posix.getgroups()
1022
1023 def tearDown(self):
1024 if hasattr(posix, 'setgroups'):
1025 posix.setgroups(self.saved_groups)
1026 elif hasattr(posix, 'initgroups'):
1027 name = pwd.getpwuid(posix.getuid()).pw_name
1028 posix.initgroups(name, self.saved_groups[0])
1029
1030 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1031 "test needs posix.initgroups()")
1032 def test_initgroups(self):
1033 # find missing group
1034
Antoine Pitroue5a91012010-09-04 17:32:06 +00001035 g = max(self.saved_groups) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001036 name = pwd.getpwuid(posix.getuid()).pw_name
1037 posix.initgroups(name, g)
1038 self.assertIn(g, posix.getgroups())
1039
1040 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1041 "test needs posix.setgroups()")
1042 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001043 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001044 posix.setgroups(groups)
1045 self.assertListEqual(groups, posix.getgroups())
1046
Neal Norwitze241ce82003-02-17 18:17:05 +00001047def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001048 try:
1049 support.run_unittest(PosixTester, PosixGroupsTester)
1050 finally:
1051 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001052
1053if __name__ == '__main__':
1054 test_main()