blob: 09f04ec348412f630237fd194f261ac4df0a796a [file] [log] [blame]
Neal Norwitze241ce82003-02-17 18:17:05 +00001"Test posix functions"
2
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003from test import support
R. David Murrayeb3615d2009-04-22 02:24:39 +00004
5# Skip these tests if there is no posix module.
6posix = support.import_module('posix')
Neal Norwitze241ce82003-02-17 18:17:05 +00007
Antoine Pitroub7572f02009-12-02 20:46:48 +00008import errno
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00009import sys
Neal Norwitze241ce82003-02-17 18:17:05 +000010import time
11import os
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000012import pwd
Benjamin Petersondcf97b92008-07-02 17:30:14 +000013import shutil
Benjamin Peterson052a02b2010-08-17 01:27:09 +000014import stat
Ned Deilyba2eab22011-07-26 13:53:55 -070015import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000016import unittest
17import warnings
R. David Murraya21e4ca2009-03-31 23:16:50 +000018
Ned Deilyba2eab22011-07-26 13:53:55 -070019_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
20 support.TESTFN + '-dummy-symlink')
Neal Norwitze241ce82003-02-17 18:17:05 +000021
22class PosixTester(unittest.TestCase):
23
24 def setUp(self):
25 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000026 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000027 fp.close()
Ned Deily3eb67d52011-06-28 00:00:28 -070028 self.teardown_files = [ support.TESTFN ]
Brett Cannonc8d502e2010-03-20 21:53:28 +000029 self._warnings_manager = support.check_warnings()
30 self._warnings_manager.__enter__()
31 warnings.filterwarnings('ignore', '.* potential security risk .*',
32 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000033
34 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070035 for teardown_file in self.teardown_files:
36 support.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000037 self._warnings_manager.__exit__(None, None, None)
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)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000042 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000043 "times", "getloadavg",
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
Neal Norwitze241ce82003-02-17 18:17:05 +000048 for name in NO_ARG_FUNCTIONS:
49 posix_func = getattr(posix, name, None)
50 if posix_func is not None:
51 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000052 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000053
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000054 if hasattr(posix, 'getresuid'):
55 def test_getresuid(self):
56 user_ids = posix.getresuid()
57 self.assertEqual(len(user_ids), 3)
58 for val in user_ids:
59 self.assertGreaterEqual(val, 0)
60
61 if hasattr(posix, 'getresgid'):
62 def test_getresgid(self):
63 group_ids = posix.getresgid()
64 self.assertEqual(len(group_ids), 3)
65 for val in group_ids:
66 self.assertGreaterEqual(val, 0)
67
68 if hasattr(posix, 'setresuid'):
69 def test_setresuid(self):
70 current_user_ids = posix.getresuid()
71 self.assertIsNone(posix.setresuid(*current_user_ids))
72 # -1 means don't change that value.
73 self.assertIsNone(posix.setresuid(-1, -1, -1))
74
75 def test_setresuid_exception(self):
76 # Don't do this test if someone is silly enough to run us as root.
77 current_user_ids = posix.getresuid()
78 if 0 not in current_user_ids:
79 new_user_ids = (current_user_ids[0]+1, -1, -1)
80 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
81
82 if hasattr(posix, 'setresgid'):
83 def test_setresgid(self):
84 current_group_ids = posix.getresgid()
85 self.assertIsNone(posix.setresgid(*current_group_ids))
86 # -1 means don't change that value.
87 self.assertIsNone(posix.setresgid(-1, -1, -1))
88
89 def test_setresgid_exception(self):
90 # Don't do this test if someone is silly enough to run us as root.
91 current_group_ids = posix.getresgid()
92 if 0 not in current_group_ids:
93 new_group_ids = (current_group_ids[0]+1, -1, -1)
94 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
95
Antoine Pitroub7572f02009-12-02 20:46:48 +000096 @unittest.skipUnless(hasattr(posix, 'initgroups'),
97 "test needs os.initgroups()")
98 def test_initgroups(self):
99 # It takes a string and an integer; check that it raises a TypeError
100 # for other argument lists.
101 self.assertRaises(TypeError, posix.initgroups)
102 self.assertRaises(TypeError, posix.initgroups, None)
103 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
104 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
105
106 # If a non-privileged user invokes it, it should fail with OSError
107 # EPERM.
108 if os.getuid() != 0:
109 name = pwd.getpwuid(posix.getuid()).pw_name
110 try:
111 posix.initgroups(name, 13)
112 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000113 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000114 else:
115 self.fail("Expected OSError to be raised by initgroups")
116
Neal Norwitze241ce82003-02-17 18:17:05 +0000117 def test_statvfs(self):
118 if hasattr(posix, 'statvfs'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000119 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000120
121 def test_fstatvfs(self):
122 if hasattr(posix, 'fstatvfs'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000123 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000124 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000125 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000126 finally:
127 fp.close()
128
129 def test_ftruncate(self):
130 if hasattr(posix, 'ftruncate'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000131 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000132 try:
133 # we need to have some data to truncate
134 fp.write('test')
135 fp.flush()
136 posix.ftruncate(fp.fileno(), 0)
137 finally:
138 fp.close()
139
140 def test_dup(self):
141 if hasattr(posix, 'dup'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000142 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000143 try:
144 fd = posix.dup(fp.fileno())
Ezio Melottie9615932010-01-24 19:26:24 +0000145 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000146 os.close(fd)
147 finally:
148 fp.close()
149
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000150 def test_confstr(self):
151 if hasattr(posix, 'confstr'):
152 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
153 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
154
Neal Norwitze241ce82003-02-17 18:17:05 +0000155 def test_dup2(self):
156 if hasattr(posix, 'dup2'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000157 fp1 = open(support.TESTFN)
158 fp2 = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000159 try:
160 posix.dup2(fp1.fileno(), fp2.fileno())
161 finally:
162 fp1.close()
163 fp2.close()
164
Skip Montanaro98470002005-06-17 01:14:49 +0000165 def test_osexlock(self):
166 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000167 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000168 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000169 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000170 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
171 os.close(fd)
172
173 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000174 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000175 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000176 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000177 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
178 os.close(fd)
179
180 def test_osshlock(self):
181 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000182 fd1 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000183 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000184 fd2 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000185 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
186 os.close(fd2)
187 os.close(fd1)
188
189 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000190 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000191 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000192 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000193 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
194 os.close(fd)
195
Neal Norwitze241ce82003-02-17 18:17:05 +0000196 def test_fstat(self):
197 if hasattr(posix, 'fstat'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000198 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000199 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000200 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000201 finally:
202 fp.close()
203
204 def test_stat(self):
205 if hasattr(posix, 'stat'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000206 self.assertTrue(posix.stat(support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000207
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000208 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
209 def test_mkfifo(self):
210 support.unlink(support.TESTFN)
211 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
212 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
213
214 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
215 "don't have mknod()/S_IFIFO")
216 def test_mknod(self):
217 # Test using mknod() to create a FIFO (the only use specified
218 # by POSIX).
219 support.unlink(support.TESTFN)
220 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
221 try:
222 posix.mknod(support.TESTFN, mode, 0)
223 except OSError as e:
224 # Some old systems don't allow unprivileged users to use
225 # mknod(), or only support creating device nodes.
226 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
227 else:
228 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
229
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000230 def _test_all_chown_common(self, chown_func, first_param):
231 """Common code for chown, fchown and lchown tests."""
232 if os.getuid() == 0:
233 try:
234 # Many linux distros have a nfsnobody user as MAX_UID-2
235 # that makes a good test case for signedness issues.
236 # http://bugs.python.org/issue1747858
237 # This part of the test only runs when run as root.
238 # Only scary people run their tests as root.
239 ent = pwd.getpwnam('nfsnobody')
240 chown_func(first_param, ent.pw_uid, ent.pw_gid)
241 except KeyError:
242 pass
243 else:
244 # non-root cannot chown to root, raises OSError
245 self.assertRaises(OSError, chown_func,
246 first_param, 0, 0)
247 # test a successful chown call
248 chown_func(first_param, os.getuid(), os.getgid())
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000249
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000250 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
251 def test_chown(self):
252 # raise an OSError if the file does not exist
253 os.unlink(support.TESTFN)
254 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000255
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000256 # re-create the file
257 open(support.TESTFN, 'w').close()
258 self._test_all_chown_common(posix.chown, support.TESTFN)
259
260 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
261 def test_fchown(self):
262 os.unlink(support.TESTFN)
263
264 # re-create the file
265 test_file = open(support.TESTFN, 'w')
266 try:
267 fd = test_file.fileno()
268 self._test_all_chown_common(posix.fchown, fd)
269 finally:
270 test_file.close()
271
272 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
273 def test_lchown(self):
274 os.unlink(support.TESTFN)
275 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700276 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000277 self._test_all_chown_common(posix.lchown, support.TESTFN)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000278
Neal Norwitze241ce82003-02-17 18:17:05 +0000279 def test_chdir(self):
280 if hasattr(posix, 'chdir'):
281 posix.chdir(os.curdir)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000282 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000283
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000284 def test_listdir(self):
285 if hasattr(posix, 'listdir'):
286 self.assertTrue(support.TESTFN in posix.listdir(os.curdir))
287
288 def test_listdir_default(self):
289 # When listdir is called without argument, it's the same as listdir(os.curdir)
290 if hasattr(posix, 'listdir'):
291 self.assertTrue(support.TESTFN in posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000292
293 def test_access(self):
294 if hasattr(posix, 'access'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000295 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000296
297 def test_umask(self):
298 if hasattr(posix, 'umask'):
299 old_mask = posix.umask(0)
Ezio Melottie9615932010-01-24 19:26:24 +0000300 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000301 posix.umask(old_mask)
302
303 def test_strerror(self):
304 if hasattr(posix, 'strerror'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000305 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000306
307 def test_pipe(self):
308 if hasattr(posix, 'pipe'):
309 reader, writer = posix.pipe()
310 os.close(reader)
311 os.close(writer)
312
Neal Norwitze241ce82003-02-17 18:17:05 +0000313 def test_utime(self):
314 if hasattr(posix, 'utime'):
315 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000316 posix.utime(support.TESTFN, None)
317 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
318 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
319 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
320 posix.utime(support.TESTFN, (int(now), int(now)))
321 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000322
Ned Deily3eb67d52011-06-28 00:00:28 -0700323 def _test_chflags_regular_file(self, chflags_func, target_file):
324 st = os.stat(target_file)
325 self.assertTrue(hasattr(st, 'st_flags'))
326 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
327 try:
328 new_st = os.stat(target_file)
329 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
330 try:
331 fd = open(target_file, 'w+')
332 except IOError as e:
333 self.assertEqual(e.errno, errno.EPERM)
334 finally:
335 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000336
Ned Deily3eb67d52011-06-28 00:00:28 -0700337 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
338 def test_chflags(self):
339 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
340
341 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
342 def test_lchflags_regular_file(self):
343 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
344
345 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
346 def test_lchflags_symlink(self):
347 testfn_st = os.stat(support.TESTFN)
348
349 self.assertTrue(hasattr(testfn_st, 'st_flags'))
350
351 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
352 self.teardown_files.append(_DUMMY_SYMLINK)
353 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
354
355 posix.lchflags(_DUMMY_SYMLINK,
356 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
357 try:
358 new_testfn_st = os.stat(support.TESTFN)
359 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
360
361 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
362 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
363 new_dummy_symlink_st.st_flags)
364 finally:
365 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000366
Guido van Rossum98297ee2007-11-06 21:34:58 +0000367 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000368 if os.name == "nt":
369 item_type = str
370 else:
371 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000372 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000373 self.assertEqual(type(k), item_type)
374 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000375
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000376 def test_getcwd_long_pathnames(self):
377 if hasattr(posix, 'getcwd'):
378 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
379 curdir = os.getcwd()
380 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
381
382 try:
383 os.mkdir(base_path)
384 os.chdir(base_path)
385 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000386# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000387# because the test results in Error in that case.
388# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000389# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000390 return
391
392 def _create_and_do_getcwd(dirname, current_path_length = 0):
393 try:
394 os.mkdir(dirname)
395 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000396 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000397
398 os.chdir(dirname)
399 try:
400 os.getcwd()
401 if current_path_length < 1027:
402 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
403 finally:
404 os.chdir('..')
405 os.rmdir(dirname)
406
407 _create_and_do_getcwd(dirname)
408
409 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000410 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000411 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000412
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000413 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000414 def test_getgroups(self):
415 with os.popen('id -G') as idg:
416 groups = idg.read().strip()
417
418 if not groups:
419 raise unittest.SkipTest("need working 'id -G'")
420
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000421 # 'id -G' and 'os.getgroups()' should return the same
422 # groups, ignoring order and duplicates.
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000423 # #10822 - it is implementation defined whether posix.getgroups()
424 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussorencb615e62010-07-24 14:15:19 +0000425 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000426 set([int(x) for x in groups.split()]),
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000427 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000428
429class PosixGroupsTester(unittest.TestCase):
430
431 def setUp(self):
432 if posix.getuid() != 0:
433 raise unittest.SkipTest("not enough privileges")
434 if not hasattr(posix, 'getgroups'):
435 raise unittest.SkipTest("need posix.getgroups")
436 if sys.platform == 'darwin':
437 raise unittest.SkipTest("getgroups(2) is broken on OSX")
438 self.saved_groups = posix.getgroups()
439
440 def tearDown(self):
441 if hasattr(posix, 'setgroups'):
442 posix.setgroups(self.saved_groups)
443 elif hasattr(posix, 'initgroups'):
444 name = pwd.getpwuid(posix.getuid()).pw_name
445 posix.initgroups(name, self.saved_groups[0])
446
447 @unittest.skipUnless(hasattr(posix, 'initgroups'),
448 "test needs posix.initgroups()")
449 def test_initgroups(self):
450 # find missing group
451
Antoine Pitroue5a91012010-09-04 17:32:06 +0000452 g = max(self.saved_groups) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000453 name = pwd.getpwuid(posix.getuid()).pw_name
454 posix.initgroups(name, g)
455 self.assertIn(g, posix.getgroups())
456
457 @unittest.skipUnless(hasattr(posix, 'setgroups'),
458 "test needs posix.setgroups()")
459 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +0000460 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000461 posix.setgroups(groups)
462 self.assertListEqual(groups, posix.getgroups())
463
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000464
Neal Norwitze241ce82003-02-17 18:17:05 +0000465def test_main():
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000466 support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000467
468if __name__ == '__main__':
469 test_main()