1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
#!python
#----------------------------------------------------------------------
# test largefile support on system where this makes sense
#
#----------------------------------------------------------------------
from test import test_support
import os, struct, stat, sys
try:
import signal
# The default handler for SIGXFSZ is to abort the process.
# By ignoring it, system calls exceeding the file size resource
# limit will raise IOError instead of crashing the interpreter.
oldhandler = signal.signal(signal.SIGXFSZ, signal.SIG_IGN)
except (ImportError, AttributeError):
pass
# create >2GB file (2GB = 2147483648 bytes)
size = 2500000000L
name = test_support.TESTFN
# On Windows and Mac OSX this test comsumes large resources; It takes
# a long time to build the >2GB file and takes >2GB of disk space
# therefore the resource must be enabled to run this test. If not,
# nothing after this line stanza will be executed.
if sys.platform[:3] == 'win' or sys.platform == 'darwin' or test_support.is_jython:
test_support.requires(
'largefile',
'test requires %s bytes and a long time to run' % str(size))
else:
# Only run if the current filesystem supports large files.
# (Skip this test on Windows, since we now always support large files.)
f = open(test_support.TESTFN, 'wb')
try:
# 2**31 == 2147483648
f.seek(2147483649L)
# Seeking is not enough of a test: you must write and flush, too!
f.write("x")
f.flush()
except (IOError, OverflowError):
f.close()
os.unlink(test_support.TESTFN)
raise test_support.TestSkipped, \
"filesystem does not have largefile support"
else:
f.close()
def expect(got_this, expect_this):
if test_support.verbose:
print '%r =?= %r ...' % (got_this, expect_this),
if got_this != expect_this:
if test_support.verbose:
print 'no'
raise test_support.TestFailed, 'got %r, but expected %r' %\
(got_this, expect_this)
else:
if test_support.verbose:
print 'yes'
# test that each file function works as expected for a large (i.e. >2GB, do
# we have to check >4GB) files
if test_support.verbose:
print 'create large file via seek (may be sparse file) ...'
f = open(name, 'wb')
try:
f.write('z')
f.seek(0)
f.seek(size)
f.write('a')
f.flush()
if hasattr(os, 'fstat'):
if test_support.verbose:
print 'check file size with os.fstat'
expect(os.fstat(f.fileno())[stat.ST_SIZE], size+1)
finally:
f.close()
if test_support.verbose:
print 'check file size with os.stat'
expect(os.stat(name)[stat.ST_SIZE], size+1)
if test_support.verbose:
print 'play around with seek() and read() with the built largefile'
f = open(name, 'rb')
try:
expect(f.tell(), 0)
expect(f.read(1), 'z')
expect(f.tell(), 1)
f.seek(0)
expect(f.tell(), 0)
f.seek(0, 0)
expect(f.tell(), 0)
f.seek(42)
expect(f.tell(), 42)
f.seek(42, 0)
expect(f.tell(), 42)
f.seek(42, 1)
expect(f.tell(), 84)
f.seek(0, 1)
expect(f.tell(), 84)
f.seek(0, 2) # seek from the end
expect(f.tell(), size + 1 + 0)
f.seek(-10, 2)
expect(f.tell(), size + 1 - 10)
f.seek(-size-1, 2)
expect(f.tell(), 0)
f.seek(size)
expect(f.tell(), size)
expect(f.read(1), 'a') # the 'a' that was written at the end of file above
f.seek(-size-1, 1)
expect(f.read(1), 'z')
expect(f.tell(), 1)
finally:
f.close()
if test_support.verbose:
print 'play around with os.lseek() with the built largefile'
f = open(name, 'rb')
try:
expect(os.lseek(f.fileno(), 0, 0), 0)
expect(os.lseek(f.fileno(), 42, 0), 42)
expect(os.lseek(f.fileno(), 42, 1), 84)
expect(os.lseek(f.fileno(), 0, 1), 84)
expect(os.lseek(f.fileno(), 0, 2), size+1+0)
expect(os.lseek(f.fileno(), -10, 2), size+1-10)
expect(os.lseek(f.fileno(), -size-1, 2), 0)
expect(os.lseek(f.fileno(), size, 0), size)
expect(f.read(1), 'a') # the 'a' that was written at the end of file above
finally:
f.close()
if hasattr(f, 'truncate'):
if test_support.verbose:
print 'try truncate'
f = open(name, 'r+b')
try:
f.seek(0, 2)
expect(f.tell(), size+1) # else we've lost track of the true size
# Cut it back via seek + truncate with no argument.
newsize = size - 10
f.seek(newsize)
f.truncate()
expect(f.tell(), newsize) # else pointer moved
f.seek(0, 2)
expect(f.tell(), newsize) # else wasn't truncated
# Ensure that truncate(smaller than true size) shrinks the file.
newsize -= 1
f.seek(42)
f.truncate(newsize)
expect(f.tell(), 42) # else pointer moved
f.seek(0, 2)
expect(f.tell(), newsize) # else wasn't truncated
# XXX truncate(larger than true size) is ill-defined across platforms
# cut it waaaaay back
f.seek(0)
f.truncate(1)
expect(f.tell(), 0) # else pointer moved
expect(len(f.read()), 1) # else wasn't truncated
finally:
f.close()
os.unlink(name)
|