blob: 76126342085f191a0c3775812766f0428fe1f25a [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
Charles-François Nataliab2d58e2012-04-17 19:48:35 +020012import platform
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000013import pwd
Benjamin Petersondcf97b92008-07-02 17:30:14 +000014import shutil
Benjamin Peterson052a02b2010-08-17 01:27:09 +000015import stat
Ned Deilyba2eab22011-07-26 13:53:55 -070016import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000017import unittest
18import warnings
R. David Murraya21e4ca2009-03-31 23:16:50 +000019
Ned Deilyba2eab22011-07-26 13:53:55 -070020_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
21 support.TESTFN + '-dummy-symlink')
Neal Norwitze241ce82003-02-17 18:17:05 +000022
23class PosixTester(unittest.TestCase):
24
25 def setUp(self):
26 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000027 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000028 fp.close()
Ned Deily3eb67d52011-06-28 00:00:28 -070029 self.teardown_files = [ support.TESTFN ]
Brett Cannonc8d502e2010-03-20 21:53:28 +000030 self._warnings_manager = support.check_warnings()
31 self._warnings_manager.__enter__()
32 warnings.filterwarnings('ignore', '.* potential security risk .*',
33 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000034
35 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070036 for teardown_file in self.teardown_files:
37 support.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000038 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000039
40 def testNoArgFunctions(self):
41 # test posix functions which take no arguments and have
42 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000043 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000044 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000045 "getegid", "geteuid", "getgid", "getgroups",
46 "getpid", "getpgrp", "getppid", "getuid",
47 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000048
Neal Norwitze241ce82003-02-17 18:17:05 +000049 for name in NO_ARG_FUNCTIONS:
50 posix_func = getattr(posix, name, None)
51 if posix_func is not None:
52 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000053 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000054
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000055 if hasattr(posix, 'getresuid'):
56 def test_getresuid(self):
57 user_ids = posix.getresuid()
58 self.assertEqual(len(user_ids), 3)
59 for val in user_ids:
60 self.assertGreaterEqual(val, 0)
61
62 if hasattr(posix, 'getresgid'):
63 def test_getresgid(self):
64 group_ids = posix.getresgid()
65 self.assertEqual(len(group_ids), 3)
66 for val in group_ids:
67 self.assertGreaterEqual(val, 0)
68
69 if hasattr(posix, 'setresuid'):
70 def test_setresuid(self):
71 current_user_ids = posix.getresuid()
72 self.assertIsNone(posix.setresuid(*current_user_ids))
73 # -1 means don't change that value.
74 self.assertIsNone(posix.setresuid(-1, -1, -1))
75
76 def test_setresuid_exception(self):
77 # Don't do this test if someone is silly enough to run us as root.
78 current_user_ids = posix.getresuid()
79 if 0 not in current_user_ids:
80 new_user_ids = (current_user_ids[0]+1, -1, -1)
81 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
82
83 if hasattr(posix, 'setresgid'):
84 def test_setresgid(self):
85 current_group_ids = posix.getresgid()
86 self.assertIsNone(posix.setresgid(*current_group_ids))
87 # -1 means don't change that value.
88 self.assertIsNone(posix.setresgid(-1, -1, -1))
89
90 def test_setresgid_exception(self):
91 # Don't do this test if someone is silly enough to run us as root.
92 current_group_ids = posix.getresgid()
93 if 0 not in current_group_ids:
94 new_group_ids = (current_group_ids[0]+1, -1, -1)
95 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
96
Antoine Pitroub7572f02009-12-02 20:46:48 +000097 @unittest.skipUnless(hasattr(posix, 'initgroups'),
98 "test needs os.initgroups()")
99 def test_initgroups(self):
100 # It takes a string and an integer; check that it raises a TypeError
101 # for other argument lists.
102 self.assertRaises(TypeError, posix.initgroups)
103 self.assertRaises(TypeError, posix.initgroups, None)
104 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
105 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
106
107 # If a non-privileged user invokes it, it should fail with OSError
108 # EPERM.
109 if os.getuid() != 0:
110 name = pwd.getpwuid(posix.getuid()).pw_name
111 try:
112 posix.initgroups(name, 13)
113 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000114 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000115 else:
116 self.fail("Expected OSError to be raised by initgroups")
117
Neal Norwitze241ce82003-02-17 18:17:05 +0000118 def test_statvfs(self):
119 if hasattr(posix, 'statvfs'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000120 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000121
122 def test_fstatvfs(self):
123 if hasattr(posix, 'fstatvfs'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000124 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000125 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000126 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000127 finally:
128 fp.close()
129
130 def test_ftruncate(self):
131 if hasattr(posix, 'ftruncate'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000132 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000133 try:
134 # we need to have some data to truncate
135 fp.write('test')
136 fp.flush()
137 posix.ftruncate(fp.fileno(), 0)
138 finally:
139 fp.close()
140
141 def test_dup(self):
142 if hasattr(posix, 'dup'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000143 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000144 try:
145 fd = posix.dup(fp.fileno())
Ezio Melottie9615932010-01-24 19:26:24 +0000146 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000147 os.close(fd)
148 finally:
149 fp.close()
150
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000151 def test_confstr(self):
152 if hasattr(posix, 'confstr'):
153 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
154 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
155
Neal Norwitze241ce82003-02-17 18:17:05 +0000156 def test_dup2(self):
157 if hasattr(posix, 'dup2'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000158 fp1 = open(support.TESTFN)
159 fp2 = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000160 try:
161 posix.dup2(fp1.fileno(), fp2.fileno())
162 finally:
163 fp1.close()
164 fp2.close()
165
Skip Montanaro98470002005-06-17 01:14:49 +0000166 def test_osexlock(self):
167 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000168 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000169 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000170 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000171 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
172 os.close(fd)
173
174 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000175 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000176 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000177 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000178 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
179 os.close(fd)
180
181 def test_osshlock(self):
182 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000183 fd1 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000184 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000185 fd2 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000186 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
187 os.close(fd2)
188 os.close(fd1)
189
190 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000191 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000192 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000193 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000194 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
195 os.close(fd)
196
Neal Norwitze241ce82003-02-17 18:17:05 +0000197 def test_fstat(self):
198 if hasattr(posix, 'fstat'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000199 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000200 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000201 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000202 finally:
203 fp.close()
204
205 def test_stat(self):
206 if hasattr(posix, 'stat'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000207 self.assertTrue(posix.stat(support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000208
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000209 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
210 def test_mkfifo(self):
211 support.unlink(support.TESTFN)
212 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
213 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
214
215 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
216 "don't have mknod()/S_IFIFO")
217 def test_mknod(self):
218 # Test using mknod() to create a FIFO (the only use specified
219 # by POSIX).
220 support.unlink(support.TESTFN)
221 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
222 try:
223 posix.mknod(support.TESTFN, mode, 0)
224 except OSError as e:
225 # Some old systems don't allow unprivileged users to use
226 # mknod(), or only support creating device nodes.
227 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
228 else:
229 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
230
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000231 def _test_all_chown_common(self, chown_func, first_param):
232 """Common code for chown, fchown and lchown tests."""
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200233 # test a successful chown call
234 chown_func(first_param, os.getuid(), os.getgid())
235
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000236 if os.getuid() == 0:
237 try:
238 # Many linux distros have a nfsnobody user as MAX_UID-2
239 # that makes a good test case for signedness issues.
240 # http://bugs.python.org/issue1747858
241 # This part of the test only runs when run as root.
242 # Only scary people run their tests as root.
243 ent = pwd.getpwnam('nfsnobody')
244 chown_func(first_param, ent.pw_uid, ent.pw_gid)
245 except KeyError:
246 pass
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200247 elif platform.system() in ('HP-UX', 'SunOS'):
248 # HP-UX and Solaris can allow a non-root user to chown() to root
249 # (issue #5113)
250 raise unittest.SkipTest("Skipping because of non-standard chown() "
251 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000252 else:
253 # non-root cannot chown to root, raises OSError
254 self.assertRaises(OSError, chown_func,
255 first_param, 0, 0)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000256
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000257 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
258 def test_chown(self):
259 # raise an OSError if the file does not exist
260 os.unlink(support.TESTFN)
261 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000262
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000263 # re-create the file
264 open(support.TESTFN, 'w').close()
265 self._test_all_chown_common(posix.chown, support.TESTFN)
266
267 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
268 def test_fchown(self):
269 os.unlink(support.TESTFN)
270
271 # re-create the file
272 test_file = open(support.TESTFN, 'w')
273 try:
274 fd = test_file.fileno()
275 self._test_all_chown_common(posix.fchown, fd)
276 finally:
277 test_file.close()
278
279 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
280 def test_lchown(self):
281 os.unlink(support.TESTFN)
282 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700283 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000284 self._test_all_chown_common(posix.lchown, support.TESTFN)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000285
Neal Norwitze241ce82003-02-17 18:17:05 +0000286 def test_chdir(self):
287 if hasattr(posix, 'chdir'):
288 posix.chdir(os.curdir)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000289 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000290
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000291 def test_listdir(self):
292 if hasattr(posix, 'listdir'):
293 self.assertTrue(support.TESTFN in posix.listdir(os.curdir))
294
295 def test_listdir_default(self):
296 # When listdir is called without argument, it's the same as listdir(os.curdir)
297 if hasattr(posix, 'listdir'):
298 self.assertTrue(support.TESTFN in posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000299
300 def test_access(self):
301 if hasattr(posix, 'access'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000302 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000303
304 def test_umask(self):
305 if hasattr(posix, 'umask'):
306 old_mask = posix.umask(0)
Ezio Melottie9615932010-01-24 19:26:24 +0000307 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000308 posix.umask(old_mask)
309
310 def test_strerror(self):
311 if hasattr(posix, 'strerror'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000312 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000313
314 def test_pipe(self):
315 if hasattr(posix, 'pipe'):
316 reader, writer = posix.pipe()
317 os.close(reader)
318 os.close(writer)
319
Neal Norwitze241ce82003-02-17 18:17:05 +0000320 def test_utime(self):
321 if hasattr(posix, 'utime'):
322 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000323 posix.utime(support.TESTFN, None)
324 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
325 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
326 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
327 posix.utime(support.TESTFN, (int(now), int(now)))
328 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000329
Ned Deily3eb67d52011-06-28 00:00:28 -0700330 def _test_chflags_regular_file(self, chflags_func, target_file):
331 st = os.stat(target_file)
332 self.assertTrue(hasattr(st, 'st_flags'))
333 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
334 try:
335 new_st = os.stat(target_file)
336 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
337 try:
338 fd = open(target_file, 'w+')
339 except IOError as e:
340 self.assertEqual(e.errno, errno.EPERM)
341 finally:
342 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000343
Ned Deily3eb67d52011-06-28 00:00:28 -0700344 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
345 def test_chflags(self):
346 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
347
348 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
349 def test_lchflags_regular_file(self):
350 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
351
352 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
353 def test_lchflags_symlink(self):
354 testfn_st = os.stat(support.TESTFN)
355
356 self.assertTrue(hasattr(testfn_st, 'st_flags'))
357
358 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
359 self.teardown_files.append(_DUMMY_SYMLINK)
360 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
361
362 posix.lchflags(_DUMMY_SYMLINK,
363 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
364 try:
365 new_testfn_st = os.stat(support.TESTFN)
366 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
367
368 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
369 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
370 new_dummy_symlink_st.st_flags)
371 finally:
372 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000373
Guido van Rossum98297ee2007-11-06 21:34:58 +0000374 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000375 if os.name == "nt":
376 item_type = str
377 else:
378 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000379 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000380 self.assertEqual(type(k), item_type)
381 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000382
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000383 def test_getcwd_long_pathnames(self):
384 if hasattr(posix, 'getcwd'):
385 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
386 curdir = os.getcwd()
387 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
388
389 try:
390 os.mkdir(base_path)
391 os.chdir(base_path)
392 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000393# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000394# because the test results in Error in that case.
395# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000396# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000397 return
398
399 def _create_and_do_getcwd(dirname, current_path_length = 0):
400 try:
401 os.mkdir(dirname)
402 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000403 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000404
405 os.chdir(dirname)
406 try:
407 os.getcwd()
408 if current_path_length < 1027:
409 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
410 finally:
411 os.chdir('..')
412 os.rmdir(dirname)
413
414 _create_and_do_getcwd(dirname)
415
416 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000417 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000418 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000419
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000420 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000421 def test_getgroups(self):
422 with os.popen('id -G') as idg:
423 groups = idg.read().strip()
424
425 if not groups:
426 raise unittest.SkipTest("need working 'id -G'")
427
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000428 # 'id -G' and 'os.getgroups()' should return the same
429 # groups, ignoring order and duplicates.
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000430 # #10822 - it is implementation defined whether posix.getgroups()
431 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussorencb615e62010-07-24 14:15:19 +0000432 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000433 set([int(x) for x in groups.split()]),
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000434 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000435
436class PosixGroupsTester(unittest.TestCase):
437
438 def setUp(self):
439 if posix.getuid() != 0:
440 raise unittest.SkipTest("not enough privileges")
441 if not hasattr(posix, 'getgroups'):
442 raise unittest.SkipTest("need posix.getgroups")
443 if sys.platform == 'darwin':
444 raise unittest.SkipTest("getgroups(2) is broken on OSX")
445 self.saved_groups = posix.getgroups()
446
447 def tearDown(self):
448 if hasattr(posix, 'setgroups'):
449 posix.setgroups(self.saved_groups)
450 elif hasattr(posix, 'initgroups'):
451 name = pwd.getpwuid(posix.getuid()).pw_name
452 posix.initgroups(name, self.saved_groups[0])
453
454 @unittest.skipUnless(hasattr(posix, 'initgroups'),
455 "test needs posix.initgroups()")
456 def test_initgroups(self):
457 # find missing group
458
Antoine Pitroue5a91012010-09-04 17:32:06 +0000459 g = max(self.saved_groups) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000460 name = pwd.getpwuid(posix.getuid()).pw_name
461 posix.initgroups(name, g)
462 self.assertIn(g, posix.getgroups())
463
464 @unittest.skipUnless(hasattr(posix, 'setgroups'),
465 "test needs posix.setgroups()")
466 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +0000467 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000468 posix.setgroups(groups)
469 self.assertListEqual(groups, posix.getgroups())
470
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000471
Neal Norwitze241ce82003-02-17 18:17:05 +0000472def test_main():
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000473 support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000474
475if __name__ == '__main__':
476 test_main()