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
)