1
from test.test_support import verify, vereq, TESTFN
5
PAGESIZE = mmap.PAGESIZE
8
"Test mmap module on Unix systems and Windows"
10
# Create a file to be mmap'ed.
11
if os.path.exists(TESTFN):
13
f = open(TESTFN, 'w+')
15
try: # unlink TESTFN no matter what
16
# Write 2 pages worth of data to the file
17
f.write('\0'* PAGESIZE)
19
f.write('\0'* (PAGESIZE-3) )
21
m = mmap.mmap(f.fileno(), 2 * PAGESIZE)
24
# Simple sanity checks
26
print type(m) # SF bug 128713: segfaulted on Linux
27
print ' Position of foo:', m.find('foo') / float(PAGESIZE), 'pages'
28
vereq(m.find('foo'), PAGESIZE)
30
print ' Length of file:', len(m) / float(PAGESIZE), 'pages'
31
vereq(len(m), 2*PAGESIZE)
33
print ' Contents of byte 0:', repr(m[0])
35
print ' Contents of first 3 bytes:', repr(m[0:3])
36
vereq(m[0:3], '\0\0\0')
38
# Modify the file's content
39
print "\n Modifying file's content..."
41
m[PAGESIZE +3: PAGESIZE +3+3] = 'bar'
43
# Check that the modification worked
44
print ' Contents of byte 0:', repr(m[0])
46
print ' Contents of first 3 bytes:', repr(m[0:3])
47
vereq(m[0:3], '3\0\0')
48
print ' Contents of second page:', repr(m[PAGESIZE-1 : PAGESIZE + 7])
49
vereq(m[PAGESIZE-1 : PAGESIZE + 7], '\0foobar\0')
53
# Test doing a regular expression match in an mmap'ed file
54
match = re.search('[A-Za-z]+', m)
56
print ' ERROR: regex match on mmap failed!'
58
start, end = match.span(0)
61
print ' Regex match on mmap (page start, length of match):',
62
print start / float(PAGESIZE), length
64
vereq(start, PAGESIZE)
65
vereq(end, PAGESIZE + 6)
67
# test seeking around (try to overflow the seek implementation)
69
print ' Seek to zeroth byte'
72
print ' Seek to 42nd byte'
75
print ' Seek to last byte'
76
vereq(m.tell(), len(m))
78
print ' Try to seek to negative position...'
84
verify(0, 'expected a ValueError but did not get it')
86
print ' Try to seek beyond end of mmap...'
92
verify(0, 'expected a ValueError but did not get it')
94
print ' Try to seek to negative position...'
100
verify(0, 'expected a ValueError but did not get it')
103
print ' Attempting resize()'
107
# resize() not supported
108
# No messages are printed, since the output of this test suite
109
# would then be different across platforms.
112
# resize() is supported
113
verify(len(m) == 512,
114
"len(m) is %d, but expecting 512" % (len(m),) )
115
# Check that we can no longer seek beyond the new size.
121
verify(0, 'Could seek beyond the new size')
135
# Test for "access" keyword parameter
138
print " Creating", mapsize, "byte test data file."
139
open(TESTFN, "wb").write("a"*mapsize)
140
print " Opening mmap with access=ACCESS_READ"
141
f = open(TESTFN, "rb")
142
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_READ)
143
verify(m[:] == 'a'*mapsize, "Readonly memory map data incorrect.")
145
print " Ensuring that readonly mmap can't be slice assigned."
151
verify(0, "Able to write to readonly memory map")
153
print " Ensuring that readonly mmap can't be item assigned."
159
verify(0, "Able to write to readonly memory map")
161
print " Ensuring that readonly mmap can't be write() to."
168
verify(0, "Able to write to readonly memory map")
170
print " Ensuring that readonly mmap can't be write_byte() to."
177
verify(0, "Able to write to readonly memory map")
179
print " Ensuring that readonly mmap can't be resized."
182
except SystemError: # resize is not universally supported
187
verify(0, "Able to resize readonly memory map")
189
verify(open(TESTFN, "rb").read() == 'a'*mapsize,
190
"Readonly memory map data file was modified")
192
print " Opening mmap with size too big"
194
f = open(TESTFN, "r+b")
196
m = mmap.mmap(f.fileno(), mapsize+1)
198
# we do not expect a ValueError on Windows
199
# CAUTION: This also changes the size of the file on disk, and
200
# later tests assume that the length hasn't changed. We need to
202
if sys.platform.startswith('win'):
203
verify(0, "Opening mmap with size+1 should work on Windows.")
205
# we expect a ValueError on Unix, but not on Windows
206
if not sys.platform.startswith('win'):
207
verify(0, "Opening mmap with size+1 should raise ValueError.")
210
if sys.platform.startswith('win'):
211
# Repair damage from the resizing test.
212
f = open(TESTFN, 'r+b')
216
print " Opening mmap with access=ACCESS_WRITE"
217
f = open(TESTFN, "r+b")
218
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE)
219
print " Modifying write-through memory map."
221
verify(m[:] == 'c'*mapsize,
222
"Write-through memory map memory not updated properly.")
226
f = open(TESTFN, 'rb')
229
verify(stuff == 'c'*mapsize,
230
"Write-through memory map data file not updated properly.")
232
print " Opening mmap with access=ACCESS_COPY"
233
f = open(TESTFN, "r+b")
234
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_COPY)
235
print " Modifying copy-on-write memory map."
237
verify(m[:] == 'd' * mapsize,
238
"Copy-on-write memory map data not written correctly.")
240
verify(open(TESTFN, "rb").read() == 'c'*mapsize,
241
"Copy-on-write test data file should not be modified.")
243
print " Ensuring copy-on-write maps cannot be resized."
248
verify(0, "Copy-on-write mmap resize did not raise exception.")
251
print " Ensuring invalid access parameter raises exception."
252
f = open(TESTFN, "r+b")
253
m = mmap.mmap(f.fileno(), mapsize, access=4)
257
verify(0, "Invalid access code should have raised exception.")
259
if os.name == "posix":
260
# Try incompatible flags, prot and access parameters.
261
f = open(TESTFN, "r+b")
263
m = mmap.mmap(f.fileno(), mapsize, flags=mmap.MAP_PRIVATE,
264
prot=mmap.PROT_READ, access=mmap.ACCESS_WRITE)
268
verify(0, "Incompatible parameters should raise ValueError.")
276
# Do a tougher .find() test. SF bug 515943 pointed out that, in 2.2,
277
# searching for data with embedded \0 bytes didn't work.
278
f = open(TESTFN, 'w+')
280
try: # unlink TESTFN no matter what
281
data = 'aabaac\x00deef\x00\x00aa\x00'
285
m = mmap.mmap(f.fileno(), n)
288
for start in range(n+1):
289
for finish in range(start, n+1):
290
slice = data[start : finish]
291
vereq(m.find(slice), data.find(slice))
292
vereq(m.find(slice + 'x'), -1)
298
# make sure a double close doesn't crash on Solaris (Bug# 665913)
299
f = open(TESTFN, 'w+')
301
try: # unlink TESTFN no matter what
302
f.write(2**16 * 'a') # Arbitrary character
306
mf = mmap.mmap(f.fileno(), 2**16, access=mmap.ACCESS_READ)