blob: 3f6e11bb3638eb39765691ad4a52cdfb280569b0 [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
Neal Norwitze241ce82003-02-17 18:17:05 +000041 for name in NO_ARG_FUNCTIONS:
42 posix_func = getattr(posix, name, None)
43 if posix_func is not None:
44 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000045 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000046
Martin v. Löwis50ea4562009-11-27 13:56:01 +000047 if hasattr(posix, 'getresuid'):
48 def test_getresuid(self):
49 user_ids = posix.getresuid()
50 self.assertEqual(len(user_ids), 3)
51 for val in user_ids:
52 self.assertGreaterEqual(val, 0)
53
54 if hasattr(posix, 'getresgid'):
55 def test_getresgid(self):
56 group_ids = posix.getresgid()
57 self.assertEqual(len(group_ids), 3)
58 for val in group_ids:
59 self.assertGreaterEqual(val, 0)
60
61 if hasattr(posix, 'setresuid'):
62 def test_setresuid(self):
63 current_user_ids = posix.getresuid()
64 self.assertIsNone(posix.setresuid(*current_user_ids))
65 # -1 means don't change that value.
66 self.assertIsNone(posix.setresuid(-1, -1, -1))
67
68 def test_setresuid_exception(self):
69 # Don't do this test if someone is silly enough to run us as root.
70 current_user_ids = posix.getresuid()
71 if 0 not in current_user_ids:
72 new_user_ids = (current_user_ids[0]+1, -1, -1)
73 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
74
75 if hasattr(posix, 'setresgid'):
76 def test_setresgid(self):
77 current_group_ids = posix.getresgid()
78 self.assertIsNone(posix.setresgid(*current_group_ids))
79 # -1 means don't change that value.
80 self.assertIsNone(posix.setresgid(-1, -1, -1))
81
82 def test_setresgid_exception(self):
83 # Don't do this test if someone is silly enough to run us as root.
84 current_group_ids = posix.getresgid()
85 if 0 not in current_group_ids:
86 new_group_ids = (current_group_ids[0]+1, -1, -1)
87 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
88
Antoine Pitrou30b3b352009-12-02 20:37:54 +000089 @unittest.skipUnless(hasattr(posix, 'initgroups'),
90 "test needs os.initgroups()")
91 def test_initgroups(self):
92 # It takes a string and an integer; check that it raises a TypeError
93 # for other argument lists.
94 self.assertRaises(TypeError, posix.initgroups)
95 self.assertRaises(TypeError, posix.initgroups, None)
96 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
97 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
98
99 # If a non-privileged user invokes it, it should fail with OSError
100 # EPERM.
101 if os.getuid() != 0:
102 name = pwd.getpwuid(posix.getuid()).pw_name
103 try:
104 posix.initgroups(name, 13)
105 except OSError as e:
106 self.assertEquals(e.errno, errno.EPERM)
107 else:
108 self.fail("Expected OSError to be raised by initgroups")
109
Neal Norwitze241ce82003-02-17 18:17:05 +0000110 def test_statvfs(self):
111 if hasattr(posix, 'statvfs'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000112 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000113
114 def test_fstatvfs(self):
115 if hasattr(posix, 'fstatvfs'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000116 fp = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000117 try:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000118 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000119 finally:
120 fp.close()
121
122 def test_ftruncate(self):
123 if hasattr(posix, 'ftruncate'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000124 fp = open(test_support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000125 try:
126 # we need to have some data to truncate
127 fp.write('test')
128 fp.flush()
129 posix.ftruncate(fp.fileno(), 0)
130 finally:
131 fp.close()
132
133 def test_dup(self):
134 if hasattr(posix, 'dup'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000135 fp = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000136 try:
137 fd = posix.dup(fp.fileno())
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000138 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000139 os.close(fd)
140 finally:
141 fp.close()
142
Skip Montanaro94785ef2006-04-20 01:29:48 +0000143 def test_confstr(self):
144 if hasattr(posix, 'confstr'):
145 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
146 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
147
Neal Norwitze241ce82003-02-17 18:17:05 +0000148 def test_dup2(self):
149 if hasattr(posix, 'dup2'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000150 fp1 = open(test_support.TESTFN)
151 fp2 = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000152 try:
153 posix.dup2(fp1.fileno(), fp2.fileno())
154 finally:
155 fp1.close()
156 fp2.close()
157
158 def fdopen_helper(self, *args):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000159 fd = os.open(test_support.TESTFN, os.O_RDONLY)
Neal Norwitze241ce82003-02-17 18:17:05 +0000160 fp2 = posix.fdopen(fd, *args)
161 fp2.close()
162
163 def test_fdopen(self):
164 if hasattr(posix, 'fdopen'):
165 self.fdopen_helper()
166 self.fdopen_helper('r')
167 self.fdopen_helper('r', 100)
168
Skip Montanaro98470002005-06-17 01:14:49 +0000169 def test_osexlock(self):
170 if hasattr(posix, "O_EXLOCK"):
171 fd = os.open(test_support.TESTFN,
172 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
173 self.assertRaises(OSError, os.open, test_support.TESTFN,
174 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
175 os.close(fd)
176
177 if hasattr(posix, "O_SHLOCK"):
178 fd = os.open(test_support.TESTFN,
179 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
180 self.assertRaises(OSError, os.open, test_support.TESTFN,
181 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
182 os.close(fd)
183
184 def test_osshlock(self):
185 if hasattr(posix, "O_SHLOCK"):
186 fd1 = os.open(test_support.TESTFN,
187 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
188 fd2 = os.open(test_support.TESTFN,
189 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
190 os.close(fd2)
191 os.close(fd1)
192
193 if hasattr(posix, "O_EXLOCK"):
194 fd = os.open(test_support.TESTFN,
195 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
196 self.assertRaises(OSError, os.open, test_support.TESTFN,
197 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
198 os.close(fd)
199
Neal Norwitze241ce82003-02-17 18:17:05 +0000200 def test_fstat(self):
201 if hasattr(posix, 'fstat'):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000202 fp = open(test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000203 try:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000204 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000205 finally:
206 fp.close()
207
208 def test_stat(self):
209 if hasattr(posix, 'stat'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000210 self.assertTrue(posix.stat(test_support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000211
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000212 def _test_all_chown_common(self, chown_func, first_param):
213 """Common code for chown, fchown and lchown tests."""
214 if os.getuid() == 0:
215 try:
216 # Many linux distros have a nfsnobody user as MAX_UID-2
217 # that makes a good test case for signedness issues.
218 # http://bugs.python.org/issue1747858
219 # This part of the test only runs when run as root.
220 # Only scary people run their tests as root.
221 ent = pwd.getpwnam('nfsnobody')
222 chown_func(first_param, ent.pw_uid, ent.pw_gid)
223 except KeyError:
224 pass
225 else:
226 # non-root cannot chown to root, raises OSError
227 self.assertRaises(OSError, chown_func,
228 first_param, 0, 0)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000229
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000230 # test a successful chown call
231 chown_func(first_param, os.getuid(), os.getgid())
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000232
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000233 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
234 def test_chown(self):
235 # raise an OSError if the file does not exist
236 os.unlink(test_support.TESTFN)
237 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
238
239 # re-create the file
240 open(test_support.TESTFN, 'w').close()
241 self._test_all_chown_common(posix.chown, test_support.TESTFN)
242
243 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
244 def test_fchown(self):
245 os.unlink(test_support.TESTFN)
246
247 # re-create the file
248 test_file = open(test_support.TESTFN, 'w')
249 try:
250 fd = test_file.fileno()
251 self._test_all_chown_common(posix.fchown, fd)
252 finally:
253 test_file.close()
254
255 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
256 def test_lchown(self):
257 os.unlink(test_support.TESTFN)
258 # create a symlink
259 os.symlink('/tmp/dummy-symlink-target', test_support.TESTFN)
260 self._test_all_chown_common(posix.lchown, test_support.TESTFN)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000261
Neal Norwitze241ce82003-02-17 18:17:05 +0000262 def test_chdir(self):
263 if hasattr(posix, 'chdir'):
264 posix.chdir(os.curdir)
Walter Dörwald21d3a322003-05-01 17:45:56 +0000265 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000266
267 def test_lsdir(self):
268 if hasattr(posix, 'lsdir'):
Ezio Melottiaa980582010-01-23 23:04:36 +0000269 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000270
271 def test_access(self):
272 if hasattr(posix, 'access'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000273 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000274
275 def test_umask(self):
276 if hasattr(posix, 'umask'):
277 old_mask = posix.umask(0)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000278 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000279 posix.umask(old_mask)
280
281 def test_strerror(self):
282 if hasattr(posix, 'strerror'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000283 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000284
285 def test_pipe(self):
286 if hasattr(posix, 'pipe'):
Antoine Pitroubba8f2d2010-04-10 23:32:12 +0000287 reader, writer = posix.pipe()
288 os.close(reader)
289 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000290
291 def test_tempnam(self):
292 if hasattr(posix, 'tempnam'):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000293 self.assertTrue(posix.tempnam())
294 self.assertTrue(posix.tempnam(os.curdir))
295 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000296
297 def test_tmpfile(self):
298 if hasattr(posix, 'tmpfile'):
299 fp = posix.tmpfile()
300 fp.close()
301
302 def test_utime(self):
303 if hasattr(posix, 'utime'):
304 now = time.time()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000305 posix.utime(test_support.TESTFN, None)
Neal Norwitzc28e7ad2004-06-06 20:27:05 +0000306 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
307 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
308 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
309 posix.utime(test_support.TESTFN, (int(now), int(now)))
Walter Dörwald21d3a322003-05-01 17:45:56 +0000310 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000311
Martin v. Löwis382abef2007-02-19 10:55:19 +0000312 def test_chflags(self):
313 if hasattr(posix, 'chflags'):
314 st = os.stat(test_support.TESTFN)
315 if hasattr(st, 'st_flags'):
316 posix.chflags(test_support.TESTFN, st.st_flags)
317
318 def test_lchflags(self):
319 if hasattr(posix, 'lchflags'):
320 st = os.stat(test_support.TESTFN)
321 if hasattr(st, 'st_flags'):
322 posix.lchflags(test_support.TESTFN, st.st_flags)
323
Facundo Batista5596b0c2008-06-22 13:36:20 +0000324 def test_getcwd_long_pathnames(self):
325 if hasattr(posix, 'getcwd'):
326 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
327 curdir = os.getcwd()
Facundo Batista96f3dc32008-06-22 18:23:55 +0000328 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000329
330 try:
331 os.mkdir(base_path)
332 os.chdir(base_path)
Facundo Batista96f3dc32008-06-22 18:23:55 +0000333 except:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000334# Just returning nothing instead of the SkipTest exception,
Facundo Batista2694eb02008-06-22 19:35:24 +0000335# because the test results in Error in that case.
336# Is that ok?
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000337# raise unittest.SkipTest, "cannot create directory for testing"
Facundo Batista2694eb02008-06-22 19:35:24 +0000338 return
Facundo Batista5596b0c2008-06-22 13:36:20 +0000339
Facundo Batista96f3dc32008-06-22 18:23:55 +0000340 try:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000341 def _create_and_do_getcwd(dirname, current_path_length = 0):
342 try:
343 os.mkdir(dirname)
344 except:
Benjamin Peterson888a39b2009-03-26 20:48:25 +0000345 raise unittest.SkipTest, "mkdir cannot create directory sufficiently deep for getcwd test"
Facundo Batista5596b0c2008-06-22 13:36:20 +0000346
347 os.chdir(dirname)
348 try:
349 os.getcwd()
Stefan Krah182ae642010-07-13 19:17:08 +0000350 if current_path_length < 4099:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000351 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
Stefan Krah182ae642010-07-13 19:17:08 +0000352 except OSError as e:
353 expected_errno = errno.ENAMETOOLONG
354 if 'sunos' in sys.platform or 'openbsd' in sys.platform:
355 expected_errno = errno.ERANGE # Issue 9185
356 self.assertEqual(e.errno, expected_errno)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000357 finally:
358 os.chdir('..')
359 os.rmdir(dirname)
360
361 _create_and_do_getcwd(dirname)
362
363 finally:
Facundo Batista5596b0c2008-06-22 13:36:20 +0000364 os.chdir(curdir)
R. David Murrayb0c828a2009-07-09 18:41:03 +0000365 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000366
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000367 def test_getgroups(self):
368 with os.popen('id -G') as idg:
369 groups = idg.read().strip()
370
371 if not groups:
372 raise unittest.SkipTest("need working 'id -G'")
373
374 self.assertEqual([int(x) for x in groups.split()], posix.getgroups())
375
376class PosixGroupsTester(unittest.TestCase):
377
378 def setUp(self):
379 if posix.getuid() != 0:
380 raise unittest.SkipTest("not enough privileges")
381 if not hasattr(posix, 'getgroups'):
382 raise unittest.SkipTest("need posix.getgroups")
383 if sys.platform == 'darwin':
384 raise unittest.SkipTest("getgroups(2) is broken on OSX")
385 self.saved_groups = posix.getgroups()
386
387 def tearDown(self):
388 if hasattr(posix, 'setgroups'):
389 posix.setgroups(self.saved_groups)
390 elif hasattr(posix, 'initgroups'):
391 name = pwd.getpwuid(posix.getuid()).pw_name
392 posix.initgroups(name, self.saved_groups[0])
393
394 @unittest.skipUnless(hasattr(posix, 'initgroups'),
395 "test needs posix.initgroups()")
396 def test_initgroups(self):
397 # find missing group
398
399 groups = sorted(self.saved_groups)
400 for g1,g2 in zip(groups[:-1], groups[1:]):
401 g = g1 + 1
402 if g < g2:
403 break
404 else:
405 g = g2 + 1
406 name = pwd.getpwuid(posix.getuid()).pw_name
407 posix.initgroups(name, g)
408 self.assertIn(g, posix.getgroups())
409
410 @unittest.skipUnless(hasattr(posix, 'setgroups'),
411 "test needs posix.setgroups()")
412 def test_setgroups(self):
413 for groups in [[0], range(16)]:
414 posix.setgroups(groups)
415 self.assertListEqual(groups, posix.getgroups())
416
Facundo Batista5596b0c2008-06-22 13:36:20 +0000417
Neal Norwitze241ce82003-02-17 18:17:05 +0000418def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000419 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000420
421if __name__ == '__main__':
422 test_main()