blob: f995a9cb7568834c9518c254c88f9c3564e2cc92 [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 Storchakada5c2a02013-02-12 09:27:53 +0200227 def check_stat():
228 if stat_func is not None:
229 stat = stat_func(first_param)
230 self.assertEqual(stat.st_uid, os.getuid())
231 self.assertEqual(stat.st_gid, os.getgid())
Charles-François Natalif8387642012-04-17 19:46:06 +0200232 # test a successful chown call
233 chown_func(first_param, os.getuid(), os.getgid())
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200234 check_stat()
235 chown_func(first_param, -1, os.getgid())
236 check_stat()
237 chown_func(first_param, os.getuid(), -1)
238 check_stat()
Charles-François Natalif8387642012-04-17 19:46:06 +0200239
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000240 if os.getuid() == 0:
241 try:
242 # Many linux distros have a nfsnobody user as MAX_UID-2
243 # that makes a good test case for signedness issues.
244 # http://bugs.python.org/issue1747858
245 # This part of the test only runs when run as root.
246 # Only scary people run their tests as root.
247 ent = pwd.getpwnam('nfsnobody')
248 chown_func(first_param, ent.pw_uid, ent.pw_gid)
249 except KeyError:
250 pass
Charles-François Natalif8387642012-04-17 19:46:06 +0200251 elif platform.system() in ('HP-UX', 'SunOS'):
252 # HP-UX and Solaris can allow a non-root user to chown() to root
253 # (issue #5113)
254 raise unittest.SkipTest("Skipping because of non-standard chown() "
255 "behavior")
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000256 else:
257 # non-root cannot chown to root, raises OSError
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200258 self.assertRaises(OSError, chown_func, first_param, 0, 0)
259 check_stat()
260 self.assertRaises(OSError, chown_func, first_param, -1, 0)
261 check_stat()
262 self.assertRaises(OSError, chown_func, first_param, 0, -1)
263 check_stat()
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000264
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000265 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
266 def test_chown(self):
267 # raise an OSError if the file does not exist
268 os.unlink(test_support.TESTFN)
269 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
270
271 # re-create the file
272 open(test_support.TESTFN, 'w').close()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200273 self._test_all_chown_common(posix.chown, test_support.TESTFN,
274 getattr(posix, 'stat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000275
276 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
277 def test_fchown(self):
278 os.unlink(test_support.TESTFN)
279
280 # re-create the file
281 test_file = open(test_support.TESTFN, 'w')
282 try:
283 fd = test_file.fileno()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200284 self._test_all_chown_common(posix.fchown, fd,
285 getattr(posix, 'fstat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000286 finally:
287 test_file.close()
288
289 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
290 def test_lchown(self):
291 os.unlink(test_support.TESTFN)
292 # create a symlink
Ned Deily43e10542011-06-27 23:41:53 -0700293 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200294 self._test_all_chown_common(posix.lchown, test_support.TESTFN,
295 getattr(posix, 'lstat', None))
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000296
Neal Norwitze241ce82003-02-17 18:17:05 +0000297 def test_chdir(self):
298 if hasattr(posix, 'chdir'):
299 posix.chdir(os.curdir)
Walter Dörwald21d3a322003-05-01 17:45:56 +0000300 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000301
302 def test_lsdir(self):
303 if hasattr(posix, 'lsdir'):
Ezio Melottiaa980582010-01-23 23:04:36 +0000304 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000305
306 def test_access(self):
307 if hasattr(posix, 'access'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000308 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000309
310 def test_umask(self):
311 if hasattr(posix, 'umask'):
312 old_mask = posix.umask(0)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000313 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000314 posix.umask(old_mask)
315
316 def test_strerror(self):
317 if hasattr(posix, 'strerror'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000318 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000319
320 def test_pipe(self):
321 if hasattr(posix, 'pipe'):
Antoine Pitroubba8f2d2010-04-10 23:32:12 +0000322 reader, writer = posix.pipe()
323 os.close(reader)
324 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000325
326 def test_tempnam(self):
327 if hasattr(posix, 'tempnam'):
Antoine Pitroub0614612011-01-02 20:04:52 +0000328 with warnings.catch_warnings():
329 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
330 self.assertTrue(posix.tempnam())
331 self.assertTrue(posix.tempnam(os.curdir))
332 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000333
334 def test_tmpfile(self):
335 if hasattr(posix, 'tmpfile'):
Antoine Pitroub0614612011-01-02 20:04:52 +0000336 with warnings.catch_warnings():
337 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
338 fp = posix.tmpfile()
339 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000340
341 def test_utime(self):
342 if hasattr(posix, 'utime'):
343 now = time.time()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000344 posix.utime(test_support.TESTFN, None)
Neal Norwitzc28e7ad2004-06-06 20:27:05 +0000345 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
346 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
347 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
348 posix.utime(test_support.TESTFN, (int(now), int(now)))
Walter Dörwald21d3a322003-05-01 17:45:56 +0000349 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000350
Ned Deily43e10542011-06-27 23:41:53 -0700351 def _test_chflags_regular_file(self, chflags_func, target_file):
352 st = os.stat(target_file)
353 self.assertTrue(hasattr(st, 'st_flags'))
Victor Stinner8c7c6972012-12-04 10:07:16 +0100354
355 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
356 try:
357 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
358 except OSError as err:
359 if err.errno != errno.EOPNOTSUPP:
360 raise
361 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
362 self.skipTest(msg)
363
Ned Deily43e10542011-06-27 23:41:53 -0700364 try:
365 new_st = os.stat(target_file)
366 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
367 try:
368 fd = open(target_file, 'w+')
369 except IOError as e:
370 self.assertEqual(e.errno, errno.EPERM)
371 finally:
372 posix.chflags(target_file, st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000373
Ned Deily43e10542011-06-27 23:41:53 -0700374 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
375 def test_chflags(self):
376 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN)
377
378 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
379 def test_lchflags_regular_file(self):
380 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN)
381
382 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
383 def test_lchflags_symlink(self):
384 testfn_st = os.stat(test_support.TESTFN)
385
386 self.assertTrue(hasattr(testfn_st, 'st_flags'))
387
388 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK)
389 self.teardown_files.append(_DUMMY_SYMLINK)
390 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
391
Victor Stinner8c7c6972012-12-04 10:07:16 +0100392 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
393 try:
394 posix.lchflags(_DUMMY_SYMLINK,
395 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
396 except OSError as err:
397 if err.errno != errno.EOPNOTSUPP:
398 raise
399 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
400 self.skipTest(msg)
401
Ned Deily43e10542011-06-27 23:41:53 -0700402 try:
403 new_testfn_st = os.stat(test_support.TESTFN)
404 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
405
406 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
407 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
408 new_dummy_symlink_st.st_flags)
409 finally:
410 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000411
Facundo Batista5596b0c2008-06-22 13:36:20 +0000412 def test_getcwd_long_pathnames(self):
413 if hasattr(posix, 'getcwd'):
414 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
415 curdir = os.getcwd()
Facundo Batista96f3dc32008-06-22 18:23:55 +0000416 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000417
418 try:
419 os.mkdir(base_path)
420 os.chdir(base_path)
Facundo Batista96f3dc32008-06-22 18:23:55 +0000421 except:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000422# Just returning nothing instead of the SkipTest exception,
Facundo Batista2694eb02008-06-22 19:35:24 +0000423# because the test results in Error in that case.
424# Is that ok?
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000425# raise unittest.SkipTest, "cannot create directory for testing"
Facundo Batista2694eb02008-06-22 19:35:24 +0000426 return
Facundo Batista5596b0c2008-06-22 13:36:20 +0000427
Facundo Batista96f3dc32008-06-22 18:23:55 +0000428 try:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000429 def _create_and_do_getcwd(dirname, current_path_length = 0):
430 try:
431 os.mkdir(dirname)
432 except:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000433 raise unittest.SkipTest, "mkdir cannot create directory sufficiently deep for getcwd test"
Facundo Batista5596b0c2008-06-22 13:36:20 +0000434
435 os.chdir(dirname)
436 try:
437 os.getcwd()
Stefan Krah182ae642010-07-13 19:17:08 +0000438 if current_path_length < 4099:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000439 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
Stefan Krah182ae642010-07-13 19:17:08 +0000440 except OSError as e:
441 expected_errno = errno.ENAMETOOLONG
Trent Nelsonda4277a2012-08-29 09:20:41 -0400442 # The following platforms have quirky getcwd()
443 # behaviour -- see issue 9185 and 15765 for
444 # more information.
445 quirky_platform = (
446 'sunos' in sys.platform or
447 'netbsd' in sys.platform or
448 'openbsd' in sys.platform
449 )
450 if quirky_platform:
451 expected_errno = errno.ERANGE
Stefan Krah182ae642010-07-13 19:17:08 +0000452 self.assertEqual(e.errno, expected_errno)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000453 finally:
454 os.chdir('..')
455 os.rmdir(dirname)
456
457 _create_and_do_getcwd(dirname)
458
459 finally:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000460 os.chdir(curdir)
R. David Murrayb0c828a2009-07-09 18:41:03 +0000461 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000462
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000463 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000464 def test_getgroups(self):
465 with os.popen('id -G') as idg:
466 groups = idg.read().strip()
Charles-François Natali666a5732012-05-02 20:00:37 +0200467 ret = idg.close()
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000468
Charles-François Natalidee8dad2012-05-02 20:48:21 +0200469 if ret != None or not groups:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000470 raise unittest.SkipTest("need working 'id -G'")
471
Ned Deilycc23cc62013-02-02 15:06:45 -0800472 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
473 if sys.platform == 'darwin':
474 import sysconfig
475 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
476 if float(dt) < 10.6:
477 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
478
Ronald Oussorenac72e582010-08-03 07:31:12 +0000479 # 'id -G' and 'os.getgroups()' should return the same
480 # groups, ignoring order and duplicates.
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000481 # #10822 - it is implementation defined whether posix.getgroups()
482 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussoren5719c2f2010-07-24 14:21:29 +0000483 self.assertEqual(
Ronald Oussorenac72e582010-08-03 07:31:12 +0000484 set([int(x) for x in groups.split()]),
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000485 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000486
487class PosixGroupsTester(unittest.TestCase):
488
489 def setUp(self):
490 if posix.getuid() != 0:
491 raise unittest.SkipTest("not enough privileges")
492 if not hasattr(posix, 'getgroups'):
493 raise unittest.SkipTest("need posix.getgroups")
494 if sys.platform == 'darwin':
495 raise unittest.SkipTest("getgroups(2) is broken on OSX")
496 self.saved_groups = posix.getgroups()
497
498 def tearDown(self):
499 if hasattr(posix, 'setgroups'):
500 posix.setgroups(self.saved_groups)
501 elif hasattr(posix, 'initgroups'):
502 name = pwd.getpwuid(posix.getuid()).pw_name
503 posix.initgroups(name, self.saved_groups[0])
504
505 @unittest.skipUnless(hasattr(posix, 'initgroups'),
506 "test needs posix.initgroups()")
507 def test_initgroups(self):
508 # find missing group
509
Antoine Pitroudd806ce2010-09-04 17:34:12 +0000510 g = max(self.saved_groups) + 1
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000511 name = pwd.getpwuid(posix.getuid()).pw_name
512 posix.initgroups(name, g)
513 self.assertIn(g, posix.getgroups())
514
515 @unittest.skipUnless(hasattr(posix, 'setgroups'),
516 "test needs posix.setgroups()")
517 def test_setgroups(self):
518 for groups in [[0], range(16)]:
519 posix.setgroups(groups)
520 self.assertListEqual(groups, posix.getgroups())
521
Facundo Batista5596b0c2008-06-22 13:36:20 +0000522
Neal Norwitze241ce82003-02-17 18:17:05 +0000523def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000524 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000525
526if __name__ == '__main__':
527 test_main()