@@ -14,91 +14,157 @@ 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 ))
36-
37- # TODO: RUSTPYTHON
38- @unittest .skip ("file size limit exceeded." )
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 ))
45+
46+ @unittest .skip ("TODO: RUSTPYTHON; crash" )
47+ @unittest .skipIf (sys .platform == "vxworks" ,
48+ "setting RLIMIT_FSIZE is not supported on VxWorks" )
49+ @unittest .skipUnless (hasattr (resource , 'RLIMIT_FSIZE' ), 'requires resource.RLIMIT_FSIZE' )
3950 def test_fsize_enforced (self ):
51+ (cur , max ) = resource .getrlimit (resource .RLIMIT_FSIZE )
52+ # Check to see what happens when the RLIMIT_FSIZE is small. Some
53+ # versions of Python were terminated by an uncaught SIGXFSZ, but
54+ # pythonrun.c has been fixed to ignore that exception. If so, the
55+ # write() should return EFBIG when the limit is exceeded.
56+
57+ # At least one platform has an unlimited RLIMIT_FSIZE and attempts
58+ # to change it raise ValueError instead.
4059 try :
41- (cur , max ) = resource .getrlimit (resource .RLIMIT_FSIZE )
42- except AttributeError :
43- pass
44- else :
45- # Check to see what happens when the RLIMIT_FSIZE is small. Some
46- # versions of Python were terminated by an uncaught SIGXFSZ, but
47- # pythonrun.c has been fixed to ignore that exception. If so, the
48- # write() should return EFBIG when the limit is exceeded.
49-
50- # At least one platform has an unlimited RLIMIT_FSIZE and attempts
51- # to change it raise ValueError instead.
5260 try :
61+ resource .setrlimit (resource .RLIMIT_FSIZE , (1024 , max ))
62+ limit_set = True
63+ except ValueError :
64+ limit_set = False
65+ f = open (os_helper .TESTFN , "wb" )
66+ try :
67+ f .write (b"X" * 1024 )
5368 try :
54- resource . setrlimit ( resource . RLIMIT_FSIZE , ( 1024 , max ) )
55- limit_set = True
56- except ValueError :
57- limit_set = False
58- f = open ( os_helper . TESTFN , "wb" )
59- try :
60- f . write ( b"X" * 1024 )
61- try :
62- f . write ( b"Y" )
69+ f . write ( b"Y" )
70+ f . flush ()
71+ # On some systems (e.g., Ubuntu on hppa) the flush()
72+ # doesn't always cause the exception, but the close()
73+ # does eventually. Try flushing several times in
74+ # an attempt to ensure the file is really synced and
75+ # the exception raised.
76+ for i in range ( 5 ) :
77+ time . sleep ( .1 )
6378 f .flush ()
64- # On some systems (e.g., Ubuntu on hppa) the flush()
65- # doesn't always cause the exception, but the close()
66- # does eventually. Try flushing several times in
67- # an attempt to ensure the file is really synced and
68- # the exception raised.
69- for i in range (5 ):
70- time .sleep (.1 )
71- f .flush ()
72- except OSError :
73- if not limit_set :
74- raise
75- if limit_set :
76- # Close will attempt to flush the byte we wrote
77- # Restore limit first to avoid getting a spurious error
78- resource .setrlimit (resource .RLIMIT_FSIZE , (cur , max ))
79- finally :
80- f .close ()
81- finally :
79+ except OSError :
80+ if not limit_set :
81+ raise
8282 if limit_set :
83+ # Close will attempt to flush the byte we wrote
84+ # Restore limit first to avoid getting a spurious error
8385 resource .setrlimit (resource .RLIMIT_FSIZE , (cur , max ))
84- os_helper .unlink (os_helper .TESTFN )
86+ finally :
87+ f .close ()
88+ finally :
89+ if limit_set :
90+ resource .setrlimit (resource .RLIMIT_FSIZE , (cur , max ))
91+ os_helper .unlink (os_helper .TESTFN )
8592
86- def test_fsize_toobig (self ):
93+ @unittest .skipIf (sys .platform == "vxworks" ,
94+ "setting RLIMIT_FSIZE is not supported on VxWorks" )
95+ @unittest .skipUnless (hasattr (resource , 'RLIMIT_FSIZE' ), 'requires resource.RLIMIT_FSIZE' )
96+ def test_fsize_too_big (self ):
8797 # Be sure that setrlimit is checking for really large values
8898 too_big = 10 ** 50
99+ (cur , max ) = resource .getrlimit (resource .RLIMIT_FSIZE )
100+ try :
101+ resource .setrlimit (resource .RLIMIT_FSIZE , (too_big , max ))
102+ except (OverflowError , ValueError ):
103+ pass
89104 try :
90- ( cur , max ) = resource .getrlimit (resource .RLIMIT_FSIZE )
91- except AttributeError :
105+ resource .setrlimit (resource .RLIMIT_FSIZE , ( max , too_big ) )
106+ except ( OverflowError , ValueError ) :
92107 pass
108+
109+ @unittest .skipIf (sys .platform == "darwin" , "TODO: RUSTPYTHON; crash" )
110+ @unittest .skipIf (sys .platform == "vxworks" ,
111+ "setting RLIMIT_FSIZE is not supported on VxWorks" )
112+ @unittest .skipUnless (hasattr (resource , 'RLIMIT_FSIZE' ), 'requires resource.RLIMIT_FSIZE' )
113+ def test_fsize_not_too_big (self ):
114+ (cur , max ) = resource .getrlimit (resource .RLIMIT_FSIZE )
115+ self .addCleanup (resource .setrlimit , resource .RLIMIT_FSIZE , (cur , max ))
116+
117+ def expected (cur ):
118+ if resource .RLIM_INFINITY < 0 :
119+ return [(cur , max ), (resource .RLIM_INFINITY , max )]
120+ elif resource .RLIM_INFINITY < cur :
121+ return [(resource .RLIM_INFINITY , max )]
122+ else :
123+ return [(cur , max )]
124+
125+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 31 - 5 , max ))
126+ self .assertEqual (resource .getrlimit (resource .RLIMIT_FSIZE ), (2 ** 31 - 5 , max ))
127+
128+ try :
129+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 32 , max ))
130+ except OverflowError :
131+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 31 , max ))
132+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ), expected (2 ** 31 ))
133+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 32 - 5 , max ))
134+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ), expected (2 ** 32 - 5 ))
93135 else :
136+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ), expected (2 ** 32 ))
137+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 31 , max ))
138+ self .assertEqual (resource .getrlimit (resource .RLIMIT_FSIZE ), (2 ** 31 , max ))
139+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 32 - 5 , max ))
140+ self .assertEqual (resource .getrlimit (resource .RLIMIT_FSIZE ), (2 ** 32 - 5 , max ))
141+
142+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 63 - 5 , max ))
143+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ), expected (2 ** 63 - 5 ))
94144 try :
95- resource .setrlimit (resource .RLIMIT_FSIZE , (too_big , max ))
96- except (OverflowError , ValueError ):
97- pass
98- try :
99- resource .setrlimit (resource .RLIMIT_FSIZE , (max , too_big ))
100- except (OverflowError , ValueError ):
145+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 63 , max ))
146+ except ValueError :
147+ # There is a hard limit on macOS.
101148 pass
149+ else :
150+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ), expected (2 ** 63 ))
151+ resource .setrlimit (resource .RLIMIT_FSIZE , (2 ** 64 - 5 , max ))
152+ self .assertIn (resource .getrlimit (resource .RLIMIT_FSIZE ), expected (2 ** 64 - 5 ))
153+
154+ @unittest .expectedFailure # TODO: RUSTPYTHON; OverflowError: Python int too large to convert to Rust u64
155+ @unittest .skipIf (sys .platform == "vxworks" ,
156+ "setting RLIMIT_FSIZE is not supported on VxWorks" )
157+ @unittest .skipUnless (hasattr (resource , 'RLIMIT_FSIZE' ), 'requires resource.RLIMIT_FSIZE' )
158+ def test_fsize_negative (self ):
159+ (cur , max ) = resource .getrlimit (resource .RLIMIT_FSIZE )
160+ for value in - 5 , - 2 ** 31 , - 2 ** 32 - 5 , - 2 ** 63 , - 2 ** 64 - 5 , - 2 ** 1000 :
161+ with self .subTest (value = value ):
162+ # This test assumes that the values don't map to RLIM_INFINITY,
163+ # though Posix doesn't guarantee it.
164+ self .assertNotEqual (value , resource .RLIM_INFINITY )
165+
166+ self .assertRaises (ValueError , resource .setrlimit , resource .RLIMIT_FSIZE , (value , max ))
167+ self .assertRaises (ValueError , resource .setrlimit , resource .RLIMIT_FSIZE , (cur , value ))
102168
103169 @unittest .skipUnless (hasattr (resource , "getrusage" ), "needs getrusage" )
104170 def test_getrusage (self ):
@@ -119,24 +185,20 @@ def test_getrusage(self):
119185 # Issue 6083: Reference counting bug
120186 @unittest .skipIf (sys .platform == "vxworks" ,
121187 "setting RLIMIT_CPU is not supported on VxWorks" )
188+ @unittest .skipUnless (hasattr (resource , 'RLIMIT_CPU' ), 'requires resource.RLIMIT_CPU' )
122189 def test_setrusage_refcount (self ):
123- try :
124- limits = resource .getrlimit (resource .RLIMIT_CPU )
125- except AttributeError :
126- pass
127- else :
128- class BadSequence :
129- def __len__ (self ):
130- return 2
131- def __getitem__ (self , key ):
132- if key in (0 , 1 ):
133- return len (tuple (range (1000000 )))
134- raise IndexError
135-
136- resource .setrlimit (resource .RLIMIT_CPU , BadSequence ())
137-
138- # TODO: RUSTPYTHON: module 'resource' has no attribute 'getpagesize'
139- @unittest .expectedFailure
190+ limits = resource .getrlimit (resource .RLIMIT_CPU )
191+ class BadSequence :
192+ def __len__ (self ):
193+ return 2
194+ def __getitem__ (self , key ):
195+ if key in (0 , 1 ):
196+ return len (tuple (range (1000000 )))
197+ raise IndexError
198+
199+ resource .setrlimit (resource .RLIMIT_CPU , BadSequence ())
200+
201+ @unittest .expectedFailure # TODO: RUSTPYTHON; module 'resource' has no attribute 'getpagesize'
140202 def test_pagesize (self ):
141203 pagesize = resource .getpagesize ()
142204 self .assertIsInstance (pagesize , int )
@@ -172,7 +234,8 @@ class BadSeq:
172234 def __len__ (self ):
173235 return 2
174236 def __getitem__ (self , key ):
175- return limits [key ] - 1 # new reference
237+ lim = limits [key ]
238+ return lim - 1 if lim > 0 else lim + sys .maxsize * 2 # new reference
176239
177240 limits = resource .getrlimit (resource .RLIMIT_AS )
178241 self .assertEqual (resource .prlimit (0 , resource .RLIMIT_AS , BadSeq ()),
0 commit comments