diff -r 22cfc057a1f1 Lib/test/test_os.py --- a/Lib/test/test_os.py Mon Jun 23 20:16:06 2014 -0700 +++ b/Lib/test/test_os.py Thu Jun 26 22:57:41 2014 +0700 @@ -4,6 +4,7 @@ import os import errno +import getpass import unittest import warnings import sys @@ -43,6 +44,14 @@ import _winapi except ImportError: _winapi = None +try: + import grp +except ImportError: + grp = None +try: + import pwd +except ImportError: + pwd = None from test.script_helper import assert_python_ok @@ -68,6 +77,7 @@ # 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 + # Tests creating TESTFN class FileTests(unittest.TestCase): def setUp(self): @@ -931,17 +941,6 @@ os.makedirs(path, mode=mode, exist_ok=True) os.umask(old_mask) - @unittest.skipUnless(hasattr(os, 'chown'), 'test needs os.chown') - def test_chown_uid_gid_arguments_must_be_index(self): - stat = os.stat(support.TESTFN) - uid = stat.st_uid - gid = stat.st_gid - for value in (-1.0, -1j, decimal.Decimal(-1), fractions.Fraction(-2, 2)): - self.assertRaises(TypeError, os.chown, support.TESTFN, value, gid) - self.assertRaises(TypeError, os.chown, support.TESTFN, uid, value) - self.assertIsNone(os.chown(support.TESTFN, uid, gid)) - self.assertIsNone(os.chown(support.TESTFN, -1, -1)) - def test_exist_ok_s_isgid_directory(self): path = os.path.join(support.TESTFN, 'dir1') S_ISGID = stat.S_ISGID @@ -992,6 +991,84 @@ os.removedirs(path) +@unittest.skipUnless(hasattr(os, 'chown'), "Test needs chown") +class ChownFileTests(unittest.TestCase): + + groups = [] + all_users = [] + + def _root_in_posix(): + if hasattr(os, 'geteuid'): + return os.geteuid() == 0 + else: + return False + + def setUpClass(): + os.mkdir(support.TESTFN) + if grp is not None: + # Get groups whom the process' user belongs to + ChownFileTests.groups = [g.gr_gid for g in + grp.getgrall() + if getpass.getuser() in g.gr_mem] + if hasattr(os, 'getgid'): + process_gid = os.getgid() + if process_gid not in ChownFileTests.groups: + ChownFileTests.groups.append(process_gid) + + if pwd is not None: + # Get all users + ChownFileTests.all_users = [u.pw_uid for u in pwd.getpwall()] + + def test_chown_uid_gid_arguments_must_be_index(self): + stat = os.stat(support.TESTFN) + uid = stat.st_uid + gid = stat.st_gid + for value in (-1.0, -1j, decimal.Decimal(-1), fractions.Fraction(-2, 2)): + self.assertRaises(TypeError, os.chown, support.TESTFN, value, gid) + self.assertRaises(TypeError, os.chown, support.TESTFN, uid, value) + self.assertIsNone(os.chown(support.TESTFN, uid, gid)) + self.assertIsNone(os.chown(support.TESTFN, -1, -1)) + + def test_chown(self): + if len(ChownFileTests.groups) < 2: + self.skipTest("Test needs groups more than one") + gid_1, gid_2 = ChownFileTests.groups[: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(_root_in_posix(), "test needs root priviledge") + def test_chown_with_root(self): + if len(ChownFileTests.all_users) < 2: + self.skipTest("Test needs users more than one") + uid_1, uid_2 = ChownFileTests.all_users[: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(not _root_in_posix(), "test needs non-root account") + def test_chown_without_permission(self): + if len(ChownFileTests.all_users) < 2: + self.skipTest("Test needs users more than one") + uid_1, uid_2 = ChownFileTests.all_users[:2] + gid = os.stat(support.TESTFN).st_gid + with self.assertRaisesRegex(PermissionError, + "Operation not permitted"): + os.chown(support.TESTFN, uid_1, gid) + os.chown(support.TESTFN, uid_2, gid) + + def tearDownClass(): + os.rmdir(support.TESTFN) + + class RemoveDirsTests(unittest.TestCase): def setUp(self): os.makedirs(support.TESTFN) @@ -2576,6 +2653,7 @@ WalkTests, FwalkTests, MakedirTests, + ChownFileTests, DevNullTests, URandomTests, ExecTests,