blob: a5db21eefbd7de7396ecc9ce377a4f7e6e049493 [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
Gregory P. Smithf48da8f2008-03-18 19:05:32 +000012import pwd
Facundo Batista5596b0c2008-06-22 13:36:20 +000013import shutil
Stefan Krah182ae642010-07-13 19:17:08 +000014import sys
Neal Norwitze241ce82003-02-17 18:17:05 +000015import unittest
16import warnings
R. David Murray59beec32009-03-30 19:04:00 +000017
R. David Murray59beec32009-03-30 19:04:00 +000018
Neal Norwitze241ce82003-02-17 18:17:05 +000019warnings.filterwarnings('ignore', '.* potential security risk .*',
20 RuntimeWarning)
21
22class PosixTester(unittest.TestCase):
23
24 def setUp(self):
25 # create empty file
Walter Dörwald21d3a322003-05-01 17:45:56 +000026 fp = open(test_support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000027 fp.close()
28
29 def tearDown(self):
Walter Dörwald21d3a322003-05-01 17:45:56 +000030 os.unlink(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +000031
32 def testNoArgFunctions(self):
33 # test posix functions which take no arguments and have
34 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
35 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdu", "uname",
Neal Norwitz71b13e82003-02-23 22:12:24 +000036 "times", "getloadavg", "tmpnam",
Neal Norwitze241ce82003-02-17 18:17:05 +000037 "getegid", "geteuid", "getgid", "getgroups",
38 "getpid", "getpgrp", "getppid", "getuid",
39 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000040
Antoine Pitroub0614612011-01-02 20:04:52 +000041 with warnings.catch_warnings():
42 warnings.filterwarnings("ignore", "", DeprecationWarning)
43 for name in NO_ARG_FUNCTIONS:
44 posix_func = getattr(posix, name, None)
45 if posix_func is not None:
46 posix_func()
47 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000048
Martin v. Löwis50ea4562009-11-27 13:56:01 +000049 if hasattr(posix, 'getresuid'):
50 def test_getresuid(self):
51 user_ids = posix.getresuid()
52 self.assertEqual(len(user_ids), 3)
53 for val in user_ids:
54 self.assertGreaterEqual(val, 0)
55
56 if hasattr(posix, 'getresgid'):
57 def test_getresgid(self):
58 group_ids = posix.getresgid()
59 self.assertEqual(len(group_ids), 3)
60 for val in group_ids:
61 self.assertGreaterEqual(val, 0)
62
63 if hasattr(posix, 'setresuid'):
64 def test_setresuid(self):
65 current_user_ids = posix.getresuid()
66 self.assertIsNone(posix.setresuid(*current_user_ids))
67 # -1 means don't change that value.
68 self.assertIsNone(posix.setresuid(-1, -1, -1))
69
70 def test_setresuid_exception(self):
71 # Don't do this test if someone is silly enough to run us as root.
72 current_user_ids = posix.getresuid()
73 if 0 not in current_user_ids:
74 new_user_ids = (current_user_ids[0]+1, -1, -1)
75 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
76
77 if hasattr(posix, 'setresgid'):
78 def test_setresgid(self):
79 current_group_ids = posix.getresgid()
80 self.assertIsNone(posix.setresgid(*current_group_ids))
81 # -1 means don't change that value.
82 self.assertIsNone(posix.setresgid(-1, -1, -1))
83
84 def test_setresgid_exception(self):
85 # Don't do this test if someone is silly enough to run us as root.
86 current_group_ids = posix.getresgid()
87 if 0 not in current_group_ids:
88 new_group_ids = (current_group_ids[0]+1, -1, -1)
89 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
90
Antoine Pitrou30b3b352009-12-02 20:37:54 +000091 @unittest.skipUnless(hasattr(posix, 'initgroups'),
92 "test needs os.initgroups()")
93 def test_initgroups(self):
94 # It takes a string and an integer; check that it raises a TypeError
95 # for other argument lists.
96 self.assertRaises(TypeError, posix.initgroups)
97 self.assertRaises(TypeError, posix.initgroups, None)
98 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
99 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
100
101 # If a non-privileged user invokes it, it should fail with OSError
102 # EPERM.
103 if os.getuid() != 0:
104 name = pwd.getpwuid(posix.getuid()).pw_name
105 try:
106 posix.initgroups(name, 13)
107 except OSError as e:
Ezio Melotti2623a372010-11-21 13:34:58 +0000108 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000109 else:
110 self.fail("Expected OSError to be raised by initgroups")
111
Neal Norwitze241ce82003-02-17 18:17:05 +0000112 def test_statvfs(self):
113 if hasattr(posix, 'statvfs'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000114 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000115
116 def test_fstatvfs(self):
117 if hasattr(posix, 'fstatvfs'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000118 fp = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000119 try:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000120 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000121 finally:
122 fp.close()
123
124 def test_ftruncate(self):
125 if hasattr(posix, 'ftruncate'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000126 fp = open(test_support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000127 try:
128 # we need to have some data to truncate
129 fp.write('test')
130 fp.flush()
131 posix.ftruncate(fp.fileno(), 0)
132 finally:
133 fp.close()
134
135 def test_dup(self):
136 if hasattr(posix, 'dup'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000137 fp = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000138 try:
139 fd = posix.dup(fp.fileno())
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000140 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000141 os.close(fd)
142 finally:
143 fp.close()
144
Skip Montanaro94785ef2006-04-20 01:29:48 +0000145 def test_confstr(self):
146 if hasattr(posix, 'confstr'):
147 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
148 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
149
Neal Norwitze241ce82003-02-17 18:17:05 +0000150 def test_dup2(self):
151 if hasattr(posix, 'dup2'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000152 fp1 = open(test_support.TESTFN)
153 fp2 = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000154 try:
155 posix.dup2(fp1.fileno(), fp2.fileno())
156 finally:
157 fp1.close()
158 fp2.close()
159
160 def fdopen_helper(self, *args):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000161 fd = os.open(test_support.TESTFN, os.O_RDONLY)
Neal Norwitze241ce82003-02-17 18:17:05 +0000162 fp2 = posix.fdopen(fd, *args)
163 fp2.close()
164
165 def test_fdopen(self):
166 if hasattr(posix, 'fdopen'):
167 self.fdopen_helper()
168 self.fdopen_helper('r')
169 self.fdopen_helper('r', 100)
170
Skip Montanaro98470002005-06-17 01:14:49 +0000171 def test_osexlock(self):
172 if hasattr(posix, "O_EXLOCK"):
173 fd = os.open(test_support.TESTFN,
174 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
175 self.assertRaises(OSError, os.open, test_support.TESTFN,
176 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
177 os.close(fd)
178
179 if hasattr(posix, "O_SHLOCK"):
180 fd = os.open(test_support.TESTFN,
181 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
182 self.assertRaises(OSError, os.open, test_support.TESTFN,
183 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
184 os.close(fd)
185
186 def test_osshlock(self):
187 if hasattr(posix, "O_SHLOCK"):
188 fd1 = os.open(test_support.TESTFN,
189 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
190 fd2 = os.open(test_support.TESTFN,
191 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
192 os.close(fd2)
193 os.close(fd1)
194
195 if hasattr(posix, "O_EXLOCK"):
196 fd = os.open(test_support.TESTFN,
197 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
198 self.assertRaises(OSError, os.open, test_support.TESTFN,
199 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
200 os.close(fd)
201
Neal Norwitze241ce82003-02-17 18:17:05 +0000202 def test_fstat(self):
203 if hasattr(posix, 'fstat'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000204 fp = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000205 try:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000206 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000207 finally:
208 fp.close()
209
210 def test_stat(self):
211 if hasattr(posix, 'stat'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000212 self.assertTrue(posix.stat(test_support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000213
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000214 def _test_all_chown_common(self, chown_func, first_param):
215 """Common code for chown, fchown and lchown tests."""
216 if os.getuid() == 0:
217 try:
218 # Many linux distros have a nfsnobody user as MAX_UID-2
219 # that makes a good test case for signedness issues.
220 # http://bugs.python.org/issue1747858
221 # This part of the test only runs when run as root.
222 # Only scary people run their tests as root.
223 ent = pwd.getpwnam('nfsnobody')
224 chown_func(first_param, ent.pw_uid, ent.pw_gid)
225 except KeyError:
226 pass
227 else:
228 # non-root cannot chown to root, raises OSError
229 self.assertRaises(OSError, chown_func,
230 first_param, 0, 0)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000231
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000232 # test a successful chown call
233 chown_func(first_param, os.getuid(), os.getgid())
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000234
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000235 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
236 def test_chown(self):
237 # raise an OSError if the file does not exist
238 os.unlink(test_support.TESTFN)
239 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
240
241 # re-create the file
242 open(test_support.TESTFN, 'w').close()
243 self._test_all_chown_common(posix.chown, test_support.TESTFN)
244
245 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
246 def test_fchown(self):
247 os.unlink(test_support.TESTFN)
248
249 # re-create the file
250 test_file = open(test_support.TESTFN, 'w')
251 try:
252 fd = test_file.fileno()
253 self._test_all_chown_common(posix.fchown, fd)
254 finally:
255 test_file.close()
256
257 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
258 def test_lchown(self):
259 os.unlink(test_support.TESTFN)
260 # create a symlink
261 os.symlink('/tmp/dummy-symlink-target', test_support.TESTFN)
262 self._test_all_chown_common(posix.lchown, test_support.TESTFN)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000263
Neal Norwitze241ce82003-02-17 18:17:05 +0000264 def test_chdir(self):
265 if hasattr(posix, 'chdir'):
266 posix.chdir(os.curdir)
Walter Dörwald21d3a322003-05-01 17:45:56 +0000267 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000268
269 def test_lsdir(self):
270 if hasattr(posix, 'lsdir'):
Ezio Melottiaa980582010-01-23 23:04:36 +0000271 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000272
273 def test_access(self):
274 if hasattr(posix, 'access'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000275 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000276
277 def test_umask(self):
278 if hasattr(posix, 'umask'):
279 old_mask = posix.umask(0)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000280 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000281 posix.umask(old_mask)
282
283 def test_strerror(self):
284 if hasattr(posix, 'strerror'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000285 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000286
287 def test_pipe(self):
288 if hasattr(posix, 'pipe'):
Antoine Pitroubba8f2d2010-04-10 23:32:12 +0000289 reader, writer = posix.pipe()
290 os.close(reader)
291 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000292
293 def test_tempnam(self):
294 if hasattr(posix, 'tempnam'):
Antoine Pitroub0614612011-01-02 20:04:52 +0000295 with warnings.catch_warnings():
296 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
297 self.assertTrue(posix.tempnam())
298 self.assertTrue(posix.tempnam(os.curdir))
299 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000300
301 def test_tmpfile(self):
302 if hasattr(posix, 'tmpfile'):
Antoine Pitroub0614612011-01-02 20:04:52 +0000303 with warnings.catch_warnings():
304 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
305 fp = posix.tmpfile()
306 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000307
308 def test_utime(self):
309 if hasattr(posix, 'utime'):
310 now = time.time()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000311 posix.utime(test_support.TESTFN, None)
Neal Norwitzc28e7ad2004-06-06 20:27:05 +0000312 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
313 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
314 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
315 posix.utime(test_support.TESTFN, (int(now), int(now)))
Walter Dörwald21d3a322003-05-01 17:45:56 +0000316 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000317
Martin v. Löwis382abef2007-02-19 10:55:19 +0000318 def test_chflags(self):
319 if hasattr(posix, 'chflags'):
320 st = os.stat(test_support.TESTFN)
321 if hasattr(st, 'st_flags'):
322 posix.chflags(test_support.TESTFN, st.st_flags)
323
324 def test_lchflags(self):
325 if hasattr(posix, 'lchflags'):
326 st = os.stat(test_support.TESTFN)
327 if hasattr(st, 'st_flags'):
328 posix.lchflags(test_support.TESTFN, st.st_flags)
329
Facundo Batista5596b0c2008-06-22 13:36:20 +0000330 def test_getcwd_long_pathnames(self):
331 if hasattr(posix, 'getcwd'):
332 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
333 curdir = os.getcwd()
Facundo Batista96f3dc32008-06-22 18:23:55 +0000334 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000335
336 try:
337 os.mkdir(base_path)
338 os.chdir(base_path)
Facundo Batista96f3dc32008-06-22 18:23:55 +0000339 except:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000340# Just returning nothing instead of the SkipTest exception,
Facundo Batista2694eb02008-06-22 19:35:24 +0000341# because the test results in Error in that case.
342# Is that ok?
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000343# raise unittest.SkipTest, "cannot create directory for testing"
Facundo Batista2694eb02008-06-22 19:35:24 +0000344 return
Facundo Batista5596b0c2008-06-22 13:36:20 +0000345
Facundo Batista96f3dc32008-06-22 18:23:55 +0000346 try:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000347 def _create_and_do_getcwd(dirname, current_path_length = 0):
348 try:
349 os.mkdir(dirname)
350 except:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000351 raise unittest.SkipTest, "mkdir cannot create directory sufficiently deep for getcwd test"
Facundo Batista5596b0c2008-06-22 13:36:20 +0000352
353 os.chdir(dirname)
354 try:
355 os.getcwd()
Stefan Krah182ae642010-07-13 19:17:08 +0000356 if current_path_length < 4099:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000357 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
Stefan Krah182ae642010-07-13 19:17:08 +0000358 except OSError as e:
359 expected_errno = errno.ENAMETOOLONG
360 if 'sunos' in sys.platform or 'openbsd' in sys.platform:
361 expected_errno = errno.ERANGE # Issue 9185
362 self.assertEqual(e.errno, expected_errno)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000363 finally:
364 os.chdir('..')
365 os.rmdir(dirname)
366
367 _create_and_do_getcwd(dirname)
368
369 finally:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000370 os.chdir(curdir)
R. David Murrayb0c828a2009-07-09 18:41:03 +0000371 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000372
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000373 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000374 def test_getgroups(self):
375 with os.popen('id -G') as idg:
376 groups = idg.read().strip()
377
378 if not groups:
379 raise unittest.SkipTest("need working 'id -G'")
380
Ronald Oussorenac72e582010-08-03 07:31:12 +0000381 # 'id -G' and 'os.getgroups()' should return the same
382 # groups, ignoring order and duplicates.
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000383 # #10822 - it is implementation defined whether posix.getgroups()
384 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussoren5719c2f2010-07-24 14:21:29 +0000385 self.assertEqual(
Ronald Oussorenac72e582010-08-03 07:31:12 +0000386 set([int(x) for x in groups.split()]),
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000387 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000388
389class PosixGroupsTester(unittest.TestCase):
390
391 def setUp(self):
392 if posix.getuid() != 0:
393 raise unittest.SkipTest("not enough privileges")
394 if not hasattr(posix, 'getgroups'):
395 raise unittest.SkipTest("need posix.getgroups")
396 if sys.platform == 'darwin':
397 raise unittest.SkipTest("getgroups(2) is broken on OSX")
398 self.saved_groups = posix.getgroups()
399
400 def tearDown(self):
401 if hasattr(posix, 'setgroups'):
402 posix.setgroups(self.saved_groups)
403 elif hasattr(posix, 'initgroups'):
404 name = pwd.getpwuid(posix.getuid()).pw_name
405 posix.initgroups(name, self.saved_groups[0])
406
407 @unittest.skipUnless(hasattr(posix, 'initgroups'),
408 "test needs posix.initgroups()")
409 def test_initgroups(self):
410 # find missing group
411
Antoine Pitroudd806ce2010-09-04 17:34:12 +0000412 g = max(self.saved_groups) + 1
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000413 name = pwd.getpwuid(posix.getuid()).pw_name
414 posix.initgroups(name, g)
415 self.assertIn(g, posix.getgroups())
416
417 @unittest.skipUnless(hasattr(posix, 'setgroups'),
418 "test needs posix.setgroups()")
419 def test_setgroups(self):
420 for groups in [[0], range(16)]:
421 posix.setgroups(groups)
422 self.assertListEqual(groups, posix.getgroups())
423
Facundo Batista5596b0c2008-06-22 13:36:20 +0000424
Neal Norwitze241ce82003-02-17 18:17:05 +0000425def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000426 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000427
428if __name__ == '__main__':
429 test_main()