diff -r 3598805d7636 Lib/test/test_os.py --- a/Lib/test/test_os.py Wed Dec 25 22:26:59 2013 -0500 +++ b/Lib/test/test_os.py Thu Dec 26 18:26:53 2013 +0800 @@ -4,6 +4,9 @@ import os import errno +import getpass +import grp +import pwd import unittest import warnings import sys @@ -23,6 +26,22 @@ warnings.filterwarnings("ignore", "tempnam", RuntimeWarning, __name__) warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning, __name__) +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): @@ -64,6 +83,52 @@ new = sys.getrefcount(path) self.assertEqual(old, new) + @unittest.skipUnless(hasattr(os, 'chown') and len(groups) > 1, + 'test needs os.chown and groups more than one') + def test_chown(self): + f = os.open(test_support.TESTFN, os.O_CREAT|os.O_RDWR) + os.close(f) + gid_1, gid_2 = groups[0:2] + uid = os.stat(test_support.TESTFN).st_uid + os.chown(test_support.TESTFN, uid, gid_1) + gid = os.stat(test_support.TESTFN).st_gid + self.assertEqual(gid, gid_1) + os.chown(test_support.TESTFN, uid, gid_2) + gid = os.stat(test_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): + f = os.open(test_support.TESTFN, os.O_CREAT|os.O_RDWR) + os.close(f) + uid_1, uid_2 = all_users[0:2] + gid = os.stat(test_support.TESTFN).st_gid + os.chown(test_support.TESTFN, uid_1, gid) + uid = os.stat(test_support.TESTFN).st_uid + self.assertEqual(uid, uid_1) + os.chown(test_support.TESTFN, uid_2, gid) + uid = os.stat(test_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): + f = os.open(test_support.TESTFN, os.O_CREAT|os.O_RDWR) + os.close(f) + uid_1, uid_2 = all_users[0:2] + gid = os.stat(test_support.TESTFN).st_gid + with self.assertRaises(OSError) as cx: + os.chown(test_support.TESTFN, uid_1, gid) + os.chown(test_support.TESTFN, uid_2, gid) + self.assertEqual(str(cx.exception), + "[Errno 1] Operation not permitted: '%s'" % + test_support.TESTFN) + class TemporaryFileTests(unittest.TestCase): def setUp(self):