blob: b0a8cdf564d5d124839953c3ec61f7a7a4488ac8 [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
Martin v. Löwis50ea4562009-11-27 13:56:01 +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 Pitrou30b3b352009-12-02 20:37:54 +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:
Charles-François Natali666a5732012-05-02 20:00:37 +0200111 try:
112 name = pwd.getpwuid(posix.getuid()).pw_name
113 except KeyError:
114 # the current UID may not have a pwd entry
115 raise unittest.SkipTest("need a pwd entry")
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000116 try:
117 posix.initgroups(name, 13)
118 except OSError as e:
Ezio Melotti2623a372010-11-21 13:34:58 +0000119 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000120 else:
121 self.fail("Expected OSError to be raised by initgroups")
122
Neal Norwitze241ce82003-02-17 18:17:05 +0000123 def test_statvfs(self):
124 if hasattr(posix, 'statvfs'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000125 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000126
127 def test_fstatvfs(self):
128 if hasattr(posix, 'fstatvfs'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000129 fp = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000130 try:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000131 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000132 finally:
133 fp.close()
134
135 def test_ftruncate(self):
136 if hasattr(posix, 'ftruncate'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000137 fp = open(test_support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000138 try:
139 # we need to have some data to truncate
140 fp.write('test')
141 fp.flush()
142 posix.ftruncate(fp.fileno(), 0)
143 finally:
144 fp.close()
145
146 def test_dup(self):
147 if hasattr(posix, 'dup'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000148 fp = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000149 try:
150 fd = posix.dup(fp.fileno())
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000151 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000152 os.close(fd)
153 finally:
154 fp.close()
155
Skip Montanaro94785ef2006-04-20 01:29:48 +0000156 def test_confstr(self):
157 if hasattr(posix, 'confstr'):
158 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
159 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
160
Neal Norwitze241ce82003-02-17 18:17:05 +0000161 def test_dup2(self):
162 if hasattr(posix, 'dup2'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000163 fp1 = open(test_support.TESTFN)
164 fp2 = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000165 try:
166 posix.dup2(fp1.fileno(), fp2.fileno())
167 finally:
168 fp1.close()
169 fp2.close()
170
171 def fdopen_helper(self, *args):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000172 fd = os.open(test_support.TESTFN, os.O_RDONLY)
Neal Norwitze241ce82003-02-17 18:17:05 +0000173 fp2 = posix.fdopen(fd, *args)
174 fp2.close()
175
176 def test_fdopen(self):
177 if hasattr(posix, 'fdopen'):
178 self.fdopen_helper()
179 self.fdopen_helper('r')
180 self.fdopen_helper('r', 100)
181
Skip Montanaro98470002005-06-17 01:14:49 +0000182 def test_osexlock(self):
183 if hasattr(posix, "O_EXLOCK"):
184 fd = os.open(test_support.TESTFN,
185 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
186 self.assertRaises(OSError, os.open, test_support.TESTFN,
187 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
188 os.close(fd)
189
190 if hasattr(posix, "O_SHLOCK"):
191 fd = os.open(test_support.TESTFN,
192 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
193 self.assertRaises(OSError, os.open, test_support.TESTFN,
194 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
195 os.close(fd)
196
197 def test_osshlock(self):
198 if hasattr(posix, "O_SHLOCK"):
199 fd1 = os.open(test_support.TESTFN,
200 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
201 fd2 = os.open(test_support.TESTFN,
202 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
203 os.close(fd2)
204 os.close(fd1)
205
206 if hasattr(posix, "O_EXLOCK"):
207 fd = os.open(test_support.TESTFN,
208 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
209 self.assertRaises(OSError, os.open, test_support.TESTFN,
210 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
211 os.close(fd)
212
Neal Norwitze241ce82003-02-17 18:17:05 +0000213 def test_fstat(self):
214 if hasattr(posix, 'fstat'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000215 fp = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000216 try:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000217 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000218 finally:
219 fp.close()
220
221 def test_stat(self):
222 if hasattr(posix, 'stat'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000223 self.assertTrue(posix.stat(test_support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000224
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200225 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000226 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200227 def check_stat(uid, gid):
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200228 if stat_func is not None:
229 stat = stat_func(first_param)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200230 self.assertEqual(stat.st_uid, uid)
231 self.assertEqual(stat.st_gid, gid)
232 uid = os.getuid()
233 gid = os.getgid()
Charles-François Natalif8387642012-04-17 19:46:06 +0200234 # test a successful chown call
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200235 chown_func(first_param, uid, gid)
236 check_stat(uid, gid)
237 chown_func(first_param, -1, gid)
238 check_stat(uid, gid)
239 chown_func(first_param, uid, -1)
240 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200241
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200242 if uid == 0:
243 # Try an amusingly large uid/gid to make sure we handle
244 # large unsigned values. (chown lets you use any
245 # uid/gid you like, even if they aren't defined.)
246 #
247 # This problem keeps coming up:
248 # http://bugs.python.org/issue1747858
249 # http://bugs.python.org/issue4591
250 # http://bugs.python.org/issue15301
251 # Hopefully the fix in 4591 fixes it for good!
252 #
253 # This part of the test only runs when run as root.
254 # Only scary people run their tests as root.
255
256 big_value = 2**31
257 chown_func(first_param, big_value, big_value)
258 check_stat(big_value, big_value)
259 chown_func(first_param, -1, -1)
260 check_stat(big_value, big_value)
261 chown_func(first_param, uid, gid)
262 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200263 elif platform.system() in ('HP-UX', 'SunOS'):
264 # HP-UX and Solaris can allow a non-root user to chown() to root
265 # (issue #5113)
266 raise unittest.SkipTest("Skipping because of non-standard chown() "
267 "behavior")
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000268 else:
269 # non-root cannot chown to root, raises OSError
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200270 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200271 check_stat(uid, gid)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200272 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200273 check_stat(uid, gid)
Serhiy Storchaka484dee32013-02-21 14:33:45 +0200274 if 0 not in os.getgroups():
Serhiy Storchakafffc4792013-02-20 19:47:31 +0200275 self.assertRaises(OSError, chown_func, first_param, -1, 0)
276 check_stat(uid, gid)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200277 # test illegal types
278 for t in str, float:
279 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
280 check_stat(uid, gid)
281 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
282 check_stat(uid, gid)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000283
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000284 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
285 def test_chown(self):
286 # raise an OSError if the file does not exist
287 os.unlink(test_support.TESTFN)
288 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
289
290 # re-create the file
291 open(test_support.TESTFN, 'w').close()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200292 self._test_all_chown_common(posix.chown, test_support.TESTFN,
293 getattr(posix, 'stat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000294
295 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
296 def test_fchown(self):
297 os.unlink(test_support.TESTFN)
298
299 # re-create the file
300 test_file = open(test_support.TESTFN, 'w')
301 try:
302 fd = test_file.fileno()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200303 self._test_all_chown_common(posix.fchown, fd,
304 getattr(posix, 'fstat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000305 finally:
306 test_file.close()
307
308 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
309 def test_lchown(self):
310 os.unlink(test_support.TESTFN)
311 # create a symlink
Ned Deily43e10542011-06-27 23:41:53 -0700312 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200313 self._test_all_chown_common(posix.lchown, test_support.TESTFN,
314 getattr(posix, 'lstat', None))
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000315
Neal Norwitze241ce82003-02-17 18:17:05 +0000316 def test_chdir(self):
317 if hasattr(posix, 'chdir'):
318 posix.chdir(os.curdir)
Walter Dörwald21d3a322003-05-01 17:45:56 +0000319 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000320
321 def test_lsdir(self):
322 if hasattr(posix, 'lsdir'):
Ezio Melottiaa980582010-01-23 23:04:36 +0000323 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000324
325 def test_access(self):
326 if hasattr(posix, 'access'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000327 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000328
329 def test_umask(self):
330 if hasattr(posix, 'umask'):
331 old_mask = posix.umask(0)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000332 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000333 posix.umask(old_mask)
334
335 def test_strerror(self):
336 if hasattr(posix, 'strerror'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000337 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000338
339 def test_pipe(self):
340 if hasattr(posix, 'pipe'):
Antoine Pitroubba8f2d2010-04-10 23:32:12 +0000341 reader, writer = posix.pipe()
342 os.close(reader)
343 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000344
345 def test_tempnam(self):
346 if hasattr(posix, 'tempnam'):
Antoine Pitroub0614612011-01-02 20:04:52 +0000347 with warnings.catch_warnings():
348 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
349 self.assertTrue(posix.tempnam())
350 self.assertTrue(posix.tempnam(os.curdir))
351 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000352
353 def test_tmpfile(self):
354 if hasattr(posix, 'tmpfile'):
Antoine Pitroub0614612011-01-02 20:04:52 +0000355 with warnings.catch_warnings():
356 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
357 fp = posix.tmpfile()
358 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000359
360 def test_utime(self):
361 if hasattr(posix, 'utime'):
362 now = time.time()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000363 posix.utime(test_support.TESTFN, None)
Neal Norwitzc28e7ad2004-06-06 20:27:05 +0000364 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
365 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
366 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
367 posix.utime(test_support.TESTFN, (int(now), int(now)))
Walter Dörwald21d3a322003-05-01 17:45:56 +0000368 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000369
Ned Deily43e10542011-06-27 23:41:53 -0700370 def _test_chflags_regular_file(self, chflags_func, target_file):
371 st = os.stat(target_file)
372 self.assertTrue(hasattr(st, 'st_flags'))
Victor Stinner8c7c6972012-12-04 10:07:16 +0100373
374 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
375 try:
376 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
377 except OSError as err:
378 if err.errno != errno.EOPNOTSUPP:
379 raise
380 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
381 self.skipTest(msg)
382
Ned Deily43e10542011-06-27 23:41:53 -0700383 try:
384 new_st = os.stat(target_file)
385 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
386 try:
387 fd = open(target_file, 'w+')
388 except IOError as e:
389 self.assertEqual(e.errno, errno.EPERM)
390 finally:
391 posix.chflags(target_file, st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000392
Ned Deily43e10542011-06-27 23:41:53 -0700393 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
394 def test_chflags(self):
395 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN)
396
397 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
398 def test_lchflags_regular_file(self):
399 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN)
400
401 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
402 def test_lchflags_symlink(self):
403 testfn_st = os.stat(test_support.TESTFN)
404
405 self.assertTrue(hasattr(testfn_st, 'st_flags'))
406
407 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK)
408 self.teardown_files.append(_DUMMY_SYMLINK)
409 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
410
Victor Stinner8c7c6972012-12-04 10:07:16 +0100411 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
412 try:
413 posix.lchflags(_DUMMY_SYMLINK,
414 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
415 except OSError as err:
416 if err.errno != errno.EOPNOTSUPP:
417 raise
418 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
419 self.skipTest(msg)
420
Ned Deily43e10542011-06-27 23:41:53 -0700421 try:
422 new_testfn_st = os.stat(test_support.TESTFN)
423 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
424
425 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
426 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
427 new_dummy_symlink_st.st_flags)
428 finally:
429 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000430
Facundo Batista5596b0c2008-06-22 13:36:20 +0000431 def test_getcwd_long_pathnames(self):
432 if hasattr(posix, 'getcwd'):
433 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
434 curdir = os.getcwd()
Facundo Batista96f3dc32008-06-22 18:23:55 +0000435 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000436
437 try:
438 os.mkdir(base_path)
439 os.chdir(base_path)
Facundo Batista96f3dc32008-06-22 18:23:55 +0000440 except:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000441# Just returning nothing instead of the SkipTest exception,
Facundo Batista2694eb02008-06-22 19:35:24 +0000442# because the test results in Error in that case.
443# Is that ok?
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000444# raise unittest.SkipTest, "cannot create directory for testing"
Facundo Batista2694eb02008-06-22 19:35:24 +0000445 return
Facundo Batista5596b0c2008-06-22 13:36:20 +0000446
Facundo Batista96f3dc32008-06-22 18:23:55 +0000447 try:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000448 def _create_and_do_getcwd(dirname, current_path_length = 0):
449 try:
450 os.mkdir(dirname)
451 except:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000452 raise unittest.SkipTest, "mkdir cannot create directory sufficiently deep for getcwd test"
Facundo Batista5596b0c2008-06-22 13:36:20 +0000453
454 os.chdir(dirname)
455 try:
456 os.getcwd()
Stefan Krah182ae642010-07-13 19:17:08 +0000457 if current_path_length < 4099:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000458 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
Stefan Krah182ae642010-07-13 19:17:08 +0000459 except OSError as e:
460 expected_errno = errno.ENAMETOOLONG
Trent Nelsonda4277a2012-08-29 09:20:41 -0400461 # The following platforms have quirky getcwd()
462 # behaviour -- see issue 9185 and 15765 for
463 # more information.
464 quirky_platform = (
465 'sunos' in sys.platform or
466 'netbsd' in sys.platform or
467 'openbsd' in sys.platform
468 )
469 if quirky_platform:
470 expected_errno = errno.ERANGE
Stefan Krah182ae642010-07-13 19:17:08 +0000471 self.assertEqual(e.errno, expected_errno)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000472 finally:
473 os.chdir('..')
474 os.rmdir(dirname)
475
476 _create_and_do_getcwd(dirname)
477
478 finally:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000479 os.chdir(curdir)
R. David Murrayb0c828a2009-07-09 18:41:03 +0000480 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000481
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000482 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000483 def test_getgroups(self):
484 with os.popen('id -G') as idg:
485 groups = idg.read().strip()
Charles-François Natali666a5732012-05-02 20:00:37 +0200486 ret = idg.close()
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000487
Charles-François Natalidee8dad2012-05-02 20:48:21 +0200488 if ret != None or not groups:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000489 raise unittest.SkipTest("need working 'id -G'")
490
Ned Deilycc23cc62013-02-02 15:06:45 -0800491 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
492 if sys.platform == 'darwin':
493 import sysconfig
494 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
495 if float(dt) < 10.6:
496 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
497
Ronald Oussorenac72e582010-08-03 07:31:12 +0000498 # 'id -G' and 'os.getgroups()' should return the same
499 # groups, ignoring order and duplicates.
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000500 # #10822 - it is implementation defined whether posix.getgroups()
501 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussoren5719c2f2010-07-24 14:21:29 +0000502 self.assertEqual(
Ronald Oussorenac72e582010-08-03 07:31:12 +0000503 set([int(x) for x in groups.split()]),
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000504 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000505
506class PosixGroupsTester(unittest.TestCase):
507
508 def setUp(self):
509 if posix.getuid() != 0:
510 raise unittest.SkipTest("not enough privileges")
511 if not hasattr(posix, 'getgroups'):
512 raise unittest.SkipTest("need posix.getgroups")
513 if sys.platform == 'darwin':
514 raise unittest.SkipTest("getgroups(2) is broken on OSX")
515 self.saved_groups = posix.getgroups()
516
517 def tearDown(self):
518 if hasattr(posix, 'setgroups'):
519 posix.setgroups(self.saved_groups)
520 elif hasattr(posix, 'initgroups'):
521 name = pwd.getpwuid(posix.getuid()).pw_name
522 posix.initgroups(name, self.saved_groups[0])
523
524 @unittest.skipUnless(hasattr(posix, 'initgroups'),
525 "test needs posix.initgroups()")
526 def test_initgroups(self):
527 # find missing group
528
Antoine Pitroudd806ce2010-09-04 17:34:12 +0000529 g = max(self.saved_groups) + 1
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000530 name = pwd.getpwuid(posix.getuid()).pw_name
531 posix.initgroups(name, g)
532 self.assertIn(g, posix.getgroups())
533
534 @unittest.skipUnless(hasattr(posix, 'setgroups'),
535 "test needs posix.setgroups()")
536 def test_setgroups(self):
537 for groups in [[0], range(16)]:
538 posix.setgroups(groups)
539 self.assertListEqual(groups, posix.getgroups())
540
Facundo Batista5596b0c2008-06-22 13:36:20 +0000541
Neal Norwitze241ce82003-02-17 18:17:05 +0000542def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000543 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000544
545if __name__ == '__main__':
546 test_main()