blob: a98aab24a1d4784a49b9e4e0fd699c7e8506a1c2 [file] [log] [blame]
Facundo Batista9521f082008-02-07 16:16:29 +00001"""Test largefile support on system where this makes sense.
2"""
Trent Mickf29f47b2000-08-11 19:02:59 +00003
Facundo Batista9521f082008-02-07 16:16:29 +00004import os
5import stat
6import sys
7import unittest
8from test.test_support import run_unittest, TESTFN, verbose, requires, \
9 TestSkipped, unlink
Trent Mickf29f47b2000-08-11 19:02:59 +000010
Martin v. Löwisdf8adcd2001-12-11 17:57:26 +000011try:
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
Guido van Rossuma31ddbb2001-09-10 15:03:18 +000020# create >2GB file (2GB = 2147483648 bytes)
21size = 2500000000L
Guido van Rossuma31ddbb2001-09-10 15:03:18 +000022
23
Facundo Batista9521f082008-02-07 16:16:29 +000024class TestCase(unittest.TestCase):
25 """Test that each file function works as expected for a large
26 (i.e. > 2GB, do we have to check > 4GB) files.
Brett Cannon6382ffc2008-03-03 02:41:40 +000027
Facundo Batista9521f082008-02-07 16:16:29 +000028 """
29
30 def test_seek(self):
31 if verbose:
32 print 'create large file via seek (may be sparse file) ...'
Brett Cannon6382ffc2008-03-03 02:41:40 +000033 with open(TESTFN, 'wb') as f:
Facundo Batista9521f082008-02-07 16:16:29 +000034 f.write('z')
35 f.seek(0)
36 f.seek(size)
37 f.write('a')
38 f.flush()
39 if verbose:
40 print 'check file size with os.fstat'
41 self.assertEqual(os.fstat(f.fileno())[stat.ST_SIZE], size+1)
Facundo Batista9521f082008-02-07 16:16:29 +000042
43 def test_osstat(self):
44 if verbose:
45 print 'check file size with os.stat'
46 self.assertEqual(os.stat(TESTFN)[stat.ST_SIZE], size+1)
47
48 def test_seek_read(self):
49 if verbose:
50 print 'play around with seek() and read() with the built largefile'
Brett Cannon6382ffc2008-03-03 02:41:40 +000051 with open(TESTFN, 'rb') as f:
Facundo Batista9521f082008-02-07 16:16:29 +000052 self.assertEqual(f.tell(), 0)
53 self.assertEqual(f.read(1), 'z')
54 self.assertEqual(f.tell(), 1)
55 f.seek(0)
56 self.assertEqual(f.tell(), 0)
57 f.seek(0, 0)
58 self.assertEqual(f.tell(), 0)
59 f.seek(42)
60 self.assertEqual(f.tell(), 42)
61 f.seek(42, 0)
62 self.assertEqual(f.tell(), 42)
63 f.seek(42, 1)
64 self.assertEqual(f.tell(), 84)
65 f.seek(0, 1)
66 self.assertEqual(f.tell(), 84)
67 f.seek(0, 2) # seek from the end
68 self.assertEqual(f.tell(), size + 1 + 0)
69 f.seek(-10, 2)
70 self.assertEqual(f.tell(), size + 1 - 10)
71 f.seek(-size-1, 2)
72 self.assertEqual(f.tell(), 0)
73 f.seek(size)
74 self.assertEqual(f.tell(), size)
75 # the 'a' that was written at the end of file above
76 self.assertEqual(f.read(1), 'a')
77 f.seek(-size-1, 1)
78 self.assertEqual(f.read(1), 'z')
79 self.assertEqual(f.tell(), 1)
Facundo Batista9521f082008-02-07 16:16:29 +000080
81 def test_lseek(self):
82 if verbose:
83 print 'play around with os.lseek() with the built largefile'
Brett Cannon6382ffc2008-03-03 02:41:40 +000084 with open(TESTFN, 'rb') as f:
Facundo Batista9521f082008-02-07 16:16:29 +000085 self.assertEqual(os.lseek(f.fileno(), 0, 0), 0)
86 self.assertEqual(os.lseek(f.fileno(), 42, 0), 42)
87 self.assertEqual(os.lseek(f.fileno(), 42, 1), 84)
88 self.assertEqual(os.lseek(f.fileno(), 0, 1), 84)
89 self.assertEqual(os.lseek(f.fileno(), 0, 2), size+1+0)
90 self.assertEqual(os.lseek(f.fileno(), -10, 2), size+1-10)
91 self.assertEqual(os.lseek(f.fileno(), -size-1, 2), 0)
92 self.assertEqual(os.lseek(f.fileno(), size, 0), size)
93 # the 'a' that was written at the end of file above
94 self.assertEqual(f.read(1), 'a')
Facundo Batista9521f082008-02-07 16:16:29 +000095
96 def test_truncate(self):
97 if verbose:
98 print 'try truncate'
Brett Cannon6382ffc2008-03-03 02:41:40 +000099 with open(TESTFN, 'r+b') as f:
100 # this is already decided before start running the test suite
101 # but we do it anyway for extra protection
102 if not hasattr(f, 'truncate'):
103 raise TestSkipped, "open().truncate() not available on this system"
Facundo Batista9521f082008-02-07 16:16:29 +0000104 f.seek(0, 2)
105 # else we've lost track of the true size
106 self.assertEqual(f.tell(), size+1)
107 # Cut it back via seek + truncate with no argument.
108 newsize = size - 10
109 f.seek(newsize)
110 f.truncate()
111 self.assertEqual(f.tell(), newsize) # else pointer moved
112 f.seek(0, 2)
113 self.assertEqual(f.tell(), newsize) # else wasn't truncated
114 # Ensure that truncate(smaller than true size) shrinks
115 # the file.
116 newsize -= 1
117 f.seek(42)
118 f.truncate(newsize)
119 self.assertEqual(f.tell(), 42) # else pointer moved
120 f.seek(0, 2)
121 self.assertEqual(f.tell(), newsize) # else wasn't truncated
122
123 # XXX truncate(larger than true size) is ill-defined
124 # across platform; cut it waaaaay back
125 f.seek(0)
126 f.truncate(1)
127 self.assertEqual(f.tell(), 0) # else pointer moved
128 self.assertEqual(len(f.read()), 1) # else wasn't truncated
Facundo Batista9521f082008-02-07 16:16:29 +0000129
130
Brett Cannon6382ffc2008-03-03 02:41:40 +0000131def test_main():
Facundo Batista9521f082008-02-07 16:16:29 +0000132 # On Windows and Mac OSX this test comsumes large resources; It
133 # takes a long time to build the >2GB file and takes >2GB of disk
134 # space therefore the resource must be enabled to run this test.
135 # If not, nothing after this line stanza will be executed.
136 if sys.platform[:3] == 'win' or sys.platform == 'darwin':
137 requires('largefile',
138 'test requires %s bytes and a long time to run' % str(size))
Guido van Rossum47f40342001-09-10 13:34:12 +0000139 else:
Facundo Batista9521f082008-02-07 16:16:29 +0000140 # Only run if the current filesystem supports large files.
141 # (Skip this test on Windows, since we now always support
142 # large files.)
143 f = open(TESTFN, 'wb')
144 try:
145 # 2**31 == 2147483648
146 f.seek(2147483649L)
147 # Seeking is not enough of a test: you must write and
148 # flush, too!
149 f.write("x")
150 f.flush()
151 except (IOError, OverflowError):
152 f.close()
153 unlink(TESTFN)
154 raise TestSkipped, "filesystem does not have largefile support"
155 else:
156 f.close()
157 suite = unittest.TestSuite()
158 suite.addTest(TestCase('test_seek'))
159 suite.addTest(TestCase('test_osstat'))
160 suite.addTest(TestCase('test_seek_read'))
161 suite.addTest(TestCase('test_lseek'))
Brett Cannon6382ffc2008-03-03 02:41:40 +0000162 with open(TESTFN, 'w') as f:
163 if hasattr(f, 'truncate'):
164 suite.addTest(TestCase('test_truncate'))
Facundo Batista9521f082008-02-07 16:16:29 +0000165 unlink(TESTFN)
Brett Cannon6382ffc2008-03-03 02:41:40 +0000166 try:
167 run_unittest(suite)
168 finally:
169 unlink(TESTFN)
Trent Mickf29f47b2000-08-11 19:02:59 +0000170
Trent Mickf29f47b2000-08-11 19:02:59 +0000171
Facundo Batista9521f082008-02-07 16:16:29 +0000172if __name__ == '__main__':
Brett Cannon6382ffc2008-03-03 02:41:40 +0000173 test_main()