@@ -14,89 +14,154 @@ class ResourceTest(unittest.TestCase):
1414
1515def test_args (self ):
1616self .assertRaises (TypeError ,resource .getrlimit )
17- self .assertRaises (TypeError ,resource .getrlimit ,42 ,42 )
17+ self .assertRaises (TypeError ,resource .getrlimit ,0 ,42 )
18+ self .assertRaises (OverflowError ,resource .getrlimit ,2 ** 1000 )
19+ self .assertRaises (OverflowError ,resource .getrlimit ,- 2 ** 1000 )
20+ self .assertRaises (TypeError ,resource .getrlimit ,'0' )
1821self .assertRaises (TypeError ,resource .setrlimit )
19- self .assertRaises (TypeError ,resource .setrlimit ,42 ,42 ,42 )
22+ self .assertRaises (TypeError ,resource .setrlimit ,0 )
23+ self .assertRaises (TypeError ,resource .setrlimit ,0 ,42 )
24+ self .assertRaises (TypeError ,resource .setrlimit ,0 ,42 ,42 )
25+ self .assertRaises (OverflowError ,resource .setrlimit ,2 ** 1000 , (42 ,42 ))
26+ self .assertRaises (OverflowError ,resource .setrlimit ,- 2 ** 1000 , (42 ,42 ))
27+ self .assertRaises (ValueError ,resource .setrlimit ,0 , (42 ,))
28+ self .assertRaises (ValueError ,resource .setrlimit ,0 , (42 ,42 ,42 ))
29+ self .assertRaises (TypeError ,resource .setrlimit ,'0' , (42 ,42 ))
30+ self .assertRaises (TypeError ,resource .setrlimit ,0 , ('42' ,42 ))
31+ self .assertRaises (TypeError ,resource .setrlimit ,0 , (42 ,'42' ))
2032
2133@unittest .skipIf (sys .platform == "vxworks" ,
2234"setting RLIMIT_FSIZE is not supported on VxWorks" )
35+ @unittest .skipUnless (hasattr (resource ,'RLIMIT_FSIZE' ),'requires resource.RLIMIT_FSIZE' )
2336def test_fsize_ismax (self ):
24- 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 ))
37+ (cur ,max )= resource .getrlimit (resource .RLIMIT_FSIZE )
38+ # RLIMIT_FSIZE should be RLIM_INFINITY, which will be a really big
39+ # number on a platform with large file support. On these platforms,
40+ # we need to test that the get/setrlimit functions properly convert
41+ # the number to a C long long and that the conversion doesn't raise
42+ # an error.
43+ self .assertEqual (resource .RLIM_INFINITY ,max )
44+ resource .setrlimit (resource .RLIMIT_FSIZE , (cur ,max ))
3645
46+ @unittest .skipIf (sys .platform == "vxworks" ,
47+ "setting RLIMIT_FSIZE is not supported on VxWorks" )
48+ @unittest .skipUnless (hasattr (resource ,'RLIMIT_FSIZE' ),'requires resource.RLIMIT_FSIZE' )
3749def test_fsize_enforced (self ):
50+ (cur ,max )= resource .getrlimit (resource .RLIMIT_FSIZE )
51+ # Check to see what happens when the RLIMIT_FSIZE is small. Some
52+ # versions of Python were terminated by an uncaught SIGXFSZ, but
53+ # pythonrun.c has been fixed to ignore that exception. If so, the
54+ # write() should return EFBIG when the limit is exceeded.
55+
56+ # At least one platform has an unlimited RLIMIT_FSIZE and attempts
57+ # to change it raise ValueError instead.
3858try :
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.
47-
48- # At least one platform has an unlimited RLIMIT_FSIZE and attempts
49- # to change it raise ValueError instead.
5059try :
60+ resource .setrlimit (resource .RLIMIT_FSIZE , (1024 ,max ))
61+ limit_set = True
62+ except ValueError :
63+ limit_set = False
64+ f = open (os_helper .TESTFN ,"wb" )
65+ try :
66+ f .write (b"X" * 1024 )
5167try :
52- resource . setrlimit ( resource . RLIMIT_FSIZE , ( 1024 , max ) )
53- limit_set = True
54- except ValueError :
55- limit_set = False
56- f = open ( os_helper . TESTFN , "wb" )
57- try :
58- f . write ( b"X" * 1024 )
59- try :
60- f . write ( b"Y" )
68+ f . write ( b"Y" )
69+ f . flush ()
70+ # On some systems (e.g., Ubuntu on hppa) the flush()
71+ # doesn't always cause the exception, but the close()
72+ # does eventually. Try flushing several times in
73+ # an attempt to ensure the file is really synced and
74+ # the exception raised.
75+ for i in range ( 5 ) :
76+ time . sleep ( .1 )
6177f .flush ()
62- # On some systems (e.g., Ubuntu on hppa) the flush()
63- # doesn't always cause the exception, but the close()
64- # does eventually. Try flushing several times in
65- # an attempt to ensure the file is really synced and
66- # the exception raised.
67- for i in range (5 ):
68- time .sleep (.1 )
69- f .flush ()
70- except OSError :
71- 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 ()
79- finally :
78+ except OSError :
79+ if not limit_set :
80+ raise
8081if limit_set :
82+ # Close will attempt to flush the byte we wrote
83+ # Restore limit first to avoid getting a spurious error
8184resource .setrlimit (resource .RLIMIT_FSIZE , (cur ,max ))
82- os_helper .unlink (os_helper .TESTFN )
85+ finally :
86+ f .close ()
87+ finally :
88+ if limit_set :
89+ resource .setrlimit (resource .RLIMIT_FSIZE , (cur ,max ))
90+ os_helper .unlink (os_helper .TESTFN )
8391
84- def test_fsize_toobig (self ):
92+ @unittest .skipIf (sys .platform == "vxworks" ,
93+ "setting RLIMIT_FSIZE is not supported on VxWorks" )
94+ @unittest .skipUnless (hasattr (resource ,'RLIMIT_FSIZE' ),'requires resource.RLIMIT_FSIZE' )
95+ def test_fsize_too_big (self ):
8596# Be sure that setrlimit is checking for really large values
8697too_big = 10 ** 50
98+ (cur ,max )= resource .getrlimit (resource .RLIMIT_FSIZE )
99+ try :
100+ resource .setrlimit (resource .RLIMIT_FSIZE , (too_big ,max ))
101+ except (OverflowError ,ValueError ):
102+ pass
87103try :
88- ( cur , max ) = resource .getrlimit (resource .RLIMIT_FSIZE )
89- except AttributeError :
104+ resource .setrlimit (resource .RLIMIT_FSIZE , ( max , too_big ) )
105+ except ( OverflowError , ValueError ) :
90106pass
107+
108+ @unittest .skipIf (sys .platform == "vxworks" ,
109+ "setting RLIMIT_FSIZE is not supported on VxWorks" )
110+ @unittest .skipUnless (hasattr (resource ,'RLIMIT_FSIZE' ),'requires resource.RLIMIT_FSIZE' )
111+ def test_fsize_not_too_big (self ):
112+ (cur ,max )= resource .getrlimit (resource .RLIMIT_FSIZE )
113+ self .addCleanup (resource .setrlimit ,resource .RLIMIT_FSIZE , (cur ,max ))
114+
115+ def expected (cur ):
116+ if resource .RLIM_INFINITY < 0 :
117+ return [(cur ,max ), (resource .RLIM_INFINITY ,max )]
118+ elif resource .RLIM_INFINITY < cur :
119+ return [(resource .RLIM_INFINITY ,max )]
120+ else :
121+ return [(cur ,max )]
122+
123+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 31 - 5 ,max ))
124+ self .assertEqual (resource .getrlimit (resource .RLIMIT_FSIZE ), (2 ** 31 - 5 ,max ))
125+
126+ try :
127+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 32 ,max ))
128+ except OverflowError :
129+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 31 ,max ))
130+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ),expected (2 ** 31 ))
131+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 32 - 5 ,max ))
132+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ),expected (2 ** 32 - 5 ))
91133else :
134+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ),expected (2 ** 32 ))
135+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 31 ,max ))
136+ self .assertEqual (resource .getrlimit (resource .RLIMIT_FSIZE ), (2 ** 31 ,max ))
137+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 32 - 5 ,max ))
138+ self .assertEqual (resource .getrlimit (resource .RLIMIT_FSIZE ), (2 ** 32 - 5 ,max ))
139+
140+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 63 - 5 ,max ))
141+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ),expected (2 ** 63 - 5 ))
92142try :
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 ):
143+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 63 ,max ))
144+ except ValueError :
145+ # There is a hard limit on macOS.
99146pass
147+ else :
148+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ),expected (2 ** 63 ))
149+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 64 - 5 ,max ))
150+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ),expected (2 ** 64 - 5 ))
151+
152+ @unittest .skipIf (sys .platform == "vxworks" ,
153+ "setting RLIMIT_FSIZE is not supported on VxWorks" )
154+ @unittest .skipUnless (hasattr (resource ,'RLIMIT_FSIZE' ),'requires resource.RLIMIT_FSIZE' )
155+ def test_fsize_negative (self ):
156+ (cur ,max )= resource .getrlimit (resource .RLIMIT_FSIZE )
157+ for value in - 5 ,- 2 ** 31 ,- 2 ** 32 - 5 ,- 2 ** 63 ,- 2 ** 64 - 5 ,- 2 ** 1000 :
158+ with self .subTest (value = value ):
159+ # This test assumes that the values don't map to RLIM_INFINITY,
160+ # though Posix doesn't guarantee it.
161+ self .assertNotEqual (value ,resource .RLIM_INFINITY )
162+
163+ self .assertRaises (ValueError ,resource .setrlimit ,resource .RLIMIT_FSIZE , (value ,max ))
164+ self .assertRaises (ValueError ,resource .setrlimit ,resource .RLIMIT_FSIZE , (cur ,value ))
100165
101166@unittest .skipUnless (hasattr (resource ,"getrusage" ),"needs getrusage" )
102167def test_getrusage (self ):
@@ -117,21 +182,18 @@ def test_getrusage(self):
117182# Issue 6083: Reference counting bug
118183@unittest .skipIf (sys .platform == "vxworks" ,
119184"setting RLIMIT_CPU is not supported on VxWorks" )
185+ @unittest .skipUnless (hasattr (resource ,'RLIMIT_CPU' ),'requires resource.RLIMIT_CPU' )
120186def test_setrusage_refcount (self ):
121- try :
122- limits = resource .getrlimit (resource .RLIMIT_CPU )
123- except AttributeError :
124- pass
125- else :
126- class BadSequence :
127- def __len__ (self ):
128- return 2
129- def __getitem__ (self ,key ):
130- if key in (0 ,1 ):
131- return len (tuple (range (1000000 )))
132- raise IndexError
187+ limits = resource .getrlimit (resource .RLIMIT_CPU )
188+ class BadSequence :
189+ def __len__ (self ):
190+ return 2
191+ def __getitem__ (self ,key ):
192+ if key in (0 ,1 ):
193+ return len (tuple (range (1000000 )))
194+ raise IndexError
133195
134- resource .setrlimit (resource .RLIMIT_CPU ,BadSequence ())
196+ resource .setrlimit (resource .RLIMIT_CPU ,BadSequence ())
135197
136198def test_pagesize (self ):
137199pagesize = resource .getpagesize ()
@@ -168,7 +230,8 @@ class BadSeq:
168230def __len__ (self ):
169231return 2
170232def __getitem__ (self ,key ):
171- return limits [key ]- 1 # new reference
233+ lim = limits [key ]
234+ return lim - 1 if lim > 0 else lim + sys .maxsize * 2 # new reference
172235
173236limits = resource .getrlimit (resource .RLIMIT_AS )
174237self .assertEqual (resource .prlimit (0 ,resource .RLIMIT_AS ,BadSeq ()),