blob: d909e316b7fd65b346fda3b914b5faa82fcd5062 [file] [log] [blame]
Brett Cannona20800d2013-10-25 15:45:25 -04001import contextlib
Christian Heimes6fc79bf2013-10-22 11:09:27 +02002import sys
Thomas Woutersb2137042007-02-01 18:02:27 +00003import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00004from test import support
Hai Shibb0424b2020-08-04 00:47:42 +08005from test.support import import_helper
6from test.support import os_helper
Christian Heimes412dc9c2008-01-27 18:55:54 +00007import time
Jeremy Hylton74ce77f2002-04-23 20:21:22 +00008
Hai Shibb0424b2020-08-04 00:47:42 +08009resource = import_helper.import_module('resource')
R. David Murraya21e4ca2009-03-31 23:16:50 +000010
Thomas Woutersb2137042007-02-01 18:02:27 +000011# This test is checking a few specific problem spots with the resource module.
Jeremy Hylton74ce77f2002-04-23 20:21:22 +000012
Thomas Woutersb2137042007-02-01 18:02:27 +000013class ResourceTest(unittest.TestCase):
Jeremy Hylton74ce77f2002-04-23 20:21:22 +000014
Thomas Woutersb2137042007-02-01 18:02:27 +000015 def test_args(self):
16 self.assertRaises(TypeError, resource.getrlimit)
17 self.assertRaises(TypeError, resource.getrlimit, 42, 42)
18 self.assertRaises(TypeError, resource.setrlimit)
19 self.assertRaises(TypeError, resource.setrlimit, 42, 42, 42)
Jason Tishlere4a070a2002-12-12 18:13:36 +000020
Lihua Zhao693c1042019-04-17 23:41:33 +080021 @unittest.skipIf(sys.platform == "vxworks",
22 "setting RLIMIT_FSIZE is not supported on VxWorks")
Thomas Woutersb2137042007-02-01 18:02:27 +000023 def test_fsize_ismax(self):
Thomas Woutersb2137042007-02-01 18:02:27 +000024 try:
25 (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
26 except AttributeError:
27 pass
28 else:
29 # RLIMIT_FSIZE should be RLIM_INFINITY, which will be a really big
30 # number on a platform with large file support. On these platforms,
31 # we need to test that the get/setrlimit functions properly convert
32 # the number to a C long long and that the conversion doesn't raise
33 # an error.
34 self.assertEqual(resource.RLIM_INFINITY, max)
35 resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
Jeremy Hylton74ce77f2002-04-23 20:21:22 +000036
Thomas Woutersb2137042007-02-01 18:02:27 +000037 def test_fsize_enforced(self):
38 try:
39 (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
40 except AttributeError:
41 pass
42 else:
43 # Check to see what happens when the RLIMIT_FSIZE is small. Some
44 # versions of Python were terminated by an uncaught SIGXFSZ, but
45 # pythonrun.c has been fixed to ignore that exception. If so, the
46 # write() should return EFBIG when the limit is exceeded.
Thomas Wouters9fe394c2007-02-05 01:24:16 +000047
Thomas Woutersb2137042007-02-01 18:02:27 +000048 # At least one platform has an unlimited RLIMIT_FSIZE and attempts
49 # to change it raise ValueError instead.
50 try:
51 try:
52 resource.setrlimit(resource.RLIMIT_FSIZE, (1024, max))
53 limit_set = True
54 except ValueError:
55 limit_set = False
Hai Shibb0424b2020-08-04 00:47:42 +080056 f = open(os_helper.TESTFN, "wb")
Thomas Woutersb2137042007-02-01 18:02:27 +000057 try:
Guido van Rossumb644fb42007-08-27 23:36:53 +000058 f.write(b"X" * 1024)
Guido van Rossum806c2462007-08-06 23:33:07 +000059 try:
Guido van Rossumb644fb42007-08-27 23:36:53 +000060 f.write(b"Y")
Guido van Rossum806c2462007-08-06 23:33:07 +000061 f.flush()
Christian Heimesaf98da12008-01-27 15:18:18 +000062 # On some systems (e.g., Ubuntu on hppa) the flush()
63 # doesn't always cause the exception, but the close()
Christian Heimes26855632008-01-27 23:50:43 +000064 # does eventually. Try flushing several times in
Christian Heimesaf98da12008-01-27 15:18:18 +000065 # an attempt to ensure the file is really synced and
66 # the exception raised.
67 for i in range(5):
Christian Heimes412dc9c2008-01-27 18:55:54 +000068 time.sleep(.1)
69 f.flush()
Andrew Svetlovf7a17b42012-12-25 16:47:37 +020070 except OSError:
Guido van Rossum806c2462007-08-06 23:33:07 +000071 if not limit_set:
72 raise
73 if limit_set:
74 # Close will attempt to flush the byte we wrote
75 # Restore limit first to avoid getting a spurious error
76 resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
77 finally:
78 f.close()
Thomas Woutersb2137042007-02-01 18:02:27 +000079 finally:
Guido van Rossum806c2462007-08-06 23:33:07 +000080 if limit_set:
81 resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
Hai Shibb0424b2020-08-04 00:47:42 +080082 os_helper.unlink(os_helper.TESTFN)
Thomas Woutersb2137042007-02-01 18:02:27 +000083
84 def test_fsize_toobig(self):
85 # Be sure that setrlimit is checking for really large values
86 too_big = 10**50
87 try:
88 (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
89 except AttributeError:
90 pass
91 else:
92 try:
93 resource.setrlimit(resource.RLIMIT_FSIZE, (too_big, max))
94 except (OverflowError, ValueError):
95 pass
96 try:
97 resource.setrlimit(resource.RLIMIT_FSIZE, (max, too_big))
98 except (OverflowError, ValueError):
99 pass
100
101 def test_getrusage(self):
102 self.assertRaises(TypeError, resource.getrusage)
103 self.assertRaises(TypeError, resource.getrusage, 42, 42)
104 usageself = resource.getrusage(resource.RUSAGE_SELF)
105 usagechildren = resource.getrusage(resource.RUSAGE_CHILDREN)
106 # May not be available on all systems.
107 try:
108 usageboth = resource.getrusage(resource.RUSAGE_BOTH)
109 except (ValueError, AttributeError):
110 pass
Antoine Pitroub6d4ee52010-11-17 16:19:35 +0000111 try:
112 usage_thread = resource.getrusage(resource.RUSAGE_THREAD)
113 except (ValueError, AttributeError):
114 pass
Thomas Woutersb2137042007-02-01 18:02:27 +0000115
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +0200116 # Issue 6083: Reference counting bug
Lihua Zhao693c1042019-04-17 23:41:33 +0800117 @unittest.skipIf(sys.platform == "vxworks",
118 "setting RLIMIT_CPU is not supported on VxWorks")
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +0200119 def test_setrusage_refcount(self):
120 try:
121 limits = resource.getrlimit(resource.RLIMIT_CPU)
122 except AttributeError:
123 pass
124 else:
125 class BadSequence:
126 def __len__(self):
127 return 2
128 def __getitem__(self, key):
129 if key in (0, 1):
130 return len(tuple(range(1000000)))
131 raise IndexError
132
133 resource.setrlimit(resource.RLIMIT_CPU, BadSequence())
134
Christian Heimes4ebc9292013-07-30 15:44:13 +0200135 def test_pagesize(self):
136 pagesize = resource.getpagesize()
137 self.assertIsInstance(pagesize, int)
138 self.assertGreaterEqual(pagesize, 0)
139
Christian Heimes6fc79bf2013-10-22 11:09:27 +0200140 @unittest.skipUnless(sys.platform == 'linux', 'test requires Linux')
141 def test_linux_constants(self):
Brett Cannona20800d2013-10-25 15:45:25 -0400142 for attr in ['MSGQUEUE', 'NICE', 'RTPRIO', 'RTTIME', 'SIGPENDING']:
143 with contextlib.suppress(AttributeError):
144 self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int)
Christian Heimes6fc79bf2013-10-22 11:09:27 +0200145
Christian Heimes5bb414d2013-12-08 14:35:55 +0100146 def test_freebsd_contants(self):
147 for attr in ['SWAP', 'SBSIZE', 'NPTS']:
148 with contextlib.suppress(AttributeError):
149 self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int)
150
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200151 @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit')
Christian Heimesc4a4b342013-10-25 08:31:19 +0200152 @support.requires_linux_version(2, 6, 36)
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200153 def test_prlimit(self):
154 self.assertRaises(TypeError, resource.prlimit)
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200155 self.assertRaises(ProcessLookupError, resource.prlimit,
156 -1, resource.RLIMIT_AS)
Christian Heimesd885aa42013-10-22 11:45:30 +0200157 limit = resource.getrlimit(resource.RLIMIT_AS)
158 self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS), limit)
159 self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, limit),
160 limit)
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200161
Serhiy Storchakab94eef22016-12-19 08:04:15 +0200162 # Issue 20191: Reference counting bug
163 @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit')
164 @support.requires_linux_version(2, 6, 36)
165 def test_prlimit_refcount(self):
166 class BadSeq:
167 def __len__(self):
168 return 2
169 def __getitem__(self, key):
170 return limits[key] - 1 # new reference
171
172 limits = resource.getrlimit(resource.RLIMIT_AS)
173 self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, BadSeq()),
174 limits)
175
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200176
Thomas Woutersb2137042007-02-01 18:02:27 +0000177def test_main(verbose=None):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000178 support.run_unittest(ResourceTest)
Thomas Woutersb2137042007-02-01 18:02:27 +0000179
180if __name__ == "__main__":
181 test_main()