blob: 243fd5d6ed13729a573e6ddf98e45d8661132381 [file] [log] [blame]
Neal Norwitze241ce82003-02-17 18:17:05 +00001"Test posix functions"
2
Walter Dörwald21d3a322003-05-01 17:45:56 +00003from test import test_support
Neal Norwitze241ce82003-02-17 18:17:05 +00004
R. David Murray95fb46c2009-04-21 13:06:04 +00005# Skip these tests if there is no posix module.
6posix = test_support.import_module('posix')
Neal Norwitze241ce82003-02-17 18:17:05 +00007
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008import errno
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00009import sys
Neal Norwitze241ce82003-02-17 18:17:05 +000010import time
11import os
Charles-François Natalif8387642012-04-17 19:46:06 +020012import platform
Gregory P. Smithf48da8f2008-03-18 19:05:32 +000013import pwd
Facundo Batista5596b0c2008-06-22 13:36:20 +000014import shutil
Ned Deily43e10542011-06-27 23:41:53 -070015import stat
Stefan Krah182ae642010-07-13 19:17:08 +000016import sys
Ned Deilyd88131a2011-07-26 13:52:14 -070017import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000018import unittest
19import warnings
R. David Murray59beec32009-03-30 19:04:00 +000020
Ned Deilyd88131a2011-07-26 13:52:14 -070021_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
22 test_support.TESTFN + '-dummy-symlink')
R. David Murray59beec32009-03-30 19:04:00 +000023
Neal Norwitze241ce82003-02-17 18:17:05 +000024warnings.filterwarnings('ignore', '.* potential security risk .*',
25 RuntimeWarning)
26
27class PosixTester(unittest.TestCase):
28
29 def setUp(self):
30 # create empty file
Walter Dörwald21d3a322003-05-01 17:45:56 +000031 fp = open(test_support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000032 fp.close()
Ned Deily43e10542011-06-27 23:41:53 -070033 self.teardown_files = [ test_support.TESTFN ]
Neal Norwitze241ce82003-02-17 18:17:05 +000034
35 def tearDown(self):
Ned Deily43e10542011-06-27 23:41:53 -070036 for teardown_file in self.teardown_files:
37 os.unlink(teardown_file)
Neal Norwitze241ce82003-02-17 18:17:05 +000038
39 def testNoArgFunctions(self):
40 # test posix functions which take no arguments and have
41 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
42 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdu", "uname",
Neal Norwitz71b13e82003-02-23 22:12:24 +000043 "times", "getloadavg", "tmpnam",
Neal Norwitze241ce82003-02-17 18:17:05 +000044 "getegid", "geteuid", "getgid", "getgroups",
45 "getpid", "getpgrp", "getppid", "getuid",
46 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000047
Antoine Pitroub0614612011-01-02 20:04:52 +000048 with warnings.catch_warnings():
49 warnings.filterwarnings("ignore", "", DeprecationWarning)
50 for name in NO_ARG_FUNCTIONS:
51 posix_func = getattr(posix, name, None)
52 if posix_func is not None:
53 posix_func()
54 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000055
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020056 @unittest.skipUnless(hasattr(posix, 'getresuid'),
57 'test needs posix.getresuid()')
58 def test_getresuid(self):
59 user_ids = posix.getresuid()
60 self.assertEqual(len(user_ids), 3)
61 for val in user_ids:
62 self.assertGreaterEqual(val, 0)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000063
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020064 @unittest.skipUnless(hasattr(posix, 'getresgid'),
65 'test needs posix.getresgid()')
66 def test_getresgid(self):
67 group_ids = posix.getresgid()
68 self.assertEqual(len(group_ids), 3)
69 for val in group_ids:
70 self.assertGreaterEqual(val, 0)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000071
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020072 @unittest.skipUnless(hasattr(posix, 'setresuid'),
73 'test needs posix.setresuid()')
74 def test_setresuid(self):
75 current_user_ids = posix.getresuid()
76 self.assertIsNone(posix.setresuid(*current_user_ids))
77 # -1 means don't change that value.
78 self.assertIsNone(posix.setresuid(-1, -1, -1))
Martin v. Löwis50ea4562009-11-27 13:56:01 +000079
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020080 @unittest.skipUnless(hasattr(posix, 'setresuid'),
81 'test needs posix.setresuid()')
82 def test_setresuid_exception(self):
83 # Don't do this test if someone is silly enough to run us as root.
84 current_user_ids = posix.getresuid()
85 if 0 not in current_user_ids:
86 new_user_ids = (current_user_ids[0]+1, -1, -1)
87 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000088
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020089 @unittest.skipUnless(hasattr(posix, 'setresgid'),
90 'test needs posix.setresgid()')
91 def test_setresgid(self):
92 current_group_ids = posix.getresgid()
93 self.assertIsNone(posix.setresgid(*current_group_ids))
94 # -1 means don't change that value.
95 self.assertIsNone(posix.setresgid(-1, -1, -1))
Martin v. Löwis50ea4562009-11-27 13:56:01 +000096
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020097 @unittest.skipUnless(hasattr(posix, 'setresgid'),
98 'test needs posix.setresgid()')
99 def test_setresgid_exception(self):
100 # Don't do this test if someone is silly enough to run us as root.
101 current_group_ids = posix.getresgid()
102 if 0 not in current_group_ids:
103 new_group_ids = (current_group_ids[0]+1, -1, -1)
104 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
Martin v. Löwis50ea4562009-11-27 13:56:01 +0000105
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000106 @unittest.skipUnless(hasattr(posix, 'initgroups'),
107 "test needs os.initgroups()")
108 def test_initgroups(self):
109 # It takes a string and an integer; check that it raises a TypeError
110 # for other argument lists.
111 self.assertRaises(TypeError, posix.initgroups)
112 self.assertRaises(TypeError, posix.initgroups, None)
113 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
114 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
115
116 # If a non-privileged user invokes it, it should fail with OSError
117 # EPERM.
118 if os.getuid() != 0:
Charles-François Natali666a5732012-05-02 20:00:37 +0200119 try:
120 name = pwd.getpwuid(posix.getuid()).pw_name
121 except KeyError:
122 # the current UID may not have a pwd entry
123 raise unittest.SkipTest("need a pwd entry")
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000124 try:
125 posix.initgroups(name, 13)
126 except OSError as e:
Ezio Melotti2623a372010-11-21 13:34:58 +0000127 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000128 else:
129 self.fail("Expected OSError to be raised by initgroups")
130
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200131 @unittest.skipUnless(hasattr(posix, 'statvfs'),
132 'test needs posix.statvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000133 def test_statvfs(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200134 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000135
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200136 @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
137 'test needs posix.fstatvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000138 def test_fstatvfs(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200139 fp = open(test_support.TESTFN)
140 try:
141 self.assertTrue(posix.fstatvfs(fp.fileno()))
142 finally:
143 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000144
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200145 @unittest.skipUnless(hasattr(posix, 'ftruncate'),
146 'test needs posix.ftruncate()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000147 def test_ftruncate(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200148 fp = open(test_support.TESTFN, 'w+')
149 try:
150 # we need to have some data to truncate
151 fp.write('test')
152 fp.flush()
153 posix.ftruncate(fp.fileno(), 0)
154 finally:
155 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000156
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200157 @unittest.skipUnless(hasattr(posix, 'dup'),
158 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000159 def test_dup(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200160 fp = open(test_support.TESTFN)
161 try:
162 fd = posix.dup(fp.fileno())
163 self.assertIsInstance(fd, int)
164 os.close(fd)
165 finally:
166 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000167
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200168 @unittest.skipUnless(hasattr(posix, 'confstr'),
169 'test needs posix.confstr()')
Skip Montanaro94785ef2006-04-20 01:29:48 +0000170 def test_confstr(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200171 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
172 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Skip Montanaro94785ef2006-04-20 01:29:48 +0000173
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200174 @unittest.skipUnless(hasattr(posix, 'dup2'),
175 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000176 def test_dup2(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200177 fp1 = open(test_support.TESTFN)
178 fp2 = open(test_support.TESTFN)
179 try:
180 posix.dup2(fp1.fileno(), fp2.fileno())
181 finally:
182 fp1.close()
183 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000184
185 def fdopen_helper(self, *args):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000186 fd = os.open(test_support.TESTFN, os.O_RDONLY)
Neal Norwitze241ce82003-02-17 18:17:05 +0000187 fp2 = posix.fdopen(fd, *args)
188 fp2.close()
189
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200190 @unittest.skipUnless(hasattr(posix, 'fdopen'),
191 'test needs posix.fdopen()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000192 def test_fdopen(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200193 self.fdopen_helper()
194 self.fdopen_helper('r')
195 self.fdopen_helper('r', 100)
Neal Norwitze241ce82003-02-17 18:17:05 +0000196
Benjamin Peterson02ab7a82014-04-09 15:40:18 -0400197 fd = os.open(test_support.TESTFN, os.O_RDONLY)
198 self.assertRaises(OSError, posix.fdopen, fd, 'w')
199 self.assertRaises(OSError, os.close, fd) # fd should be closed.
200
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200201 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
202 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000203 def test_osexlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200204 fd = os.open(test_support.TESTFN,
205 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
206 self.assertRaises(OSError, os.open, test_support.TESTFN,
207 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
208 os.close(fd)
209
210 if hasattr(posix, "O_SHLOCK"):
Skip Montanaro98470002005-06-17 01:14:49 +0000211 fd = os.open(test_support.TESTFN,
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200212 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Skip Montanaro98470002005-06-17 01:14:49 +0000213 self.assertRaises(OSError, os.open, test_support.TESTFN,
214 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
215 os.close(fd)
216
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200217 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
218 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000219 def test_osshlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200220 fd1 = os.open(test_support.TESTFN,
221 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
222 fd2 = os.open(test_support.TESTFN,
223 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
224 os.close(fd2)
225 os.close(fd1)
226
227 if hasattr(posix, "O_EXLOCK"):
228 fd = os.open(test_support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000229 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200230 self.assertRaises(OSError, os.open, test_support.TESTFN,
231 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
232 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000233
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200234 @unittest.skipUnless(hasattr(posix, 'fstat'),
235 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000236 def test_fstat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200237 fp = open(test_support.TESTFN)
238 try:
239 self.assertTrue(posix.fstat(fp.fileno()))
240 finally:
241 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000242
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200243 @unittest.skipUnless(hasattr(posix, 'stat'),
244 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000245 def test_stat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200246 self.assertTrue(posix.stat(test_support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000247
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200248 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000249 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200250 def check_stat(uid, gid):
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200251 if stat_func is not None:
252 stat = stat_func(first_param)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200253 self.assertEqual(stat.st_uid, uid)
254 self.assertEqual(stat.st_gid, gid)
255 uid = os.getuid()
256 gid = os.getgid()
Charles-François Natalif8387642012-04-17 19:46:06 +0200257 # test a successful chown call
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200258 chown_func(first_param, uid, gid)
259 check_stat(uid, gid)
260 chown_func(first_param, -1, gid)
261 check_stat(uid, gid)
262 chown_func(first_param, uid, -1)
263 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200264
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200265 if uid == 0:
266 # Try an amusingly large uid/gid to make sure we handle
267 # large unsigned values. (chown lets you use any
268 # uid/gid you like, even if they aren't defined.)
269 #
270 # This problem keeps coming up:
271 # http://bugs.python.org/issue1747858
272 # http://bugs.python.org/issue4591
273 # http://bugs.python.org/issue15301
274 # Hopefully the fix in 4591 fixes it for good!
275 #
276 # This part of the test only runs when run as root.
277 # Only scary people run their tests as root.
278
279 big_value = 2**31
280 chown_func(first_param, big_value, big_value)
281 check_stat(big_value, big_value)
282 chown_func(first_param, -1, -1)
283 check_stat(big_value, big_value)
284 chown_func(first_param, uid, gid)
285 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200286 elif platform.system() in ('HP-UX', 'SunOS'):
287 # HP-UX and Solaris can allow a non-root user to chown() to root
288 # (issue #5113)
289 raise unittest.SkipTest("Skipping because of non-standard chown() "
290 "behavior")
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000291 else:
292 # non-root cannot chown to root, raises OSError
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200293 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200294 check_stat(uid, gid)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200295 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200296 check_stat(uid, gid)
Serhiy Storchaka484dee32013-02-21 14:33:45 +0200297 if 0 not in os.getgroups():
Serhiy Storchakafffc4792013-02-20 19:47:31 +0200298 self.assertRaises(OSError, chown_func, first_param, -1, 0)
299 check_stat(uid, gid)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200300 # test illegal types
301 for t in str, float:
302 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
303 check_stat(uid, gid)
304 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
305 check_stat(uid, gid)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000306
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000307 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
308 def test_chown(self):
309 # raise an OSError if the file does not exist
310 os.unlink(test_support.TESTFN)
311 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
312
313 # re-create the file
314 open(test_support.TESTFN, 'w').close()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200315 self._test_all_chown_common(posix.chown, test_support.TESTFN,
316 getattr(posix, 'stat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000317
318 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
319 def test_fchown(self):
320 os.unlink(test_support.TESTFN)
321
322 # re-create the file
323 test_file = open(test_support.TESTFN, 'w')
324 try:
325 fd = test_file.fileno()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200326 self._test_all_chown_common(posix.fchown, fd,
327 getattr(posix, 'fstat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000328 finally:
329 test_file.close()
330
331 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
332 def test_lchown(self):
333 os.unlink(test_support.TESTFN)
334 # create a symlink
Ned Deily43e10542011-06-27 23:41:53 -0700335 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200336 self._test_all_chown_common(posix.lchown, test_support.TESTFN,
337 getattr(posix, 'lstat', None))
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000338
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200339 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000340 def test_chdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200341 posix.chdir(os.curdir)
342 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000343
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200344 @unittest.skipUnless(hasattr(posix, 'lsdir'), 'test needs posix.lsdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000345 def test_lsdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200346 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000347
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200348 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000349 def test_access(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200350 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000351
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200352 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000353 def test_umask(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200354 old_mask = posix.umask(0)
355 self.assertIsInstance(old_mask, int)
356 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000357
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200358 @unittest.skipUnless(hasattr(posix, 'strerror'),
359 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000360 def test_strerror(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200361 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000362
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200363 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000364 def test_pipe(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200365 reader, writer = posix.pipe()
366 os.close(reader)
367 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000368
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200369 @unittest.skipUnless(hasattr(posix, 'tempnam'),
370 'test needs posix.tempnam()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000371 def test_tempnam(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200372 with warnings.catch_warnings():
373 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
374 self.assertTrue(posix.tempnam())
375 self.assertTrue(posix.tempnam(os.curdir))
376 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000377
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200378 @unittest.skipUnless(hasattr(posix, 'tmpfile'),
379 'test needs posix.tmpfile()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000380 def test_tmpfile(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200381 with warnings.catch_warnings():
382 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
383 fp = posix.tmpfile()
384 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000385
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200386 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000387 def test_utime(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200388 now = time.time()
389 posix.utime(test_support.TESTFN, None)
390 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
391 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
392 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
393 posix.utime(test_support.TESTFN, (int(now), int(now)))
394 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000395
Ned Deily43e10542011-06-27 23:41:53 -0700396 def _test_chflags_regular_file(self, chflags_func, target_file):
397 st = os.stat(target_file)
398 self.assertTrue(hasattr(st, 'st_flags'))
Victor Stinner8c7c6972012-12-04 10:07:16 +0100399
400 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
401 try:
402 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
403 except OSError as err:
404 if err.errno != errno.EOPNOTSUPP:
405 raise
406 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
407 self.skipTest(msg)
408
Ned Deily43e10542011-06-27 23:41:53 -0700409 try:
410 new_st = os.stat(target_file)
411 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
412 try:
413 fd = open(target_file, 'w+')
414 except IOError as e:
415 self.assertEqual(e.errno, errno.EPERM)
416 finally:
417 posix.chflags(target_file, st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000418
Ned Deily43e10542011-06-27 23:41:53 -0700419 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
420 def test_chflags(self):
421 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN)
422
423 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
424 def test_lchflags_regular_file(self):
425 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN)
426
427 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
428 def test_lchflags_symlink(self):
429 testfn_st = os.stat(test_support.TESTFN)
430
431 self.assertTrue(hasattr(testfn_st, 'st_flags'))
432
433 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK)
434 self.teardown_files.append(_DUMMY_SYMLINK)
435 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
436
Victor Stinner8c7c6972012-12-04 10:07:16 +0100437 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
438 try:
439 posix.lchflags(_DUMMY_SYMLINK,
440 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
441 except OSError as err:
442 if err.errno != errno.EOPNOTSUPP:
443 raise
444 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
445 self.skipTest(msg)
446
Ned Deily43e10542011-06-27 23:41:53 -0700447 try:
448 new_testfn_st = os.stat(test_support.TESTFN)
449 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
450
451 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
452 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
453 new_dummy_symlink_st.st_flags)
454 finally:
455 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000456
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200457 @unittest.skipUnless(hasattr(posix, 'getcwd'),
458 'test needs posix.getcwd()')
Facundo Batista5596b0c2008-06-22 13:36:20 +0000459 def test_getcwd_long_pathnames(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200460 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
461 curdir = os.getcwd()
462 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000463
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200464 try:
465 os.mkdir(base_path)
466 os.chdir(base_path)
467 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600468 self.skipTest("cannot create directory for testing")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000469
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200470 try:
471 def _create_and_do_getcwd(dirname, current_path_length = 0):
472 try:
473 os.mkdir(dirname)
474 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600475 self.skipTest("mkdir cannot create directory sufficiently "
476 "deep for getcwd test")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000477
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200478 os.chdir(dirname)
479 try:
480 os.getcwd()
481 if current_path_length < 4099:
482 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
483 except OSError as e:
484 expected_errno = errno.ENAMETOOLONG
485 # The following platforms have quirky getcwd()
486 # behaviour -- see issue 9185 and 15765 for
487 # more information.
488 quirky_platform = (
489 'sunos' in sys.platform or
490 'netbsd' in sys.platform or
491 'openbsd' in sys.platform
492 )
493 if quirky_platform:
494 expected_errno = errno.ERANGE
495 self.assertEqual(e.errno, expected_errno)
496 finally:
497 os.chdir('..')
498 os.rmdir(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000499
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200500 _create_and_do_getcwd(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000501
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200502 finally:
503 os.chdir(curdir)
504 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000505
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000506 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000507 def test_getgroups(self):
508 with os.popen('id -G') as idg:
509 groups = idg.read().strip()
Charles-François Natali666a5732012-05-02 20:00:37 +0200510 ret = idg.close()
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000511
Charles-François Natalidee8dad2012-05-02 20:48:21 +0200512 if ret != None or not groups:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000513 raise unittest.SkipTest("need working 'id -G'")
514
Ned Deilycc23cc62013-02-02 15:06:45 -0800515 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
516 if sys.platform == 'darwin':
517 import sysconfig
518 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
519 if float(dt) < 10.6:
520 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
521
Ronald Oussorenac72e582010-08-03 07:31:12 +0000522 # 'id -G' and 'os.getgroups()' should return the same
523 # groups, ignoring order and duplicates.
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000524 # #10822 - it is implementation defined whether posix.getgroups()
525 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussoren5719c2f2010-07-24 14:21:29 +0000526 self.assertEqual(
Ronald Oussorenac72e582010-08-03 07:31:12 +0000527 set([int(x) for x in groups.split()]),
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000528 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000529
530class PosixGroupsTester(unittest.TestCase):
531
532 def setUp(self):
533 if posix.getuid() != 0:
534 raise unittest.SkipTest("not enough privileges")
535 if not hasattr(posix, 'getgroups'):
536 raise unittest.SkipTest("need posix.getgroups")
537 if sys.platform == 'darwin':
538 raise unittest.SkipTest("getgroups(2) is broken on OSX")
539 self.saved_groups = posix.getgroups()
540
541 def tearDown(self):
542 if hasattr(posix, 'setgroups'):
543 posix.setgroups(self.saved_groups)
544 elif hasattr(posix, 'initgroups'):
545 name = pwd.getpwuid(posix.getuid()).pw_name
546 posix.initgroups(name, self.saved_groups[0])
547
548 @unittest.skipUnless(hasattr(posix, 'initgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200549 'test needs posix.initgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000550 def test_initgroups(self):
551 # find missing group
552
Benjamin Petersonbde1cfb2014-03-01 19:14:12 -0500553 g = max(self.saved_groups or [0]) + 1
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000554 name = pwd.getpwuid(posix.getuid()).pw_name
555 posix.initgroups(name, g)
556 self.assertIn(g, posix.getgroups())
557
558 @unittest.skipUnless(hasattr(posix, 'setgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200559 'test needs posix.setgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000560 def test_setgroups(self):
561 for groups in [[0], range(16)]:
562 posix.setgroups(groups)
563 self.assertListEqual(groups, posix.getgroups())
564
Facundo Batista5596b0c2008-06-22 13:36:20 +0000565
Neal Norwitze241ce82003-02-17 18:17:05 +0000566def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000567 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000568
569if __name__ == '__main__':
570 test_main()