1a20800d1d93bf83c131523f14271a34641f1f588Brett Cannonimport contextlib
26fc79bf813de21015208d989e38cdc95bda03292Christian Heimesimport sys
3d885aa4d662d6b5aae33f6ecfbaccde3f201ad39Christian Heimesimport os
4b213704f3cad4fc61c4117afe559454b02193e5bThomas Woutersimport unittest
5ee8712cda46338d223509cc5751fd36509ad3860Benjamin Petersonfrom test import support
6412dc9c88f040abf4b23017c5e5e4d8b880d247dChristian Heimesimport time
7b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters
8a21e4ca3c6dc00b2825e2bb4e77a4aa76d8485f0R. David Murrayresource = support.import_module('resource')
9a21e4ca3c6dc00b2825e2bb4e77a4aa76d8485f0R. David Murray
10b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters# This test is checking a few specific problem spots with the resource module.
11b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters
12b213704f3cad4fc61c4117afe559454b02193e5bThomas Woutersclass ResourceTest(unittest.TestCase):
13b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters
14b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters    def test_args(self):
15b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        self.assertRaises(TypeError, resource.getrlimit)
16b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        self.assertRaises(TypeError, resource.getrlimit, 42, 42)
17b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        self.assertRaises(TypeError, resource.setrlimit)
18b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        self.assertRaises(TypeError, resource.setrlimit, 42, 42, 42)
19b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters
20b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters    def test_fsize_ismax(self):
21b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        try:
22b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
23b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        except AttributeError:
24b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            pass
25b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        else:
26b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            # RLIMIT_FSIZE should be RLIM_INFINITY, which will be a really big
27b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            # number on a platform with large file support.  On these platforms,
28b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            # we need to test that the get/setrlimit functions properly convert
29b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            # the number to a C long long and that the conversion doesn't raise
30b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            # an error.
31b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            self.assertEqual(resource.RLIM_INFINITY, max)
32b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
33b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters
34b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters    def test_fsize_enforced(self):
35b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        try:
36b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
37b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        except AttributeError:
38b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            pass
39b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        else:
40b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            # Check to see what happens when the RLIMIT_FSIZE is small.  Some
41b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            # versions of Python were terminated by an uncaught SIGXFSZ, but
42b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            # pythonrun.c has been fixed to ignore that exception.  If so, the
43b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            # write() should return EFBIG when the limit is exceeded.
449fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
45b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            # At least one platform has an unlimited RLIMIT_FSIZE and attempts
46b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            # to change it raise ValueError instead.
47b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            try:
48b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters                try:
49b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters                    resource.setrlimit(resource.RLIMIT_FSIZE, (1024, max))
50b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters                    limit_set = True
51b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters                except ValueError:
52b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters                    limit_set = False
53ee8712cda46338d223509cc5751fd36509ad3860Benjamin Peterson                f = open(support.TESTFN, "wb")
54b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters                try:
55b644fb43d6ba9d3fe1206079e262c62015e55b3fGuido van Rossum                    f.write(b"X" * 1024)
56806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                    try:
57b644fb43d6ba9d3fe1206079e262c62015e55b3fGuido van Rossum                        f.write(b"Y")
58806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                        f.flush()
59af98da18c0af924d7b03884a14ecd8e72a4832d0Christian Heimes                        # On some systems (e.g., Ubuntu on hppa) the flush()
60af98da18c0af924d7b03884a14ecd8e72a4832d0Christian Heimes                        # doesn't always cause the exception, but the close()
6126855635833fcd3f15786b4a9d4241ded293404cChristian Heimes                        # does eventually.  Try flushing several times in
62af98da18c0af924d7b03884a14ecd8e72a4832d0Christian Heimes                        # an attempt to ensure the file is really synced and
63af98da18c0af924d7b03884a14ecd8e72a4832d0Christian Heimes                        # the exception raised.
64af98da18c0af924d7b03884a14ecd8e72a4832d0Christian Heimes                        for i in range(5):
65412dc9c88f040abf4b23017c5e5e4d8b880d247dChristian Heimes                            time.sleep(.1)
66412dc9c88f040abf4b23017c5e5e4d8b880d247dChristian Heimes                            f.flush()
67f7a17b48d748e1835bcf9df86fb7fb318bb020f8Andrew Svetlov                    except OSError:
68806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                        if not limit_set:
69806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                            raise
70806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                    if limit_set:
71806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                        # Close will attempt to flush the byte we wrote
72806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                        # Restore limit first to avoid getting a spurious error
73806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                        resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
74806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                finally:
75806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                    f.close()
76b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            finally:
77806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                if limit_set:
78806c2469cb2e16c6cfd73de9a216933bd55c131fGuido van Rossum                    resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
79ee8712cda46338d223509cc5751fd36509ad3860Benjamin Peterson                support.unlink(support.TESTFN)
80b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters
81b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters    def test_fsize_toobig(self):
82b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        # Be sure that setrlimit is checking for really large values
83b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        too_big = 10**50
84b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        try:
85b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
86b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        except AttributeError:
87b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            pass
88b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        else:
89b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            try:
90b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters                resource.setrlimit(resource.RLIMIT_FSIZE, (too_big, max))
91b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            except (OverflowError, ValueError):
92b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters                pass
93b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            try:
94b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters                resource.setrlimit(resource.RLIMIT_FSIZE, (max, too_big))
95b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            except (OverflowError, ValueError):
96b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters                pass
97b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters
98b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters    def test_getrusage(self):
99b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        self.assertRaises(TypeError, resource.getrusage)
100b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        self.assertRaises(TypeError, resource.getrusage, 42, 42)
101b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        usageself = resource.getrusage(resource.RUSAGE_SELF)
102b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        usagechildren = resource.getrusage(resource.RUSAGE_CHILDREN)
103b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        # May not be available on all systems.
104b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        try:
105b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            usageboth = resource.getrusage(resource.RUSAGE_BOTH)
106b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters        except (ValueError, AttributeError):
107b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters            pass
108b6d4ee536174f2d467c195904c140025109242e7Antoine Pitrou        try:
109b6d4ee536174f2d467c195904c140025109242e7Antoine Pitrou            usage_thread = resource.getrusage(resource.RUSAGE_THREAD)
110b6d4ee536174f2d467c195904c140025109242e7Antoine Pitrou        except (ValueError, AttributeError):
111b6d4ee536174f2d467c195904c140025109242e7Antoine Pitrou            pass
112b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters
11319c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka    # Issue 6083: Reference counting bug
11419c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka    def test_setrusage_refcount(self):
11519c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka        try:
11619c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka            limits = resource.getrlimit(resource.RLIMIT_CPU)
11719c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka        except AttributeError:
11819c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka            pass
11919c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka        else:
12019c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka            class BadSequence:
12119c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka                def __len__(self):
12219c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka                    return 2
12319c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka                def __getitem__(self, key):
12419c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka                    if key in (0, 1):
12519c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka                        return len(tuple(range(1000000)))
12619c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka                    raise IndexError
12719c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka
12819c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka            resource.setrlimit(resource.RLIMIT_CPU, BadSequence())
12919c4e0df29234355074fe7ec67857f0a0b7e0a18Serhiy Storchaka
1304ebc9295d15c52295ce903d99ccf24142c22b29dChristian Heimes    def test_pagesize(self):
1314ebc9295d15c52295ce903d99ccf24142c22b29dChristian Heimes        pagesize = resource.getpagesize()
1324ebc9295d15c52295ce903d99ccf24142c22b29dChristian Heimes        self.assertIsInstance(pagesize, int)
1334ebc9295d15c52295ce903d99ccf24142c22b29dChristian Heimes        self.assertGreaterEqual(pagesize, 0)
1344ebc9295d15c52295ce903d99ccf24142c22b29dChristian Heimes
1356fc79bf813de21015208d989e38cdc95bda03292Christian Heimes    @unittest.skipUnless(sys.platform == 'linux', 'test requires Linux')
1366fc79bf813de21015208d989e38cdc95bda03292Christian Heimes    def test_linux_constants(self):
137a20800d1d93bf83c131523f14271a34641f1f588Brett Cannon        for attr in ['MSGQUEUE', 'NICE', 'RTPRIO', 'RTTIME', 'SIGPENDING']:
138a20800d1d93bf83c131523f14271a34641f1f588Brett Cannon            with contextlib.suppress(AttributeError):
139a20800d1d93bf83c131523f14271a34641f1f588Brett Cannon                self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int)
1406fc79bf813de21015208d989e38cdc95bda03292Christian Heimes
1415bb414d176b5c99d9f2500738fe77c47ea938763Christian Heimes    @support.requires_freebsd_version(9)
1425bb414d176b5c99d9f2500738fe77c47ea938763Christian Heimes    def test_freebsd_contants(self):
1435bb414d176b5c99d9f2500738fe77c47ea938763Christian Heimes        for attr in ['SWAP', 'SBSIZE', 'NPTS']:
1445bb414d176b5c99d9f2500738fe77c47ea938763Christian Heimes            with contextlib.suppress(AttributeError):
1455bb414d176b5c99d9f2500738fe77c47ea938763Christian Heimes                self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int)
1465bb414d176b5c99d9f2500738fe77c47ea938763Christian Heimes
147b7bd5df809aabaf857eb51b139d5e519d8b3c364Christian Heimes    @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit')
148c4a4b346a6caa46a5df0c9a7adf5c52fe3008d73Christian Heimes    @support.requires_linux_version(2, 6, 36)
149b7bd5df809aabaf857eb51b139d5e519d8b3c364Christian Heimes    def test_prlimit(self):
150b7bd5df809aabaf857eb51b139d5e519d8b3c364Christian Heimes        self.assertRaises(TypeError, resource.prlimit)
151d885aa4d662d6b5aae33f6ecfbaccde3f201ad39Christian Heimes        if os.geteuid() != 0:
152d885aa4d662d6b5aae33f6ecfbaccde3f201ad39Christian Heimes            self.assertRaises(PermissionError, resource.prlimit,
153d885aa4d662d6b5aae33f6ecfbaccde3f201ad39Christian Heimes                              1, resource.RLIMIT_AS)
154b7bd5df809aabaf857eb51b139d5e519d8b3c364Christian Heimes        self.assertRaises(ProcessLookupError, resource.prlimit,
155b7bd5df809aabaf857eb51b139d5e519d8b3c364Christian Heimes                          -1, resource.RLIMIT_AS)
156d885aa4d662d6b5aae33f6ecfbaccde3f201ad39Christian Heimes        limit = resource.getrlimit(resource.RLIMIT_AS)
157d885aa4d662d6b5aae33f6ecfbaccde3f201ad39Christian Heimes        self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS), limit)
158d885aa4d662d6b5aae33f6ecfbaccde3f201ad39Christian Heimes        self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, limit),
159d885aa4d662d6b5aae33f6ecfbaccde3f201ad39Christian Heimes                         limit)
160b7bd5df809aabaf857eb51b139d5e519d8b3c364Christian Heimes
161b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka    # Issue 20191: Reference counting bug
162b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka    @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit')
163b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka    @support.requires_linux_version(2, 6, 36)
164b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka    def test_prlimit_refcount(self):
165b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka        class BadSeq:
166b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka            def __len__(self):
167b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka                return 2
168b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka            def __getitem__(self, key):
169b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka                return limits[key] - 1  # new reference
170b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka
171b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka        limits = resource.getrlimit(resource.RLIMIT_AS)
172b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka        self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, BadSeq()),
173b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka                         limits)
174b94eef2ae3737b1f03452a30d5c96640c838dc46Serhiy Storchaka
175b7bd5df809aabaf857eb51b139d5e519d8b3c364Christian Heimes
176b213704f3cad4fc61c4117afe559454b02193e5bThomas Woutersdef test_main(verbose=None):
177ee8712cda46338d223509cc5751fd36509ad3860Benjamin Peterson    support.run_unittest(ResourceTest)
178b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters
179b213704f3cad4fc61c4117afe559454b02193e5bThomas Woutersif __name__ == "__main__":
180b213704f3cad4fc61c4117afe559454b02193e5bThomas Wouters    test_main()
181