blob: a22ebdf7c71c2d566748124fa0843925cf0ad9e3 [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
Neal Norwitze241ce82003-02-17 18:17:05 +000014import unittest
15import warnings
R. David Murraya21e4ca2009-03-31 23:16:50 +000016
Neal Norwitze241ce82003-02-17 18:17:05 +000017
18class PosixTester(unittest.TestCase):
19
20 def setUp(self):
21 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000022 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000023 fp.close()
Brett Cannonc8d502e2010-03-20 21:53:28 +000024 self._warnings_manager = support.check_warnings()
25 self._warnings_manager.__enter__()
26 warnings.filterwarnings('ignore', '.* potential security risk .*',
27 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000028
29 def tearDown(self):
Neal Norwitzc34177c2008-08-25 01:04:16 +000030 support.unlink(support.TESTFN)
Brett Cannonc8d502e2010-03-20 21:53:28 +000031 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000032
33 def testNoArgFunctions(self):
34 # test posix functions which take no arguments and have
35 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000036 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000037 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000038 "getegid", "geteuid", "getgid", "getgroups",
39 "getpid", "getpgrp", "getppid", "getuid",
40 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000041
Neal Norwitze241ce82003-02-17 18:17:05 +000042 for name in NO_ARG_FUNCTIONS:
43 posix_func = getattr(posix, name, None)
44 if posix_func is not None:
45 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000046 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000047
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000048 if hasattr(posix, 'getresuid'):
49 def test_getresuid(self):
50 user_ids = posix.getresuid()
51 self.assertEqual(len(user_ids), 3)
52 for val in user_ids:
53 self.assertGreaterEqual(val, 0)
54
55 if hasattr(posix, 'getresgid'):
56 def test_getresgid(self):
57 group_ids = posix.getresgid()
58 self.assertEqual(len(group_ids), 3)
59 for val in group_ids:
60 self.assertGreaterEqual(val, 0)
61
62 if hasattr(posix, 'setresuid'):
63 def test_setresuid(self):
64 current_user_ids = posix.getresuid()
65 self.assertIsNone(posix.setresuid(*current_user_ids))
66 # -1 means don't change that value.
67 self.assertIsNone(posix.setresuid(-1, -1, -1))
68
69 def test_setresuid_exception(self):
70 # Don't do this test if someone is silly enough to run us as root.
71 current_user_ids = posix.getresuid()
72 if 0 not in current_user_ids:
73 new_user_ids = (current_user_ids[0]+1, -1, -1)
74 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
75
76 if hasattr(posix, 'setresgid'):
77 def test_setresgid(self):
78 current_group_ids = posix.getresgid()
79 self.assertIsNone(posix.setresgid(*current_group_ids))
80 # -1 means don't change that value.
81 self.assertIsNone(posix.setresgid(-1, -1, -1))
82
83 def test_setresgid_exception(self):
84 # Don't do this test if someone is silly enough to run us as root.
85 current_group_ids = posix.getresgid()
86 if 0 not in current_group_ids:
87 new_group_ids = (current_group_ids[0]+1, -1, -1)
88 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
89
Antoine Pitroub7572f02009-12-02 20:46:48 +000090 @unittest.skipUnless(hasattr(posix, 'initgroups'),
91 "test needs os.initgroups()")
92 def test_initgroups(self):
93 # It takes a string and an integer; check that it raises a TypeError
94 # for other argument lists.
95 self.assertRaises(TypeError, posix.initgroups)
96 self.assertRaises(TypeError, posix.initgroups, None)
97 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
98 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
99
100 # If a non-privileged user invokes it, it should fail with OSError
101 # EPERM.
102 if os.getuid() != 0:
103 name = pwd.getpwuid(posix.getuid()).pw_name
104 try:
105 posix.initgroups(name, 13)
106 except OSError as e:
107 self.assertEquals(e.errno, errno.EPERM)
108 else:
109 self.fail("Expected OSError to be raised by initgroups")
110
Neal Norwitze241ce82003-02-17 18:17:05 +0000111 def test_statvfs(self):
112 if hasattr(posix, 'statvfs'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000113 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000114
115 def test_fstatvfs(self):
116 if hasattr(posix, 'fstatvfs'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000117 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000118 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000119 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000120 finally:
121 fp.close()
122
123 def test_ftruncate(self):
124 if hasattr(posix, 'ftruncate'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000125 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000126 try:
127 # we need to have some data to truncate
128 fp.write('test')
129 fp.flush()
130 posix.ftruncate(fp.fileno(), 0)
131 finally:
132 fp.close()
133
134 def test_dup(self):
135 if hasattr(posix, 'dup'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000136 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000137 try:
138 fd = posix.dup(fp.fileno())
Ezio Melottie9615932010-01-24 19:26:24 +0000139 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000140 os.close(fd)
141 finally:
142 fp.close()
143
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000144 def test_confstr(self):
145 if hasattr(posix, 'confstr'):
146 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
147 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
148
Neal Norwitze241ce82003-02-17 18:17:05 +0000149 def test_dup2(self):
150 if hasattr(posix, 'dup2'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000151 fp1 = open(support.TESTFN)
152 fp2 = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000153 try:
154 posix.dup2(fp1.fileno(), fp2.fileno())
155 finally:
156 fp1.close()
157 fp2.close()
158
Skip Montanaro98470002005-06-17 01:14:49 +0000159 def test_osexlock(self):
160 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000161 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000162 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000163 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000164 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
165 os.close(fd)
166
167 if hasattr(posix, "O_SHLOCK"):
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_SHLOCK|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 def test_osshlock(self):
175 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000176 fd1 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000177 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000178 fd2 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000179 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
180 os.close(fd2)
181 os.close(fd1)
182
183 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000184 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000185 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000186 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000187 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
188 os.close(fd)
189
Neal Norwitze241ce82003-02-17 18:17:05 +0000190 def test_fstat(self):
191 if hasattr(posix, 'fstat'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000192 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000193 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000194 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000195 finally:
196 fp.close()
197
198 def test_stat(self):
199 if hasattr(posix, 'stat'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000200 self.assertTrue(posix.stat(support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000201
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000202 def _test_all_chown_common(self, chown_func, first_param):
203 """Common code for chown, fchown and lchown tests."""
204 if os.getuid() == 0:
205 try:
206 # Many linux distros have a nfsnobody user as MAX_UID-2
207 # that makes a good test case for signedness issues.
208 # http://bugs.python.org/issue1747858
209 # This part of the test only runs when run as root.
210 # Only scary people run their tests as root.
211 ent = pwd.getpwnam('nfsnobody')
212 chown_func(first_param, ent.pw_uid, ent.pw_gid)
213 except KeyError:
214 pass
215 else:
216 # non-root cannot chown to root, raises OSError
217 self.assertRaises(OSError, chown_func,
218 first_param, 0, 0)
219 # test a successful chown call
220 chown_func(first_param, os.getuid(), os.getgid())
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000221
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000222 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
223 def test_chown(self):
224 # raise an OSError if the file does not exist
225 os.unlink(support.TESTFN)
226 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000227
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000228 # re-create the file
229 open(support.TESTFN, 'w').close()
230 self._test_all_chown_common(posix.chown, support.TESTFN)
231
232 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
233 def test_fchown(self):
234 os.unlink(support.TESTFN)
235
236 # re-create the file
237 test_file = open(support.TESTFN, 'w')
238 try:
239 fd = test_file.fileno()
240 self._test_all_chown_common(posix.fchown, fd)
241 finally:
242 test_file.close()
243
244 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
245 def test_lchown(self):
246 os.unlink(support.TESTFN)
247 # create a symlink
248 os.symlink('/tmp/dummy-symlink-target', support.TESTFN)
249 self._test_all_chown_common(posix.lchown, support.TESTFN)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000250
Neal Norwitze241ce82003-02-17 18:17:05 +0000251 def test_chdir(self):
252 if hasattr(posix, 'chdir'):
253 posix.chdir(os.curdir)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000254 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000255
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000256 def test_listdir(self):
257 if hasattr(posix, 'listdir'):
258 self.assertTrue(support.TESTFN in posix.listdir(os.curdir))
259
260 def test_listdir_default(self):
261 # When listdir is called without argument, it's the same as listdir(os.curdir)
262 if hasattr(posix, 'listdir'):
263 self.assertTrue(support.TESTFN in posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000264
265 def test_access(self):
266 if hasattr(posix, 'access'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000267 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000268
269 def test_umask(self):
270 if hasattr(posix, 'umask'):
271 old_mask = posix.umask(0)
Ezio Melottie9615932010-01-24 19:26:24 +0000272 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000273 posix.umask(old_mask)
274
275 def test_strerror(self):
276 if hasattr(posix, 'strerror'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000277 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000278
279 def test_pipe(self):
280 if hasattr(posix, 'pipe'):
281 reader, writer = posix.pipe()
282 os.close(reader)
283 os.close(writer)
284
Neal Norwitze241ce82003-02-17 18:17:05 +0000285 def test_utime(self):
286 if hasattr(posix, 'utime'):
287 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000288 posix.utime(support.TESTFN, None)
289 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
290 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
291 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
292 posix.utime(support.TESTFN, (int(now), int(now)))
293 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000294
Thomas Wouterscf297e42007-02-23 15:07:44 +0000295 def test_chflags(self):
296 if hasattr(posix, 'chflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000297 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000298 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000299 posix.chflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000300
301 def test_lchflags(self):
302 if hasattr(posix, 'lchflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000303 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000304 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000305 posix.lchflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000306
Guido van Rossum98297ee2007-11-06 21:34:58 +0000307 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000308 if os.name == "nt":
309 item_type = str
310 else:
311 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000312 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000313 self.assertEqual(type(k), item_type)
314 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000315
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000316 def test_getcwd_long_pathnames(self):
317 if hasattr(posix, 'getcwd'):
318 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
319 curdir = os.getcwd()
320 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
321
322 try:
323 os.mkdir(base_path)
324 os.chdir(base_path)
325 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000326# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000327# because the test results in Error in that case.
328# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000329# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000330 return
331
332 def _create_and_do_getcwd(dirname, current_path_length = 0):
333 try:
334 os.mkdir(dirname)
335 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000336 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000337
338 os.chdir(dirname)
339 try:
340 os.getcwd()
341 if current_path_length < 1027:
342 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
343 finally:
344 os.chdir('..')
345 os.rmdir(dirname)
346
347 _create_and_do_getcwd(dirname)
348
349 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000350 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000351 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000352
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000353 def test_getgroups(self):
354 with os.popen('id -G') as idg:
355 groups = idg.read().strip()
356
357 if not groups:
358 raise unittest.SkipTest("need working 'id -G'")
359
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000360 # 'id -G' and 'os.getgroups()' should return the same
361 # groups, ignoring order and duplicates.
Ronald Oussorencb615e62010-07-24 14:15:19 +0000362 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000363 set([int(x) for x in groups.split()]),
364 set(posix.getgroups()))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000365
366class PosixGroupsTester(unittest.TestCase):
367
368 def setUp(self):
369 if posix.getuid() != 0:
370 raise unittest.SkipTest("not enough privileges")
371 if not hasattr(posix, 'getgroups'):
372 raise unittest.SkipTest("need posix.getgroups")
373 if sys.platform == 'darwin':
374 raise unittest.SkipTest("getgroups(2) is broken on OSX")
375 self.saved_groups = posix.getgroups()
376
377 def tearDown(self):
378 if hasattr(posix, 'setgroups'):
379 posix.setgroups(self.saved_groups)
380 elif hasattr(posix, 'initgroups'):
381 name = pwd.getpwuid(posix.getuid()).pw_name
382 posix.initgroups(name, self.saved_groups[0])
383
384 @unittest.skipUnless(hasattr(posix, 'initgroups'),
385 "test needs posix.initgroups()")
386 def test_initgroups(self):
387 # find missing group
388
389 groups = sorted(self.saved_groups)
390 for g1,g2 in zip(groups[:-1], groups[1:]):
391 g = g1 + 1
392 if g < g2:
393 break
394 else:
395 g = g2 + 1
396 name = pwd.getpwuid(posix.getuid()).pw_name
397 posix.initgroups(name, g)
398 self.assertIn(g, posix.getgroups())
399
400 @unittest.skipUnless(hasattr(posix, 'setgroups'),
401 "test needs posix.setgroups()")
402 def test_setgroups(self):
403 for groups in [[0], range(16)]:
404 posix.setgroups(groups)
405 self.assertListEqual(groups, posix.getgroups())
406
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000407
Neal Norwitze241ce82003-02-17 18:17:05 +0000408def test_main():
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000409 support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000410
411if __name__ == '__main__':
412 test_main()