1
"""Test largefile support on system where this makes sense.
8
from test.support import run_unittest, TESTFN, verbose, requires, \
10
import io # C implementation of io
11
import _pyio as pyio # Python implementation of io
15
# The default handler for SIGXFSZ is to abort the process.
16
# By ignoring it, system calls exceeding the file size resource
17
# limit will raise IOError instead of crashing the interpreter.
18
oldhandler = signal.signal(signal.SIGXFSZ, signal.SIG_IGN)
19
except (ImportError, AttributeError):
22
# create >2GB file (2GB = 2147483648 bytes)
26
class LargeFileTest(unittest.TestCase):
27
"""Test that each file function works as expected for a large
28
(i.e. > 2GB, do we have to check > 4GB) files.
30
NOTE: the order of execution of the test methods is important! test_seek
31
must run first to create the test file. File cleanup must also be handled
32
outside the test instances because of this.
38
print('create large file via seek (may be sparse file) ...')
39
with self.open(TESTFN, 'wb') as f:
46
print('check file size with os.fstat')
47
self.assertEqual(os.fstat(f.fileno())[stat.ST_SIZE], size+1)
49
def test_osstat(self):
51
print('check file size with os.stat')
52
self.assertEqual(os.stat(TESTFN)[stat.ST_SIZE], size+1)
54
def test_seek_read(self):
56
print('play around with seek() and read() with the built largefile')
57
with self.open(TESTFN, 'rb') as f:
58
self.assertEqual(f.tell(), 0)
59
self.assertEqual(f.read(1), b'z')
60
self.assertEqual(f.tell(), 1)
62
self.assertEqual(f.tell(), 0)
64
self.assertEqual(f.tell(), 0)
66
self.assertEqual(f.tell(), 42)
68
self.assertEqual(f.tell(), 42)
70
self.assertEqual(f.tell(), 84)
72
self.assertEqual(f.tell(), 84)
73
f.seek(0, 2) # seek from the end
74
self.assertEqual(f.tell(), size + 1 + 0)
76
self.assertEqual(f.tell(), size + 1 - 10)
78
self.assertEqual(f.tell(), 0)
80
self.assertEqual(f.tell(), size)
81
# the 'a' that was written at the end of file above
82
self.assertEqual(f.read(1), b'a')
84
self.assertEqual(f.read(1), b'z')
85
self.assertEqual(f.tell(), 1)
89
print('play around with os.lseek() with the built largefile')
90
with self.open(TESTFN, 'rb') as f:
91
self.assertEqual(os.lseek(f.fileno(), 0, 0), 0)
92
self.assertEqual(os.lseek(f.fileno(), 42, 0), 42)
93
self.assertEqual(os.lseek(f.fileno(), 42, 1), 84)
94
self.assertEqual(os.lseek(f.fileno(), 0, 1), 84)
95
self.assertEqual(os.lseek(f.fileno(), 0, 2), size+1+0)
96
self.assertEqual(os.lseek(f.fileno(), -10, 2), size+1-10)
97
self.assertEqual(os.lseek(f.fileno(), -size-1, 2), 0)
98
self.assertEqual(os.lseek(f.fileno(), size, 0), size)
99
# the 'a' that was written at the end of file above
100
self.assertEqual(f.read(1), b'a')
102
def test_truncate(self):
104
print('try truncate')
105
with self.open(TESTFN, 'r+b') as f:
106
# this is already decided before start running the test suite
107
# but we do it anyway for extra protection
108
if not hasattr(f, 'truncate'):
109
raise TestSkipped("open().truncate() not available on this system")
111
# else we've lost track of the true size
112
self.assertEqual(f.tell(), size+1)
113
# Cut it back via seek + truncate with no argument.
117
self.assertEqual(f.tell(), newsize) # else pointer moved
119
self.assertEqual(f.tell(), newsize) # else wasn't truncated
120
# Ensure that truncate(smaller than true size) shrinks
125
self.assertEqual(f.tell(), newsize) # else wasn't truncated
127
self.assertEqual(f.tell(), newsize)
128
# XXX truncate(larger than true size) is ill-defined
129
# across platform; cut it waaaaay back
132
self.assertEqual(f.tell(), 1) # else pointer moved
134
self.assertEqual(len(f.read()), 1) # else wasn't truncated
136
def test_seekable(self):
137
# Issue #5016; seekable() can return False when the current position
138
# is negative when truncated to an int.
139
for pos in (2**31-1, 2**31, 2**31+1):
140
with self.open(TESTFN, 'rb') as f:
142
self.assert_(f.seekable())
146
# On Windows and Mac OSX this test comsumes large resources; It
147
# takes a long time to build the >2GB file and takes >2GB of disk
148
# space therefore the resource must be enabled to run this test.
149
# If not, nothing after this line stanza will be executed.
150
if sys.platform[:3] == 'win' or sys.platform == 'darwin':
151
requires('largefile',
152
'test requires %s bytes and a long time to run' % str(size))
154
# Only run if the current filesystem supports large files.
155
# (Skip this test on Windows, since we now always support
157
f = open(TESTFN, 'wb', buffering=0)
159
# 2**31 == 2147483648
161
# Seeking is not enough of a test: you must write and
165
except (IOError, OverflowError):
168
raise TestSkipped("filesystem does not have largefile support")
171
suite = unittest.TestSuite()
172
for _open, prefix in [(io.open, 'C'), (pyio.open, 'Py')]:
173
class TestCase(LargeFileTest):
175
TestCase.open = staticmethod(_open)
176
TestCase.__name__ = prefix + LargeFileTest.__name__
177
suite.addTest(TestCase('test_seek'))
178
suite.addTest(TestCase('test_osstat'))
179
suite.addTest(TestCase('test_seek_read'))
180
suite.addTest(TestCase('test_lseek'))
181
with _open(TESTFN, 'wb') as f:
182
if hasattr(f, 'truncate'):
183
suite.addTest(TestCase('test_truncate'))
184
suite.addTest(TestCase('test_seekable'))
191
if __name__ == '__main__':