blob: a6d47af3193402401fde675b3af378a9a2ed3c0c [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
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020056 @unittest.skipUnless(hasattr(posix, 'getresuid'),
57 'test needs posix.getresuid()')
58 def test_getresuid(self):
59 user_ids = posix.getresuid()
60 self.assertEqual(len(user_ids), 3)
61 for val in user_ids:
62 self.assertGreaterEqual(val, 0)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000063
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020064 @unittest.skipUnless(hasattr(posix, 'getresgid'),
65 'test needs posix.getresgid()')
66 def test_getresgid(self):
67 group_ids = posix.getresgid()
68 self.assertEqual(len(group_ids), 3)
69 for val in group_ids:
70 self.assertGreaterEqual(val, 0)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000071
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020072 @unittest.skipUnless(hasattr(posix, 'setresuid'),
73 'test needs posix.setresuid()')
74 def test_setresuid(self):
75 current_user_ids = posix.getresuid()
76 self.assertIsNone(posix.setresuid(*current_user_ids))
77 # -1 means don't change that value.
78 self.assertIsNone(posix.setresuid(-1, -1, -1))
Martin v. Löwis50ea4562009-11-27 13:56:01 +000079
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020080 @unittest.skipUnless(hasattr(posix, 'setresuid'),
81 'test needs posix.setresuid()')
82 def test_setresuid_exception(self):
83 # Don't do this test if someone is silly enough to run us as root.
84 current_user_ids = posix.getresuid()
85 if 0 not in current_user_ids:
86 new_user_ids = (current_user_ids[0]+1, -1, -1)
87 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000088
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020089 @unittest.skipUnless(hasattr(posix, 'setresgid'),
90 'test needs posix.setresgid()')
91 def test_setresgid(self):
92 current_group_ids = posix.getresgid()
93 self.assertIsNone(posix.setresgid(*current_group_ids))
94 # -1 means don't change that value.
95 self.assertIsNone(posix.setresgid(-1, -1, -1))
Martin v. Löwis50ea4562009-11-27 13:56:01 +000096
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020097 @unittest.skipUnless(hasattr(posix, 'setresgid'),
98 'test needs posix.setresgid()')
99 def test_setresgid_exception(self):
100 # Don't do this test if someone is silly enough to run us as root.
101 current_group_ids = posix.getresgid()
102 if 0 not in current_group_ids:
103 new_group_ids = (current_group_ids[0]+1, -1, -1)
104 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
Martin v. Löwis50ea4562009-11-27 13:56:01 +0000105
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000106 @unittest.skipUnless(hasattr(posix, 'initgroups'),
107 "test needs os.initgroups()")
108 def test_initgroups(self):
109 # It takes a string and an integer; check that it raises a TypeError
110 # for other argument lists.
111 self.assertRaises(TypeError, posix.initgroups)
112 self.assertRaises(TypeError, posix.initgroups, None)
113 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
114 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
115
116 # If a non-privileged user invokes it, it should fail with OSError
117 # EPERM.
118 if os.getuid() != 0:
Charles-François Natali666a5732012-05-02 20:00:37 +0200119 try:
120 name = pwd.getpwuid(posix.getuid()).pw_name
121 except KeyError:
122 # the current UID may not have a pwd entry
123 raise unittest.SkipTest("need a pwd entry")
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000124 try:
125 posix.initgroups(name, 13)
126 except OSError as e:
Ezio Melotti2623a372010-11-21 13:34:58 +0000127 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000128 else:
129 self.fail("Expected OSError to be raised by initgroups")
130
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200131 @unittest.skipUnless(hasattr(posix, 'statvfs'),
132 'test needs posix.statvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000133 def test_statvfs(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200134 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000135
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200136 @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
137 'test needs posix.fstatvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000138 def test_fstatvfs(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200139 fp = open(test_support.TESTFN)
140 try:
141 self.assertTrue(posix.fstatvfs(fp.fileno()))
142 finally:
143 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000144
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200145 @unittest.skipUnless(hasattr(posix, 'ftruncate'),
146 'test needs posix.ftruncate()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000147 def test_ftruncate(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200148 fp = open(test_support.TESTFN, 'w+')
149 try:
150 # we need to have some data to truncate
151 fp.write('test')
152 fp.flush()
153 posix.ftruncate(fp.fileno(), 0)
154 finally:
155 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000156
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200157 @unittest.skipUnless(hasattr(posix, 'dup'),
158 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000159 def test_dup(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200160 fp = open(test_support.TESTFN)
161 try:
162 fd = posix.dup(fp.fileno())
163 self.assertIsInstance(fd, int)
164 os.close(fd)
165 finally:
166 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000167
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200168 @unittest.skipUnless(hasattr(posix, 'confstr'),
169 'test needs posix.confstr()')
Skip Montanaro94785ef2006-04-20 01:29:48 +0000170 def test_confstr(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200171 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
172 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Skip Montanaro94785ef2006-04-20 01:29:48 +0000173
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200174 @unittest.skipUnless(hasattr(posix, 'dup2'),
175 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000176 def test_dup2(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200177 fp1 = open(test_support.TESTFN)
178 fp2 = open(test_support.TESTFN)
179 try:
180 posix.dup2(fp1.fileno(), fp2.fileno())
181 finally:
182 fp1.close()
183 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000184
185 def fdopen_helper(self, *args):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000186 fd = os.open(test_support.TESTFN, os.O_RDONLY)
Neal Norwitze241ce82003-02-17 18:17:05 +0000187 fp2 = posix.fdopen(fd, *args)
188 fp2.close()
189
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200190 @unittest.skipUnless(hasattr(posix, 'fdopen'),
191 'test needs posix.fdopen()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000192 def test_fdopen(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200193 self.fdopen_helper()
194 self.fdopen_helper('r')
195 self.fdopen_helper('r', 100)
Neal Norwitze241ce82003-02-17 18:17:05 +0000196
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200197 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
198 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000199 def test_osexlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200200 fd = os.open(test_support.TESTFN,
201 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
202 self.assertRaises(OSError, os.open, test_support.TESTFN,
203 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
204 os.close(fd)
205
206 if hasattr(posix, "O_SHLOCK"):
Skip Montanaro98470002005-06-17 01:14:49 +0000207 fd = os.open(test_support.TESTFN,
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200208 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Skip Montanaro98470002005-06-17 01:14:49 +0000209 self.assertRaises(OSError, os.open, test_support.TESTFN,
210 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
211 os.close(fd)
212
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200213 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
214 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000215 def test_osshlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200216 fd1 = os.open(test_support.TESTFN,
217 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
218 fd2 = os.open(test_support.TESTFN,
219 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
220 os.close(fd2)
221 os.close(fd1)
222
223 if hasattr(posix, "O_EXLOCK"):
224 fd = os.open(test_support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000225 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200226 self.assertRaises(OSError, os.open, test_support.TESTFN,
227 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
228 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000229
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200230 @unittest.skipUnless(hasattr(posix, 'fstat'),
231 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000232 def test_fstat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200233 fp = open(test_support.TESTFN)
234 try:
235 self.assertTrue(posix.fstat(fp.fileno()))
236 finally:
237 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000238
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200239 @unittest.skipUnless(hasattr(posix, 'stat'),
240 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000241 def test_stat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200242 self.assertTrue(posix.stat(test_support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000243
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200244 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000245 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200246 def check_stat(uid, gid):
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200247 if stat_func is not None:
248 stat = stat_func(first_param)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200249 self.assertEqual(stat.st_uid, uid)
250 self.assertEqual(stat.st_gid, gid)
251 uid = os.getuid()
252 gid = os.getgid()
Charles-François Natalif8387642012-04-17 19:46:06 +0200253 # test a successful chown call
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200254 chown_func(first_param, uid, gid)
255 check_stat(uid, gid)
256 chown_func(first_param, -1, gid)
257 check_stat(uid, gid)
258 chown_func(first_param, uid, -1)
259 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200260
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200261 if uid == 0:
262 # Try an amusingly large uid/gid to make sure we handle
263 # large unsigned values. (chown lets you use any
264 # uid/gid you like, even if they aren't defined.)
265 #
266 # This problem keeps coming up:
267 # http://bugs.python.org/issue1747858
268 # http://bugs.python.org/issue4591
269 # http://bugs.python.org/issue15301
270 # Hopefully the fix in 4591 fixes it for good!
271 #
272 # This part of the test only runs when run as root.
273 # Only scary people run their tests as root.
274
275 big_value = 2**31
276 chown_func(first_param, big_value, big_value)
277 check_stat(big_value, big_value)
278 chown_func(first_param, -1, -1)
279 check_stat(big_value, big_value)
280 chown_func(first_param, uid, gid)
281 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200282 elif platform.system() in ('HP-UX', 'SunOS'):
283 # HP-UX and Solaris can allow a non-root user to chown() to root
284 # (issue #5113)
285 raise unittest.SkipTest("Skipping because of non-standard chown() "
286 "behavior")
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000287 else:
288 # non-root cannot chown to root, raises OSError
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200289 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200290 check_stat(uid, gid)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200291 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200292 check_stat(uid, gid)
Serhiy Storchaka484dee32013-02-21 14:33:45 +0200293 if 0 not in os.getgroups():
Serhiy Storchakafffc4792013-02-20 19:47:31 +0200294 self.assertRaises(OSError, chown_func, first_param, -1, 0)
295 check_stat(uid, gid)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200296 # test illegal types
297 for t in str, float:
298 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
299 check_stat(uid, gid)
300 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
301 check_stat(uid, gid)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000302
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000303 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
304 def test_chown(self):
305 # raise an OSError if the file does not exist
306 os.unlink(test_support.TESTFN)
307 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
308
309 # re-create the file
310 open(test_support.TESTFN, 'w').close()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200311 self._test_all_chown_common(posix.chown, test_support.TESTFN,
312 getattr(posix, 'stat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000313
314 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
315 def test_fchown(self):
316 os.unlink(test_support.TESTFN)
317
318 # re-create the file
319 test_file = open(test_support.TESTFN, 'w')
320 try:
321 fd = test_file.fileno()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200322 self._test_all_chown_common(posix.fchown, fd,
323 getattr(posix, 'fstat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000324 finally:
325 test_file.close()
326
327 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
328 def test_lchown(self):
329 os.unlink(test_support.TESTFN)
330 # create a symlink
Ned Deily43e10542011-06-27 23:41:53 -0700331 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200332 self._test_all_chown_common(posix.lchown, test_support.TESTFN,
333 getattr(posix, 'lstat', None))
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000334
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200335 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000336 def test_chdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200337 posix.chdir(os.curdir)
338 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000339
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200340 @unittest.skipUnless(hasattr(posix, 'lsdir'), 'test needs posix.lsdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000341 def test_lsdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200342 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000343
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200344 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000345 def test_access(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200346 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000347
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200348 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000349 def test_umask(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200350 old_mask = posix.umask(0)
351 self.assertIsInstance(old_mask, int)
352 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000353
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200354 @unittest.skipUnless(hasattr(posix, 'strerror'),
355 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000356 def test_strerror(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200357 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000358
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200359 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000360 def test_pipe(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200361 reader, writer = posix.pipe()
362 os.close(reader)
363 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000364
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200365 @unittest.skipUnless(hasattr(posix, 'tempnam'),
366 'test needs posix.tempnam()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000367 def test_tempnam(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200368 with warnings.catch_warnings():
369 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
370 self.assertTrue(posix.tempnam())
371 self.assertTrue(posix.tempnam(os.curdir))
372 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000373
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200374 @unittest.skipUnless(hasattr(posix, 'tmpfile'),
375 'test needs posix.tmpfile()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000376 def test_tmpfile(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200377 with warnings.catch_warnings():
378 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
379 fp = posix.tmpfile()
380 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000381
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200382 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000383 def test_utime(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200384 now = time.time()
385 posix.utime(test_support.TESTFN, None)
386 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
387 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
388 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
389 posix.utime(test_support.TESTFN, (int(now), int(now)))
390 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000391
Ned Deily43e10542011-06-27 23:41:53 -0700392 def _test_chflags_regular_file(self, chflags_func, target_file):
393 st = os.stat(target_file)
394 self.assertTrue(hasattr(st, 'st_flags'))
Victor Stinner8c7c6972012-12-04 10:07:16 +0100395
396 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
397 try:
398 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
399 except OSError as err:
400 if err.errno != errno.EOPNOTSUPP:
401 raise
402 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
403 self.skipTest(msg)
404
Ned Deily43e10542011-06-27 23:41:53 -0700405 try:
406 new_st = os.stat(target_file)
407 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
408 try:
409 fd = open(target_file, 'w+')
410 except IOError as e:
411 self.assertEqual(e.errno, errno.EPERM)
412 finally:
413 posix.chflags(target_file, st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000414
Ned Deily43e10542011-06-27 23:41:53 -0700415 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
416 def test_chflags(self):
417 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN)
418
419 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
420 def test_lchflags_regular_file(self):
421 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN)
422
423 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
424 def test_lchflags_symlink(self):
425 testfn_st = os.stat(test_support.TESTFN)
426
427 self.assertTrue(hasattr(testfn_st, 'st_flags'))
428
429 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK)
430 self.teardown_files.append(_DUMMY_SYMLINK)
431 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
432
Victor Stinner8c7c6972012-12-04 10:07:16 +0100433 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
434 try:
435 posix.lchflags(_DUMMY_SYMLINK,
436 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
437 except OSError as err:
438 if err.errno != errno.EOPNOTSUPP:
439 raise
440 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
441 self.skipTest(msg)
442
Ned Deily43e10542011-06-27 23:41:53 -0700443 try:
444 new_testfn_st = os.stat(test_support.TESTFN)
445 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
446
447 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
448 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
449 new_dummy_symlink_st.st_flags)
450 finally:
451 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000452
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200453 @unittest.skipUnless(hasattr(posix, 'getcwd'),
454 'test needs posix.getcwd()')
Facundo Batista5596b0c2008-06-22 13:36:20 +0000455 def test_getcwd_long_pathnames(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200456 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
457 curdir = os.getcwd()
458 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000459
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200460 try:
461 os.mkdir(base_path)
462 os.chdir(base_path)
463 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600464 self.skipTest("cannot create directory for testing")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000465
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200466 try:
467 def _create_and_do_getcwd(dirname, current_path_length = 0):
468 try:
469 os.mkdir(dirname)
470 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600471 self.skipTest("mkdir cannot create directory sufficiently "
472 "deep for getcwd test")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000473
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200474 os.chdir(dirname)
475 try:
476 os.getcwd()
477 if current_path_length < 4099:
478 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
479 except OSError as e:
480 expected_errno = errno.ENAMETOOLONG
481 # The following platforms have quirky getcwd()
482 # behaviour -- see issue 9185 and 15765 for
483 # more information.
484 quirky_platform = (
485 'sunos' in sys.platform or
486 'netbsd' in sys.platform or
487 'openbsd' in sys.platform
488 )
489 if quirky_platform:
490 expected_errno = errno.ERANGE
491 self.assertEqual(e.errno, expected_errno)
492 finally:
493 os.chdir('..')
494 os.rmdir(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000495
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200496 _create_and_do_getcwd(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000497
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200498 finally:
499 os.chdir(curdir)
500 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000501
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000502 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000503 def test_getgroups(self):
504 with os.popen('id -G') as idg:
505 groups = idg.read().strip()
Charles-François Natali666a5732012-05-02 20:00:37 +0200506 ret = idg.close()
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000507
Charles-François Natalidee8dad2012-05-02 20:48:21 +0200508 if ret != None or not groups:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000509 raise unittest.SkipTest("need working 'id -G'")
510
Ned Deilycc23cc62013-02-02 15:06:45 -0800511 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
512 if sys.platform == 'darwin':
513 import sysconfig
514 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
515 if float(dt) < 10.6:
516 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
517
Ronald Oussorenac72e582010-08-03 07:31:12 +0000518 # 'id -G' and 'os.getgroups()' should return the same
519 # groups, ignoring order and duplicates.
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000520 # #10822 - it is implementation defined whether posix.getgroups()
521 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussoren5719c2f2010-07-24 14:21:29 +0000522 self.assertEqual(
Ronald Oussorenac72e582010-08-03 07:31:12 +0000523 set([int(x) for x in groups.split()]),
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000524 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000525
526class PosixGroupsTester(unittest.TestCase):
527
528 def setUp(self):
529 if posix.getuid() != 0:
530 raise unittest.SkipTest("not enough privileges")
531 if not hasattr(posix, 'getgroups'):
532 raise unittest.SkipTest("need posix.getgroups")
533 if sys.platform == 'darwin':
534 raise unittest.SkipTest("getgroups(2) is broken on OSX")
535 self.saved_groups = posix.getgroups()
536
537 def tearDown(self):
538 if hasattr(posix, 'setgroups'):
539 posix.setgroups(self.saved_groups)
540 elif hasattr(posix, 'initgroups'):
541 name = pwd.getpwuid(posix.getuid()).pw_name
542 posix.initgroups(name, self.saved_groups[0])
543
544 @unittest.skipUnless(hasattr(posix, 'initgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200545 'test needs posix.initgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000546 def test_initgroups(self):
547 # find missing group
548
Antoine Pitroudd806ce2010-09-04 17:34:12 +0000549 g = max(self.saved_groups) + 1
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000550 name = pwd.getpwuid(posix.getuid()).pw_name
551 posix.initgroups(name, g)
552 self.assertIn(g, posix.getgroups())
553
554 @unittest.skipUnless(hasattr(posix, 'setgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200555 'test needs posix.setgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000556 def test_setgroups(self):
557 for groups in [[0], range(16)]:
558 posix.setgroups(groups)
559 self.assertListEqual(groups, posix.getgroups())
560
Facundo Batista5596b0c2008-06-22 13:36:20 +0000561
Neal Norwitze241ce82003-02-17 18:17:05 +0000562def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000563 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000564
565if __name__ == '__main__':
566 test_main()