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