diff -r 94a04b8b3a12 Lib/test/test_os.py --- a/Lib/test/test_os.py Wed Dec 25 23:21:03 2013 -0500 +++ b/Lib/test/test_os.py Thu Dec 26 18:05:10 2013 +0800 @@ -4,6 +4,8 @@ import os import errno +import getpass +import grp import unittest import warnings import sys @@ -15,6 +17,7 @@ import contextlib import mmap import platform +import pwd import re import uuid import asyncore @@ -64,6 +67,22 @@ # Issue #14110: Some tests fail on FreeBSD if the user is in the wheel group. HAVE_WHEEL_GROUP = sys.platform.startswith('freebsd') and os.getgid() == 0 +def root_in_posix(): + if hasattr(os, 'getuid'): + return os.getuid() == 0 + else: + return False + +# Get groups whom the process' user belongs to +groups = [g.gr_gid for g in grp.getgrall() if getpass.getuser() in g.gr_mem] +process_gid = os.getgid() +if process_gid not in groups: + groups.append(process_gid) + +# Get all users +all_users = [u.pw_uid for u in pwd.getpwall()] + + # Tests creating TESTFN class FileTests(unittest.TestCase): def setUp(self): @@ -916,6 +935,46 @@ self.assertIsNone(os.chown(support.TESTFN, uid, gid)) self.assertIsNone(os.chown(support.TESTFN, -1, -1)) + @unittest.skipUnless(hasattr(os, 'chown') and len(groups) > 1, + 'test needs os.chown and groups more than one') + def test_chown(self): + gid_1, gid_2 = groups[0:2] + uid = os.stat(support.TESTFN).st_uid + os.chown(support.TESTFN, uid, gid_1) + gid = os.stat(support.TESTFN).st_gid + self.assertEqual(gid, gid_1) + os.chown(support.TESTFN, uid, gid_2) + gid = os.stat(support.TESTFN).st_gid + self.assertEqual(gid, gid_2) + + @unittest.skipUnless(hasattr(os, 'chown') and root_in_posix() and + len(all_users) > 1, + "test needs os.chown, root in posix, and users more " + "than 1") + def test_chown_with_root(self): + uid_1, uid_2 = all_users[0:2] + gid = os.stat(support.TESTFN).st_gid + os.chown(support.TESTFN, uid_1, gid) + uid = os.stat(support.TESTFN).st_uid + self.assertEqual(uid, uid_1) + os.chown(support.TESTFN, uid_2, gid) + uid = os.stat(support.TESTFN).st_uid + self.assertEqual(uid, uid_2) + + @unittest.skipUnless(hasattr(os, 'chown') and not root_in_posix() and + len(all_users) > 1, + "test needs os.chown, non-root account in posix, and " + "users more than 1") + def test_chown_without_permission(self): + uid_1, uid_2 = all_users[0:2] + gid = os.stat(support.TESTFN).st_gid + with self.assertRaises(PermissionError) as cx: + os.chown(support.TESTFN, uid_1, gid) + os.chown(support.TESTFN, uid_2, gid) + self.assertEqual(str(cx.exception), + "[Errno 1] Operation not permitted: '%s'" % + support.TESTFN) + def test_exist_ok_s_isgid_directory(self): path = os.path.join(support.TESTFN, 'dir1') S_ISGID = stat.S_ISGID