blob: 62c7963fe6999f2a58529067d4d5a050655e6879 [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
Thomas Woutersb2137042007-02-01 18:02:27 +000019 def test_fsize_ismax(self):
Thomas Woutersb2137042007-02-01 18:02:27 +000020 try:
21 (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
22 except AttributeError:
23 pass
24 else:
25 # RLIMIT_FSIZE should be RLIM_INFINITY, which will be a really big
26 # number on a platform with large file support. On these platforms,
27 # we need to test that the get/setrlimit functions properly convert
28 # the number to a C long long and that the conversion doesn't raise
29 # an error.
30 self.assertEqual(resource.RLIM_INFINITY, max)
31 resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
Jeremy Hylton74ce77f2002-04-23 20:21:22 +000032
Thomas Woutersb2137042007-02-01 18:02:27 +000033 def test_fsize_enforced(self):
34 try:
35 (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
36 except AttributeError:
37 pass
38 else:
39 # Check to see what happens when the RLIMIT_FSIZE is small. Some
40 # versions of Python were terminated by an uncaught SIGXFSZ, but
41 # pythonrun.c has been fixed to ignore that exception. If so, the
42 # write() should return EFBIG when the limit is exceeded.
Thomas Wouters9fe394c2007-02-05 01:24:16 +000043
Thomas Woutersb2137042007-02-01 18:02:27 +000044 # At least one platform has an unlimited RLIMIT_FSIZE and attempts
45 # to change it raise ValueError instead.
46 try:
47 try:
48 resource.setrlimit(resource.RLIMIT_FSIZE, (1024, max))
49 limit_set = True
50 except ValueError:
51 limit_set = False
Benjamin Petersonee8712c2008-05-20 21:35:26 +000052 f = open(support.TESTFN, "wb")
Thomas Woutersb2137042007-02-01 18:02:27 +000053 try:
Guido van Rossumb644fb42007-08-27 23:36:53 +000054 f.write(b"X" * 1024)
Guido van Rossum806c2462007-08-06 23:33:07 +000055 try:
Guido van Rossumb644fb42007-08-27 23:36:53 +000056 f.write(b"Y")
Guido van Rossum806c2462007-08-06 23:33:07 +000057 f.flush()
Christian Heimesaf98da12008-01-27 15:18:18 +000058 # On some systems (e.g., Ubuntu on hppa) the flush()
59 # doesn't always cause the exception, but the close()
Christian Heimes26855632008-01-27 23:50:43 +000060 # does eventually. Try flushing several times in
Christian Heimesaf98da12008-01-27 15:18:18 +000061 # an attempt to ensure the file is really synced and
62 # the exception raised.
63 for i in range(5):
Christian Heimes412dc9c2008-01-27 18:55:54 +000064 time.sleep(.1)
65 f.flush()
Andrew Svetlovf7a17b42012-12-25 16:47:37 +020066 except OSError:
Guido van Rossum806c2462007-08-06 23:33:07 +000067 if not limit_set:
68 raise
69 if limit_set:
70 # Close will attempt to flush the byte we wrote
71 # Restore limit first to avoid getting a spurious error
72 resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
73 finally:
74 f.close()
Thomas Woutersb2137042007-02-01 18:02:27 +000075 finally:
Guido van Rossum806c2462007-08-06 23:33:07 +000076 if limit_set:
77 resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000078 support.unlink(support.TESTFN)
Thomas Woutersb2137042007-02-01 18:02:27 +000079
80 def test_fsize_toobig(self):
81 # Be sure that setrlimit is checking for really large values
82 too_big = 10**50
83 try:
84 (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
85 except AttributeError:
86 pass
87 else:
88 try:
89 resource.setrlimit(resource.RLIMIT_FSIZE, (too_big, max))
90 except (OverflowError, ValueError):
91 pass
92 try:
93 resource.setrlimit(resource.RLIMIT_FSIZE, (max, too_big))
94 except (OverflowError, ValueError):
95 pass
96
97 def test_getrusage(self):
98 self.assertRaises(TypeError, resource.getrusage)
99 self.assertRaises(TypeError, resource.getrusage, 42, 42)
100 usageself = resource.getrusage(resource.RUSAGE_SELF)
101 usagechildren = resource.getrusage(resource.RUSAGE_CHILDREN)
102 # May not be available on all systems.
103 try:
104 usageboth = resource.getrusage(resource.RUSAGE_BOTH)
105 except (ValueError, AttributeError):
106 pass
Antoine Pitroub6d4ee52010-11-17 16:19:35 +0000107 try:
108 usage_thread = resource.getrusage(resource.RUSAGE_THREAD)
109 except (ValueError, AttributeError):
110 pass
Thomas Woutersb2137042007-02-01 18:02:27 +0000111
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +0200112 # Issue 6083: Reference counting bug
113 def test_setrusage_refcount(self):
114 try:
115 limits = resource.getrlimit(resource.RLIMIT_CPU)
116 except AttributeError:
117 pass
118 else:
119 class BadSequence:
120 def __len__(self):
121 return 2
122 def __getitem__(self, key):
123 if key in (0, 1):
124 return len(tuple(range(1000000)))
125 raise IndexError
126
127 resource.setrlimit(resource.RLIMIT_CPU, BadSequence())
128
Christian Heimes4ebc9292013-07-30 15:44:13 +0200129 def test_pagesize(self):
130 pagesize = resource.getpagesize()
131 self.assertIsInstance(pagesize, int)
132 self.assertGreaterEqual(pagesize, 0)
133
Christian Heimes6fc79bf2013-10-22 11:09:27 +0200134 @unittest.skipUnless(sys.platform == 'linux', 'test requires Linux')
135 def test_linux_constants(self):
Brett Cannona20800d2013-10-25 15:45:25 -0400136 for attr in ['MSGQUEUE', 'NICE', 'RTPRIO', 'RTTIME', 'SIGPENDING']:
137 with contextlib.suppress(AttributeError):
138 self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int)
Christian Heimes6fc79bf2013-10-22 11:09:27 +0200139
Christian Heimes5bb414d2013-12-08 14:35:55 +0100140 def test_freebsd_contants(self):
141 for attr in ['SWAP', 'SBSIZE', 'NPTS']:
142 with contextlib.suppress(AttributeError):
143 self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int)
144
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200145 @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit')
Christian Heimesc4a4b342013-10-25 08:31:19 +0200146 @support.requires_linux_version(2, 6, 36)
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200147 def test_prlimit(self):
148 self.assertRaises(TypeError, resource.prlimit)
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200149 self.assertRaises(ProcessLookupError, resource.prlimit,
150 -1, resource.RLIMIT_AS)
Christian Heimesd885aa42013-10-22 11:45:30 +0200151 limit = resource.getrlimit(resource.RLIMIT_AS)
152 self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS), limit)
153 self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, limit),
154 limit)
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200155
Serhiy Storchakab94eef22016-12-19 08:04:15 +0200156 # Issue 20191: Reference counting bug
157 @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit')
158 @support.requires_linux_version(2, 6, 36)
159 def test_prlimit_refcount(self):
160 class BadSeq:
161 def __len__(self):
162 return 2
163 def __getitem__(self, key):
164 return limits[key] - 1 # new reference
165
166 limits = resource.getrlimit(resource.RLIMIT_AS)
167 self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, BadSeq()),
168 limits)
169
Christian Heimesb7bd5df2013-10-22 11:21:54 +0200170
Thomas Woutersb2137042007-02-01 18:02:27 +0000171def test_main(verbose=None):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000172 support.run_unittest(ResourceTest)
Thomas Woutersb2137042007-02-01 18:02:27 +0000173
174if __name__ == "__main__":
175 test_main()