~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Lib/test/test_largefile.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""Test largefile support on system where this makes sense.
 
2
"""
 
3
 
 
4
import os
 
5
import stat
 
6
import sys
 
7
import unittest
 
8
from test.support import run_unittest, TESTFN, verbose, requires, \
 
9
                              TestSkipped, unlink
 
10
import io  # C implementation of io
 
11
import _pyio as pyio # Python implementation of io
 
12
 
 
13
try:
 
14
    import signal
 
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):
 
20
    pass
 
21
 
 
22
# create >2GB file (2GB = 2147483648 bytes)
 
23
size = 2500000000
 
24
 
 
25
 
 
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.
 
29
 
 
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.
 
33
 
 
34
    """
 
35
 
 
36
    def test_seek(self):
 
37
        if verbose:
 
38
            print('create large file via seek (may be sparse file) ...')
 
39
        with self.open(TESTFN, 'wb') as f:
 
40
            f.write(b'z')
 
41
            f.seek(0)
 
42
            f.seek(size)
 
43
            f.write(b'a')
 
44
            f.flush()
 
45
            if verbose:
 
46
                print('check file size with os.fstat')
 
47
            self.assertEqual(os.fstat(f.fileno())[stat.ST_SIZE], size+1)
 
48
 
 
49
    def test_osstat(self):
 
50
        if verbose:
 
51
            print('check file size with os.stat')
 
52
        self.assertEqual(os.stat(TESTFN)[stat.ST_SIZE], size+1)
 
53
 
 
54
    def test_seek_read(self):
 
55
        if verbose:
 
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)
 
61
            f.seek(0)
 
62
            self.assertEqual(f.tell(), 0)
 
63
            f.seek(0, 0)
 
64
            self.assertEqual(f.tell(), 0)
 
65
            f.seek(42)
 
66
            self.assertEqual(f.tell(), 42)
 
67
            f.seek(42, 0)
 
68
            self.assertEqual(f.tell(), 42)
 
69
            f.seek(42, 1)
 
70
            self.assertEqual(f.tell(), 84)
 
71
            f.seek(0, 1)
 
72
            self.assertEqual(f.tell(), 84)
 
73
            f.seek(0, 2)  # seek from the end
 
74
            self.assertEqual(f.tell(), size + 1 + 0)
 
75
            f.seek(-10, 2)
 
76
            self.assertEqual(f.tell(), size + 1 - 10)
 
77
            f.seek(-size-1, 2)
 
78
            self.assertEqual(f.tell(), 0)
 
79
            f.seek(size)
 
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')
 
83
            f.seek(-size-1, 1)
 
84
            self.assertEqual(f.read(1), b'z')
 
85
            self.assertEqual(f.tell(), 1)
 
86
 
 
87
    def test_lseek(self):
 
88
        if verbose:
 
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')
 
101
 
 
102
    def test_truncate(self):
 
103
        if verbose:
 
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")
 
110
            f.seek(0, 2)
 
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.
 
114
            newsize = size - 10
 
115
            f.seek(newsize)
 
116
            f.truncate()
 
117
            self.assertEqual(f.tell(), newsize)  # else pointer moved
 
118
            f.seek(0, 2)
 
119
            self.assertEqual(f.tell(), newsize)  # else wasn't truncated
 
120
            # Ensure that truncate(smaller than true size) shrinks
 
121
            # the file.
 
122
            newsize -= 1
 
123
            f.seek(42)
 
124
            f.truncate(newsize)
 
125
            self.assertEqual(f.tell(), newsize)  # else wasn't truncated
 
126
            f.seek(0, 2)
 
127
            self.assertEqual(f.tell(), newsize)
 
128
            # XXX truncate(larger than true size) is ill-defined
 
129
            # across platform; cut it waaaaay back
 
130
            f.seek(0)
 
131
            f.truncate(1)
 
132
            self.assertEqual(f.tell(), 1)       # else pointer moved
 
133
            f.seek(0)
 
134
            self.assertEqual(len(f.read()), 1)  # else wasn't truncated
 
135
 
 
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:
 
141
                f.seek(pos)
 
142
                self.assert_(f.seekable())
 
143
 
 
144
 
 
145
def test_main():
 
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))
 
153
    else:
 
154
        # Only run if the current filesystem supports large files.
 
155
        # (Skip this test on Windows, since we now always support
 
156
        # large files.)
 
157
        f = open(TESTFN, 'wb', buffering=0)
 
158
        try:
 
159
            # 2**31 == 2147483648
 
160
            f.seek(2147483649)
 
161
            # Seeking is not enough of a test: you must write and
 
162
            # flush, too!
 
163
            f.write(b'x')
 
164
            f.flush()
 
165
        except (IOError, OverflowError):
 
166
            f.close()
 
167
            unlink(TESTFN)
 
168
            raise TestSkipped("filesystem does not have largefile support")
 
169
        else:
 
170
            f.close()
 
171
    suite = unittest.TestSuite()
 
172
    for _open, prefix in [(io.open, 'C'), (pyio.open, 'Py')]:
 
173
        class TestCase(LargeFileTest):
 
174
            pass
 
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'))
 
185
        unlink(TESTFN)
 
186
    try:
 
187
        run_unittest(suite)
 
188
    finally:
 
189
        unlink(TESTFN)
 
190
 
 
191
if __name__ == '__main__':
 
192
    test_main()