@@ -14,89 +14,154 @@ class ResourceTest(unittest.TestCase):
1414
1515 def test_args (self ):
1616 self .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' )
1821 self .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' )
2336 def 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' )
3749 def 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.
3858 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.
47-
48- # At least one platform has an unlimited RLIMIT_FSIZE and attempts
49- # to change it raise ValueError instead.
5059 try :
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 )
5167 try :
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 )
6177 f .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
8081 if limit_set :
82+ # Close will attempt to flush the byte we wrote
83+ # Restore limit first to avoid getting a spurious error
8184 resource .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
8697 too_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
87103 try :
88- ( cur , max ) = resource .getrlimit (resource .RLIMIT_FSIZE )
89- except AttributeError :
104+ resource .setrlimit (resource .RLIMIT_FSIZE , ( max , too_big ) )
105+ except ( OverflowError , ValueError ) :
90106 pass
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 ))
91133 else :
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 ))
92142 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 ):
143+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 63 , max ))
144+ except ValueError :
145+ # There is a hard limit on macOS.
99146 pass
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" )
102167 def 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' )
120186 def 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
136198 def test_pagesize (self ):
137199 pagesize = resource .getpagesize ()
@@ -168,7 +230,8 @@ class BadSeq:
168230 def __len__ (self ):
169231 return 2
170232 def __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
173236 limits = resource .getrlimit (resource .RLIMIT_AS )
174237 self .assertEqual (resource .prlimit (0 , resource .RLIMIT_AS , BadSeq ()),
0 commit comments