blob: e5ece5284cf15ba9f75e5e531a09f8c6088aa8d4 [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
Christian Heimes412dc9c2008-01-27 18:55:54 +00005import time
Jeremy Hylton74ce77f2002-04-23 20:21:22 +00006
R. David Murraya21e4ca2009-03-31 23:16:50 +00007resource = support.import_module('resource')
8
Thomas Woutersb2137042007-02-01 18:02:27 +00009# This test is checking a few specific problem spots with the resource module.
Jeremy Hylton74ce77f2002-04-23 20:21:22 +000010
Thomas Woutersb2137042007-02-01 18:02:27 +000011class ResourceTest(unittest.TestCase):
Jeremy Hylton74ce77f2002-04-23 20:21:22 +000012
Thomas Woutersb2137042007-02-01 18:02:27 +000013 def test_args(self):
14 self.assertRaises(TypeError, resource.getrlimit)
15 self.assertRaises(TypeError, resource.getrlimit, 42, 42)
16 self.assertRaises(TypeError, resource.setrlimit)
17 self.assertRaises(TypeError, resource.setrlimit, 42, 42, 42)
Jason Tishlere4a070a2002-12-12 18:13:36 +000018
Lihua Zhao693c1042019-04-17 23:41:33 +080019 @unittest.skipIf(sys.platform == "vxworks",
20 "setting RLIMIT_FSIZE is not supported on VxWorks")
Thomas Woutersb2137042007-02-01 18:02:27 +000021 def test_fsize_ismax(self):
Thomas Woutersb2137042007-02-01 18:02:27 +000022 try:
23 (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
24 except AttributeError:
25 pass
26 else:
27 # RLIMIT_FSIZE should be RLIM_INFINITY, which will be a really big
28 # number on a platform with large file support. On these platforms,
29 # we need to test that the get/setrlimit functions properly convert
30 # the number to a C long long and that the conversion doesn't raise
31 # an error.
32 self.assertEqual(resource.RLIM_INFINITY, max)
33 resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
Jeremy Hylton74ce77f2002-04-23 20:21:22 +000034
Thomas Woutersb2137042007-02-01 18:02:27 +000035 def test_fsize_enforced(self):
36 try:
37 (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
38 except AttributeError:
39 pass
40 else:
41 # Check to see what happens when the RLIMIT_FSIZE is small. Some
42 # versions of Python were terminated by an uncaught SIGXFSZ, but
43 # pythonrun.c has been fixed to ignore that exception. If so, the
44 # write() should return EFBIG when the limit is exceeded.
Thomas Wouters9fe394c2007-02-05 01:24:16 +000045
Thomas Woutersb2137042007-02-01 18:02:27 +000046 # At least one platform has an unlimited RLIMIT_FSIZE and attempts
47 # to change it raise ValueError instead.
48 try:
49 try:
50 resource.setrlimit(resource.RLIMIT_FSIZE, (1024, max))
51 limit_set = True
52 except ValueError:
53 limit_set = False
Benjamin Petersonee8712c2008-05-20 21:35:26 +000054 f = open(support.TESTFN, "wb")
Thomas Woutersb2137042007-02-01 18:02:27 +000055 try:
Guido van Rossumb644fb42007-08-27 23:36:53 +000056 f.write(b"X" * 1024)
Guido van Rossum806c2462007-08-06 23:33:07 +000057 try:
Guido van Rossumb644fb42007-08-27 23:36:53 +000058 f.write(b"Y")
Guido van Rossum806c2462007-08-06 23:33:07 +000059 f.flush()
Christian Heimesaf98da12008-01-27 15:18:18 +000060 # On some systems (e.g., Ubuntu on hppa) the flush()
61 # doesn't always cause the exception, but the close()
Christian Heimes26855632008-01-27 23:50:43 +000062 # does eventually. Try flushing several times in
Christian Heimesaf98da12008-01-27 15:18:18 +000063 # an attempt to ensure the file is really synced and
64 # the exception raised.
65 for i in range(5):
Christian Heimes412dc9c2008-01-27 18:55:54 +000066 time.sleep(.1)
67 f.flush()
Andrew Svetlovf7a17b42012-12-25 16:47:37 +020068 except OSError:
Guido van Rossum806c2462007-08-06 23:33:07 +000069 if not limit_set:
70 raise
71 if limit_set:
72 # Close will attempt to flush the byte we wrote
73 # Restore limit first to avoid getting a spurious error
74 resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
75 finally:
76 f.close()
Thomas Woutersb2137042007-02-01 18:02:27 +000077 finally:
Guido van Rossum806c2462007-08-06 23:33:07 +000078 if limit_set:
79 resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000080 support.unlink(support.TESTFN)
Thomas Woutersb2137042007-02-01 18:02:27 +000081
82 def test_fsize_toobig(self):
83 # Be sure that setrlimit is checking for really large values
84 too_big = 10**50
85 try:
86 (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
87 except AttributeError:
88 pass
89 else:
90 try:
91 resource.setrlimit(resource.RLIMIT_FSIZE, (too_big, max))
92 except (OverflowError, ValueError):
93 pass
94 try:
95 resource.setrlimit(resource.RLIMIT_FSIZE, (max, too_big))
96 except (OverflowError, ValueError):
97 pass
98
99 def test_getrusage(self):
100 self.assertRaises(TypeError, resource.getrusage)
101 self.assertRaises(TypeError, resource.getrusage, 42, 42)
102 usageself = resource.getrusage(resource.RUSAGE_SELF)
103 usagechildren = resource.getrusage(resource.RUSAGE_CHILDREN)
104 # May not be available on all systems.
105 try:
106 usageboth = resource.getrusage(resource.RUSAGE_BOTH)
107 except (ValueError, AttributeError):
108 pass
Antoine Pitroub6d4ee52010-11-17 16:19:35 +0000109 try:
110 usage_thread = resource.getrusage(resource.RUSAGE_THREAD)
111 except (ValueError, AttributeError):
112 pass
Thomas Woutersb2137042007-02-01 18:02:27 +0000113
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +0200114 # Issue 6083: Reference counting bug
Lihua Zhao693c1042019-04-17 23:41:33 +0800115 @unittest.skipIf(sys.platform == "vxworks",
116 "setting RLIMIT_CPU is not supported on VxWorks")
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +0200117 def test_setrusage_refcount(self):
118 try:
119 limits = resource.getrlimit(resource.RLIMIT_CPU)
120 except AttributeError:
121 pass
122 else:
123 class BadSequence:
124 def __len__(self):
125 return 2
126 def __getitem__(self, key):
127 if key in (0, 1):
128 return len(tuple(range(1000000)))
129 raise IndexError
130
131 resource.setrlimit(resource.RLIMIT_CPU, BadSequence())
132
Christian Heimes4ebc9292013-07-30 15:44:13 +0200133 def test_pagesize(self):
134 pagesize = resource.getpagesize()
135 self.assertIsInstance(pagesize, int)
136 self.assertGreaterEqual(pagesize, 0)
137
Christian Heimes6fc79bf2013-10-22 11:09:27 +0200138 @unittest.skipUnless(sys.platform == 'linux', 'test requires Linux')
139 def test_linux_constants(self):
Brett Cannona20800d2013-10-25 15:45:25 -0400140 for attr in ['MSGQUEUE', 'NICE', 'RTPRIO', 'RTTIME', 'SIGPENDING']:
141 with contextlib.suppress(AttributeError):
142 self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int)
Christian Heimes6fc79bf2013-10-22 11:09:27 +0200143
Christian Heimes5bb414d2013-12-08 14:35:55 +0100144 def test_freebsd_contants(self):
145 for attr in ['SWAP', 'SBSIZE', 'NPTS']:
146 with contextlib.suppress(AttributeError):
147 self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int)
148
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200149 @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit')
Christian Heimesc4a4b342013-10-25 08:31:19 +0200150 @support.requires_linux_version(2, 6, 36)
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200151 def test_prlimit(self):
152 self.assertRaises(TypeError, resource.prlimit)
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200153 self.assertRaises(ProcessLookupError, resource.prlimit,
154 -1, resource.RLIMIT_AS)
Christian Heimesd885aa42013-10-22 11:45:30 +0200155 limit = resource.getrlimit(resource.RLIMIT_AS)
156 self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS), limit)
157 self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, limit),
158 limit)
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200159
Serhiy Storchakab94eef22016-12-19 08:04:15 +0200160 # Issue 20191: Reference counting bug
161 @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit')
162 @support.requires_linux_version(2, 6, 36)
163 def test_prlimit_refcount(self):
164 class BadSeq:
165 def __len__(self):
166 return 2
167 def __getitem__(self, key):
168 return limits[key] - 1 # new reference
169
170 limits = resource.getrlimit(resource.RLIMIT_AS)
171 self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, BadSeq()),
172 limits)
173
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200174
Thomas Woutersb2137042007-02-01 18:02:27 +0000175def test_main(verbose=None):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000176 support.run_unittest(ResourceTest)
Thomas Woutersb2137042007-02-01 18:02:27 +0000177
178if __name__ == "__main__":
179 test_main()