blob: 7214efa323d9c2583ca68cdadf33c1b7ec30d772 [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
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000225 def _test_all_chown_common(self, chown_func, first_param):
226 """Common code for chown, fchown and lchown tests."""
Charles-François Natalif8387642012-04-17 19:46:06 +0200227 # test a successful chown call
228 chown_func(first_param, os.getuid(), os.getgid())
229
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000230 if os.getuid() == 0:
231 try:
232 # Many linux distros have a nfsnobody user as MAX_UID-2
233 # that makes a good test case for signedness issues.
234 # http://bugs.python.org/issue1747858
235 # This part of the test only runs when run as root.
236 # Only scary people run their tests as root.
237 ent = pwd.getpwnam('nfsnobody')
238 chown_func(first_param, ent.pw_uid, ent.pw_gid)
239 except KeyError:
240 pass
Charles-François Natalif8387642012-04-17 19:46:06 +0200241 elif platform.system() in ('HP-UX', 'SunOS'):
242 # HP-UX and Solaris can allow a non-root user to chown() to root
243 # (issue #5113)
244 raise unittest.SkipTest("Skipping because of non-standard chown() "
245 "behavior")
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000246 else:
247 # non-root cannot chown to root, raises OSError
248 self.assertRaises(OSError, chown_func,
249 first_param, 0, 0)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000250
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000251 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
252 def test_chown(self):
253 # raise an OSError if the file does not exist
254 os.unlink(test_support.TESTFN)
255 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
256
257 # re-create the file
258 open(test_support.TESTFN, 'w').close()
259 self._test_all_chown_common(posix.chown, test_support.TESTFN)
260
261 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
262 def test_fchown(self):
263 os.unlink(test_support.TESTFN)
264
265 # re-create the file
266 test_file = open(test_support.TESTFN, 'w')
267 try:
268 fd = test_file.fileno()
269 self._test_all_chown_common(posix.fchown, fd)
270 finally:
271 test_file.close()
272
273 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
274 def test_lchown(self):
275 os.unlink(test_support.TESTFN)
276 # create a symlink
Ned Deily43e10542011-06-27 23:41:53 -0700277 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000278 self._test_all_chown_common(posix.lchown, test_support.TESTFN)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000279
Neal Norwitze241ce82003-02-17 18:17:05 +0000280 def test_chdir(self):
281 if hasattr(posix, 'chdir'):
282 posix.chdir(os.curdir)
Walter Dörwald21d3a322003-05-01 17:45:56 +0000283 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000284
285 def test_lsdir(self):
286 if hasattr(posix, 'lsdir'):
Ezio Melottiaa980582010-01-23 23:04:36 +0000287 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000288
289 def test_access(self):
290 if hasattr(posix, 'access'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000291 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000292
293 def test_umask(self):
294 if hasattr(posix, 'umask'):
295 old_mask = posix.umask(0)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000296 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000297 posix.umask(old_mask)
298
299 def test_strerror(self):
300 if hasattr(posix, 'strerror'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000301 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000302
303 def test_pipe(self):
304 if hasattr(posix, 'pipe'):
Antoine Pitroubba8f2d2010-04-10 23:32:12 +0000305 reader, writer = posix.pipe()
306 os.close(reader)
307 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000308
309 def test_tempnam(self):
310 if hasattr(posix, 'tempnam'):
Antoine Pitroub0614612011-01-02 20:04:52 +0000311 with warnings.catch_warnings():
312 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
313 self.assertTrue(posix.tempnam())
314 self.assertTrue(posix.tempnam(os.curdir))
315 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000316
317 def test_tmpfile(self):
318 if hasattr(posix, 'tmpfile'):
Antoine Pitroub0614612011-01-02 20:04:52 +0000319 with warnings.catch_warnings():
320 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
321 fp = posix.tmpfile()
322 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000323
324 def test_utime(self):
325 if hasattr(posix, 'utime'):
326 now = time.time()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000327 posix.utime(test_support.TESTFN, None)
Neal Norwitzc28e7ad2004-06-06 20:27:05 +0000328 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
329 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
330 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
331 posix.utime(test_support.TESTFN, (int(now), int(now)))
Walter Dörwald21d3a322003-05-01 17:45:56 +0000332 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000333
Ned Deily43e10542011-06-27 23:41:53 -0700334 def _test_chflags_regular_file(self, chflags_func, target_file):
335 st = os.stat(target_file)
336 self.assertTrue(hasattr(st, 'st_flags'))
Victor Stinner8c7c6972012-12-04 10:07:16 +0100337
338 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
339 try:
340 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
341 except OSError as err:
342 if err.errno != errno.EOPNOTSUPP:
343 raise
344 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
345 self.skipTest(msg)
346
Ned Deily43e10542011-06-27 23:41:53 -0700347 try:
348 new_st = os.stat(target_file)
349 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
350 try:
351 fd = open(target_file, 'w+')
352 except IOError as e:
353 self.assertEqual(e.errno, errno.EPERM)
354 finally:
355 posix.chflags(target_file, st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000356
Ned Deily43e10542011-06-27 23:41:53 -0700357 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
358 def test_chflags(self):
359 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN)
360
361 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
362 def test_lchflags_regular_file(self):
363 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN)
364
365 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
366 def test_lchflags_symlink(self):
367 testfn_st = os.stat(test_support.TESTFN)
368
369 self.assertTrue(hasattr(testfn_st, 'st_flags'))
370
371 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK)
372 self.teardown_files.append(_DUMMY_SYMLINK)
373 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
374
Victor Stinner8c7c6972012-12-04 10:07:16 +0100375 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
376 try:
377 posix.lchflags(_DUMMY_SYMLINK,
378 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
379 except OSError as err:
380 if err.errno != errno.EOPNOTSUPP:
381 raise
382 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
383 self.skipTest(msg)
384
Ned Deily43e10542011-06-27 23:41:53 -0700385 try:
386 new_testfn_st = os.stat(test_support.TESTFN)
387 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
388
389 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
390 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
391 new_dummy_symlink_st.st_flags)
392 finally:
393 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000394
Facundo Batista5596b0c2008-06-22 13:36:20 +0000395 def test_getcwd_long_pathnames(self):
396 if hasattr(posix, 'getcwd'):
397 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
398 curdir = os.getcwd()
Facundo Batista96f3dc32008-06-22 18:23:55 +0000399 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000400
401 try:
402 os.mkdir(base_path)
403 os.chdir(base_path)
Facundo Batista96f3dc32008-06-22 18:23:55 +0000404 except:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000405# Just returning nothing instead of the SkipTest exception,
Facundo Batista2694eb02008-06-22 19:35:24 +0000406# because the test results in Error in that case.
407# Is that ok?
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000408# raise unittest.SkipTest, "cannot create directory for testing"
Facundo Batista2694eb02008-06-22 19:35:24 +0000409 return
Facundo Batista5596b0c2008-06-22 13:36:20 +0000410
Facundo Batista96f3dc32008-06-22 18:23:55 +0000411 try:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000412 def _create_and_do_getcwd(dirname, current_path_length = 0):
413 try:
414 os.mkdir(dirname)
415 except:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000416 raise unittest.SkipTest, "mkdir cannot create directory sufficiently deep for getcwd test"
Facundo Batista5596b0c2008-06-22 13:36:20 +0000417
418 os.chdir(dirname)
419 try:
420 os.getcwd()
Stefan Krah182ae642010-07-13 19:17:08 +0000421 if current_path_length < 4099:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000422 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
Stefan Krah182ae642010-07-13 19:17:08 +0000423 except OSError as e:
424 expected_errno = errno.ENAMETOOLONG
Trent Nelsonda4277a2012-08-29 09:20:41 -0400425 # The following platforms have quirky getcwd()
426 # behaviour -- see issue 9185 and 15765 for
427 # more information.
428 quirky_platform = (
429 'sunos' in sys.platform or
430 'netbsd' in sys.platform or
431 'openbsd' in sys.platform
432 )
433 if quirky_platform:
434 expected_errno = errno.ERANGE
Stefan Krah182ae642010-07-13 19:17:08 +0000435 self.assertEqual(e.errno, expected_errno)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000436 finally:
437 os.chdir('..')
438 os.rmdir(dirname)
439
440 _create_and_do_getcwd(dirname)
441
442 finally:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000443 os.chdir(curdir)
R. David Murrayb0c828a2009-07-09 18:41:03 +0000444 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000445
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000446 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000447 def test_getgroups(self):
448 with os.popen('id -G') as idg:
449 groups = idg.read().strip()
Charles-François Natali666a5732012-05-02 20:00:37 +0200450 ret = idg.close()
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000451
Charles-François Natalidee8dad2012-05-02 20:48:21 +0200452 if ret != None or not groups:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000453 raise unittest.SkipTest("need working 'id -G'")
454
Ronald Oussorenac72e582010-08-03 07:31:12 +0000455 # 'id -G' and 'os.getgroups()' should return the same
456 # groups, ignoring order and duplicates.
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000457 # #10822 - it is implementation defined whether posix.getgroups()
458 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussoren5719c2f2010-07-24 14:21:29 +0000459 self.assertEqual(
Ronald Oussorenac72e582010-08-03 07:31:12 +0000460 set([int(x) for x in groups.split()]),
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000461 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000462
463class PosixGroupsTester(unittest.TestCase):
464
465 def setUp(self):
466 if posix.getuid() != 0:
467 raise unittest.SkipTest("not enough privileges")
468 if not hasattr(posix, 'getgroups'):
469 raise unittest.SkipTest("need posix.getgroups")
470 if sys.platform == 'darwin':
471 raise unittest.SkipTest("getgroups(2) is broken on OSX")
472 self.saved_groups = posix.getgroups()
473
474 def tearDown(self):
475 if hasattr(posix, 'setgroups'):
476 posix.setgroups(self.saved_groups)
477 elif hasattr(posix, 'initgroups'):
478 name = pwd.getpwuid(posix.getuid()).pw_name
479 posix.initgroups(name, self.saved_groups[0])
480
481 @unittest.skipUnless(hasattr(posix, 'initgroups'),
482 "test needs posix.initgroups()")
483 def test_initgroups(self):
484 # find missing group
485
Antoine Pitroudd806ce2010-09-04 17:34:12 +0000486 g = max(self.saved_groups) + 1
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000487 name = pwd.getpwuid(posix.getuid()).pw_name
488 posix.initgroups(name, g)
489 self.assertIn(g, posix.getgroups())
490
491 @unittest.skipUnless(hasattr(posix, 'setgroups'),
492 "test needs posix.setgroups()")
493 def test_setgroups(self):
494 for groups in [[0], range(16)]:
495 posix.setgroups(groups)
496 self.assertListEqual(groups, posix.getgroups())
497
Facundo Batista5596b0c2008-06-22 13:36:20 +0000498
Neal Norwitze241ce82003-02-17 18:17:05 +0000499def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000500 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000501
502if __name__ == '__main__':
503 test_main()