summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_largefile.py
blob: b2bec1fa9f7a32a06752c5e171afaec9eb7dd8f1 (plain)
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
#!python

#----------------------------------------------------------------------
# test largefile support on system where this makes sense
#
#XXX how to only run this when support is there
#XXX how to only optionally run this, it will take along time
#----------------------------------------------------------------------

import test_support
import os, struct, stat, sys


# only run if the current system support large files
f = open(test_support.TESTFN, 'wb')
try:
    # 2**31 == 2147483648
    f.seek(2147483649L)
except (IOError, OverflowError):
    f.close()
    os.unlink(test_support.TESTFN)
    raise test_support.TestSkipped, \
          "platform does not have largefile support"
else:
    f.close()


# create >2GB file (2GB = 2147483648 bytes)
size = 2500000000L
name = test_support.TESTFN


# On Windows 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':
    test_support.requires(
        'largefile',
        'test requires %s bytes and a long time to run' % str(size))


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')
f.write('z')
f.seek(0)
f.seek(size)
f.write('a')
f.flush()
if test_support.verbose:
    print 'check file size with os.fstat'
expect(os.fstat(f.fileno())[stat.ST_SIZE], size+1)
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')
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 the file above
f.seek(-size-1, 1)
expect(f.read(1), 'z')
expect(f.tell(), 1)
f.close()

if test_support.verbose:
    print 'play around with os.lseek() with the built largefile'
f = open(name, 'rb')
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 the file above
f.close()


# XXX add tests for truncate if it exists
# XXX has truncate ever worked on Windows? specifically on WinNT I get:
#     "IOError: [Errno 13] Permission denied"
##try:
##      newsize = size - 10
##      f.seek(newsize)
##      f.truncate()
##      expect(f.tell(), newsize)
##      newsize = newsize - 1
##      f.seek(0)
##      f.truncate(newsize)
##      expect(f.tell(), newsize)
##except AttributeError:
##      pass

os.unlink(name)