]>
git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.2/Lib/test/test_mmap.py
1 from test
.test_support
import (TESTFN
, run_unittest
, import_module
, unlink
,
4 import os
, re
, itertools
, socket
, sys
6 mmap
= import_module('mmap')
8 PAGESIZE
= mmap
.PAGESIZE
10 class MmapTests(unittest
.TestCase
):
13 if os
.path
.exists(TESTFN
):
23 # Test mmap module on Unix systems and Windows
25 # Create a file to be mmap'ed.
26 f
= open(TESTFN
, 'w+')
28 # Write 2 pages worth of data to the file
29 f
.write('\0'* PAGESIZE
)
31 f
.write('\0'* (PAGESIZE
-3) )
33 m
= mmap
.mmap(f
.fileno(), 2 * PAGESIZE
)
36 # Simple sanity checks
38 tp
= str(type(m
)) # SF bug 128713: segfaulted on Linux
39 self
.assertEqual(m
.find('foo'), PAGESIZE
)
41 self
.assertEqual(len(m
), 2*PAGESIZE
)
43 self
.assertEqual(m
[0], '\0')
44 self
.assertEqual(m
[0:3], '\0\0\0')
46 # Shouldn't crash on boundary (Issue #5292)
47 self
.assertRaises(IndexError, m
.__getitem
__, len(m
))
48 self
.assertRaises(IndexError, m
.__setitem
__, len(m
), '\0')
50 # Modify the file's content
52 m
[PAGESIZE
+3: PAGESIZE
+3+3] = 'bar'
54 # Check that the modification worked
55 self
.assertEqual(m
[0], '3')
56 self
.assertEqual(m
[0:3], '3\0\0')
57 self
.assertEqual(m
[PAGESIZE
-1 : PAGESIZE
+ 7], '\0foobar\0')
61 # Test doing a regular expression match in an mmap'ed file
62 match
= re
.search('[A-Za-z]+', m
)
64 self
.fail('regex match on mmap failed!')
66 start
, end
= match
.span(0)
69 self
.assertEqual(start
, PAGESIZE
)
70 self
.assertEqual(end
, PAGESIZE
+ 6)
72 # test seeking around (try to overflow the seek implementation)
74 self
.assertEqual(m
.tell(), 0)
76 self
.assertEqual(m
.tell(), 42)
78 self
.assertEqual(m
.tell(), len(m
))
80 # Try to seek to negative position...
81 self
.assertRaises(ValueError, m
.seek
, -1)
83 # Try to seek beyond end of mmap...
84 self
.assertRaises(ValueError, m
.seek
, 1, 2)
86 # Try to seek to negative position...
87 self
.assertRaises(ValueError, m
.seek
, -len(m
)-1, 2)
93 # resize() not supported
94 # No messages are printed, since the output of this test suite
95 # would then be different across platforms.
98 # resize() is supported
99 self
.assertEqual(len(m
), 512)
100 # Check that we can no longer seek beyond the new size.
101 self
.assertRaises(ValueError, m
.seek
, 513, 0)
103 # Check that the underlying file is truncated too
107 self
.assertEqual(f
.tell(), 512)
109 self
.assertEqual(m
.size(), 512)
119 def test_access_parameter(self
):
120 # Test for "access" keyword parameter
122 open(TESTFN
, "wb").write("a"*mapsize
)
123 f
= open(TESTFN
, "rb")
124 m
= mmap
.mmap(f
.fileno(), mapsize
, access
=mmap
.ACCESS_READ
)
125 self
.assertEqual(m
[:], 'a'*mapsize
, "Readonly memory map data incorrect.")
127 # Ensuring that readonly mmap can't be slice assigned
133 self
.fail("Able to write to readonly memory map")
135 # Ensuring that readonly mmap can't be item assigned
141 self
.fail("Able to write to readonly memory map")
143 # Ensuring that readonly mmap can't be write() to
150 self
.fail("Able to write to readonly memory map")
152 # Ensuring that readonly mmap can't be write_byte() to
159 self
.fail("Able to write to readonly memory map")
161 # Ensuring that readonly mmap can't be resized
164 except SystemError: # resize is not universally supported
169 self
.fail("Able to resize readonly memory map")
172 self
.assertEqual(open(TESTFN
, "rb").read(), 'a'*mapsize
,
173 "Readonly memory map data file was modified")
175 # Opening mmap with size too big
177 f
= open(TESTFN
, "r+b")
179 m
= mmap
.mmap(f
.fileno(), mapsize
+1)
181 # we do not expect a ValueError on Windows
182 # CAUTION: This also changes the size of the file on disk, and
183 # later tests assume that the length hasn't changed. We need to
185 if sys
.platform
.startswith('win'):
186 self
.fail("Opening mmap with size+1 should work on Windows.")
188 # we expect a ValueError on Unix, but not on Windows
189 if not sys
.platform
.startswith('win'):
190 self
.fail("Opening mmap with size+1 should raise ValueError.")
193 if sys
.platform
.startswith('win'):
194 # Repair damage from the resizing test.
195 f
= open(TESTFN
, 'r+b')
199 # Opening mmap with access=ACCESS_WRITE
200 f
= open(TESTFN
, "r+b")
201 m
= mmap
.mmap(f
.fileno(), mapsize
, access
=mmap
.ACCESS_WRITE
)
202 # Modifying write-through memory map
204 self
.assertEqual(m
[:], 'c'*mapsize
,
205 "Write-through memory map memory not updated properly.")
209 f
= open(TESTFN
, 'rb')
212 self
.assertEqual(stuff
, 'c'*mapsize
,
213 "Write-through memory map data file not updated properly.")
215 # Opening mmap with access=ACCESS_COPY
216 f
= open(TESTFN
, "r+b")
217 m
= mmap
.mmap(f
.fileno(), mapsize
, access
=mmap
.ACCESS_COPY
)
218 # Modifying copy-on-write memory map
220 self
.assertEqual(m
[:], 'd' * mapsize
,
221 "Copy-on-write memory map data not written correctly.")
223 self
.assertEqual(open(TESTFN
, "rb").read(), 'c'*mapsize
,
224 "Copy-on-write test data file should not be modified.")
225 # Ensuring copy-on-write maps cannot be resized
226 self
.assertRaises(TypeError, m
.resize
, 2*mapsize
)
230 # Ensuring invalid access parameter raises exception
231 f
= open(TESTFN
, "r+b")
232 self
.assertRaises(ValueError, mmap
.mmap
, f
.fileno(), mapsize
, access
=4)
235 if os
.name
== "posix":
236 # Try incompatible flags, prot and access parameters.
237 f
= open(TESTFN
, "r+b")
238 self
.assertRaises(ValueError, mmap
.mmap
, f
.fileno(), mapsize
,
239 flags
=mmap
.MAP_PRIVATE
,
240 prot
=mmap
.PROT_READ
, access
=mmap
.ACCESS_WRITE
)
243 # Try writing with PROT_EXEC and without PROT_WRITE
244 prot
= mmap
.PROT_READ |
getattr(mmap
, 'PROT_EXEC', 0)
245 with
open(TESTFN
, "r+b") as f
:
246 m
= mmap
.mmap(f
.fileno(), mapsize
, prot
=prot
)
247 self
.assertRaises(TypeError, m
.write
, b
"abcdef")
248 self
.assertRaises(TypeError, m
.write_byte
, 0)
251 def test_bad_file_desc(self
):
252 # Try opening a bad file descriptor...
253 self
.assertRaises(mmap
.error
, mmap
.mmap
, -2, 4096)
255 def test_tougher_find(self
):
256 # Do a tougher .find() test. SF bug 515943 pointed out that, in 2.2,
257 # searching for data with embedded \0 bytes didn't work.
258 f
= open(TESTFN
, 'w+')
260 data
= 'aabaac\x00deef\x00\x00aa\x00'
264 m
= mmap
.mmap(f
.fileno(), n
)
267 for start
in range(n
+1):
268 for finish
in range(start
, n
+1):
269 slice = data
[start
: finish
]
270 self
.assertEqual(m
.find(slice), data
.find(slice))
271 self
.assertEqual(m
.find(slice + 'x'), -1)
274 def test_find_end(self
):
275 # test the new 'end' parameter works as expected
276 f
= open(TESTFN
, 'w+')
277 data
= 'one two ones'
281 m
= mmap
.mmap(f
.fileno(), n
)
284 self
.assertEqual(m
.find('one'), 0)
285 self
.assertEqual(m
.find('ones'), 8)
286 self
.assertEqual(m
.find('one', 0, -1), 0)
287 self
.assertEqual(m
.find('one', 1), 8)
288 self
.assertEqual(m
.find('one', 1, -1), 8)
289 self
.assertEqual(m
.find('one', 1, -2), -1)
292 def test_rfind(self
):
293 # test the new 'end' parameter works as expected
294 f
= open(TESTFN
, 'w+')
295 data
= 'one two ones'
299 m
= mmap
.mmap(f
.fileno(), n
)
302 self
.assertEqual(m
.rfind('one'), 8)
303 self
.assertEqual(m
.rfind('one '), 0)
304 self
.assertEqual(m
.rfind('one', 0, -1), 8)
305 self
.assertEqual(m
.rfind('one', 0, -2), 0)
306 self
.assertEqual(m
.rfind('one', 1, -1), 8)
307 self
.assertEqual(m
.rfind('one', 1, -2), -1)
310 def test_double_close(self
):
311 # make sure a double close doesn't crash on Solaris (Bug# 665913)
312 f
= open(TESTFN
, 'w+')
314 f
.write(2**16 * 'a') # Arbitrary character
318 mf
= mmap
.mmap(f
.fileno(), 2**16, access
=mmap
.ACCESS_READ
)
323 def test_entire_file(self
):
324 # test mapping of entire file by passing 0 for map length
325 if hasattr(os
, "stat"):
326 f
= open(TESTFN
, "w+")
328 f
.write(2**16 * 'm') # Arbitrary character
331 f
= open(TESTFN
, "rb+")
332 mf
= mmap
.mmap(f
.fileno(), 0)
333 self
.assertEqual(len(mf
), 2**16, "Map size should equal file size.")
334 self
.assertEqual(mf
.read(2**16), 2**16 * "m")
338 def test_length_0_offset(self
):
339 # Issue #10916: test mapping of remainder of file by passing 0 for
340 # map length with an offset doesn't cause a segfault.
341 if not hasattr(os
, "stat"):
342 self
.skipTest("needs os.stat")
343 # NOTE: allocation granularity is currently 65536 under Win64,
344 # and therefore the minimum offset alignment.
345 with
open(TESTFN
, "wb") as f
:
346 f
.write((65536 * 2) * b
'm') # Arbitrary character
348 with
open(TESTFN
, "rb") as f
:
349 mf
= mmap
.mmap(f
.fileno(), 0, offset
=65536, access
=mmap
.ACCESS_READ
)
351 self
.assertRaises(IndexError, mf
.__getitem
__, 80000)
355 def test_length_0_large_offset(self
):
356 # Issue #10959: test mapping of a file by passing 0 for
357 # map length with a large offset doesn't cause a segfault.
358 if not hasattr(os
, "stat"):
359 self
.skipTest("needs os.stat")
361 with
open(TESTFN
, "wb") as f
:
362 f
.write(115699 * b
'm') # Arbitrary character
364 with
open(TESTFN
, "w+b") as f
:
365 self
.assertRaises(ValueError, mmap
.mmap
, f
.fileno(), 0,
369 # make move works everywhere (64-bit format problem earlier)
370 f
= open(TESTFN
, 'w+')
372 f
.write("ABCDEabcde") # Arbitrary character
375 mf
= mmap
.mmap(f
.fileno(), 10)
377 self
.assertEqual(mf
[:], "ABCDEABCDE", "Map move should have duplicated front 5")
381 # more excessive test
383 for dest
in range(len(data
)):
384 for src
in range(len(data
)):
385 for count
in range(len(data
) - max(dest
, src
)):
386 expected
= data
[:dest
] + data
[src
:src
+count
] + data
[dest
+count
:]
387 m
= mmap
.mmap(-1, len(data
))
389 m
.move(dest
, src
, count
)
390 self
.assertEqual(m
[:], expected
)
393 # segfault test (Issue 5387)
394 m
= mmap
.mmap(-1, 100)
395 offsets
= [-100, -1, 0, 1, 100]
396 for source
, dest
, size
in itertools
.product(offsets
, offsets
, offsets
):
398 m
.move(source
, dest
, size
)
402 offsets
= [(-1, -1, -1), (-1, -1, 0), (-1, 0, -1), (0, -1, -1),
403 (-1, 0, 0), (0, -1, 0), (0, 0, -1)]
404 for source
, dest
, size
in offsets
:
405 self
.assertRaises(ValueError, m
.move
, source
, dest
, size
)
409 m
= mmap
.mmap(-1, 1) # single byte
410 self
.assertRaises(ValueError, m
.move
, 0, 0, 2)
411 self
.assertRaises(ValueError, m
.move
, 1, 0, 1)
412 self
.assertRaises(ValueError, m
.move
, 0, 1, 1)
417 def test_anonymous(self
):
418 # anonymous mmap.mmap(-1, PAGE)
419 m
= mmap
.mmap(-1, PAGESIZE
)
420 for x
in xrange(PAGESIZE
):
421 self
.assertEqual(m
[x
], '\0', "anonymously mmap'ed contents should be zero")
423 for x
in xrange(PAGESIZE
):
424 m
[x
] = ch
= chr(x
& 255)
425 self
.assertEqual(m
[x
], ch
)
427 def test_extended_getslice(self
):
428 # Test extended slicing by comparing with list slicing.
429 s
= "".join(chr(c
) for c
in reversed(range(256)))
430 m
= mmap
.mmap(-1, len(s
))
432 self
.assertEqual(m
[:], s
)
433 indices
= (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
434 for start
in indices
:
436 # Skip step 0 (invalid)
437 for step
in indices
[1:]:
438 self
.assertEqual(m
[start
:stop
:step
],
441 def test_extended_set_del_slice(self
):
442 # Test extended slicing by comparing with list slicing.
443 s
= "".join(chr(c
) for c
in reversed(range(256)))
444 m
= mmap
.mmap(-1, len(s
))
445 indices
= (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
446 for start
in indices
:
448 # Skip invalid step 0
449 for step
in indices
[1:]:
451 self
.assertEqual(m
[:], s
)
453 # Make sure we have a slice of exactly the right length,
454 # but with different data.
455 data
= L
[start
:stop
:step
]
456 data
= "".join(reversed(data
))
457 L
[start
:stop
:step
] = data
458 m
[start
:stop
:step
] = data
459 self
.assertEqual(m
[:], "".join(L
))
461 def make_mmap_file (self
, f
, halfsize
):
462 # Write 2 pages worth of data to the file
463 f
.write ('\0' * halfsize
)
465 f
.write ('\0' * (halfsize
- 3))
467 return mmap
.mmap (f
.fileno(), 0)
469 def test_offset (self
):
470 f
= open (TESTFN
, 'w+b')
472 try: # unlink TESTFN no matter what
473 halfsize
= mmap
.ALLOCATIONGRANULARITY
474 m
= self
.make_mmap_file (f
, halfsize
)
478 mapsize
= halfsize
* 2
480 f
= open(TESTFN
, "r+b")
481 for offset
in [-2, -1, None]:
483 m
= mmap
.mmap(f
.fileno(), mapsize
, offset
=offset
)
484 self
.assertEqual(0, 1)
485 except (ValueError, TypeError, OverflowError):
488 self
.assertEqual(0, 0)
491 # Try valid offset, hopefully 8192 works on all OSes
492 f
= open(TESTFN
, "r+b")
493 m
= mmap
.mmap(f
.fileno(), mapsize
- halfsize
, offset
=halfsize
)
494 self
.assertEqual(m
[0:3], 'foo')
503 # resize() is supported
504 self
.assertEqual(len(m
), 512)
505 # Check that we can no longer seek beyond the new size.
506 self
.assertRaises(ValueError, m
.seek
, 513, 0)
507 # Check that the content is not changed
508 self
.assertEqual(m
[0:3], 'foo')
510 # Check that the underlying file is truncated too
513 self
.assertEqual(f
.tell(), halfsize
+ 512)
515 self
.assertEqual(m
.size(), halfsize
+ 512)
526 def test_subclass(self
):
527 class anon_mmap(mmap
.mmap
):
528 def __new__(klass
, *args
, **kwargs
):
529 return mmap
.mmap
.__new
__(klass
, -1, *args
, **kwargs
)
532 def test_prot_readonly(self
):
533 if not hasattr(mmap
, 'PROT_READ'):
536 open(TESTFN
, "wb").write("a"*mapsize
)
537 f
= open(TESTFN
, "rb")
538 m
= mmap
.mmap(f
.fileno(), mapsize
, prot
=mmap
.PROT_READ
)
539 self
.assertRaises(TypeError, m
.write
, "foo")
542 def test_error(self
):
543 self
.assertTrue(issubclass(mmap
.error
, EnvironmentError))
544 self
.assertIn("mmap.error", str(mmap
.error
))
546 def test_io_methods(self
):
548 open(TESTFN
, "wb").write("x"*len(data
))
549 f
= open(TESTFN
, "r+b")
550 m
= mmap
.mmap(f
.fileno(), len(data
))
553 for i
in xrange(len(data
)):
554 self
.assertEqual(m
.tell(), i
)
555 m
.write_byte(data
[i
])
556 self
.assertEqual(m
.tell(), i
+1)
557 self
.assertRaises(ValueError, m
.write_byte
, "x")
558 self
.assertEqual(m
[:], data
)
561 for i
in xrange(len(data
)):
562 self
.assertEqual(m
.tell(), i
)
563 self
.assertEqual(m
.read_byte(), data
[i
])
564 self
.assertEqual(m
.tell(), i
+1)
565 self
.assertRaises(ValueError, m
.read_byte
)
568 self
.assertEqual(m
.read(3), "345")
569 self
.assertEqual(m
.tell(), 6)
573 self
.assertEqual(m
.tell(), 6)
574 self
.assertEqual(m
[:], "012bar6789")
576 self
.assertRaises(ValueError, m
.write
, "bar")
579 def test_tagname(self
):
582 assert len(data1
) == len(data2
)
585 m1
= mmap
.mmap(-1, len(data1
), tagname
="foo")
587 m2
= mmap
.mmap(-1, len(data2
), tagname
="foo")
589 self
.assertEqual(m1
[:], data2
)
590 self
.assertEqual(m2
[:], data2
)
595 m1
= mmap
.mmap(-1, len(data1
), tagname
="foo")
597 m2
= mmap
.mmap(-1, len(data2
), tagname
="boo")
599 self
.assertEqual(m1
[:], data1
)
600 self
.assertEqual(m2
[:], data2
)
604 def test_crasher_on_windows(self
):
605 # Should not crash (Issue 1733986)
606 m
= mmap
.mmap(-1, 1000, tagname
="foo")
608 mmap
.mmap(-1, 5000, tagname
="foo")[:] # same tagname, but larger size
613 # Should not crash (Issue 5385)
614 open(TESTFN
, "wb").write("x"*10)
615 f
= open(TESTFN
, "r+b")
616 m
= mmap
.mmap(f
.fileno(), 0)
619 m
.resize(0) # will raise WindowsError
628 def test_invalid_descriptor(self
):
629 # socket file descriptors are valid, but out of range
630 # for _get_osfhandle, causing a crash when validating the
631 # parameters to _get_osfhandle.
634 with self
.assertRaises(mmap
.error
):
635 m
= mmap
.mmap(s
.fileno(), 10)
640 class LargeMmapTests(unittest
.TestCase
):
648 def _make_test_file(self
, num_zeroes
, tail
):
649 if sys
.platform
[:3] == 'win' or sys
.platform
== 'darwin':
650 requires('largefile',
651 'test requires %s bytes and a long time to run' % str(0x180000000))
652 f
= open(TESTFN
, 'w+b')
657 except (IOError, OverflowError):
659 raise unittest
.SkipTest("filesystem does not have largefile support")
662 def test_large_offset(self
):
663 with self
._make
_test
_file
(0x14FFFFFFF, b
" ") as f
:
664 m
= mmap
.mmap(f
.fileno(), 0, offset
=0x140000000, access
=mmap
.ACCESS_READ
)
666 self
.assertEqual(m
[0xFFFFFFF], b
" ")
670 def test_large_filesize(self
):
671 with self
._make
_test
_file
(0x17FFFFFFF, b
" ") as f
:
672 m
= mmap
.mmap(f
.fileno(), 0x10000, access
=mmap
.ACCESS_READ
)
674 self
.assertEqual(m
.size(), 0x180000000)
678 # Issue 11277: mmap() with large (~4GB) sparse files crashes on OS X.
680 def _test_around_boundary(self
, boundary
):
682 start
= boundary
- len(tail
) // 2
683 end
= start
+ len(tail
)
684 with self
._make
_test
_file
(start
, tail
) as f
:
685 m
= mmap
.mmap(f
.fileno(), 0, access
=mmap
.ACCESS_READ
)
687 self
.assertEqual(m
[start
:end
], tail
)
691 @unittest.skipUnless(sys
.maxsize
> _4G
, "test cannot run on 32-bit systems")
692 def test_around_2GB(self
):
693 self
._test
_around
_boundary
(_2G
)
695 @unittest.skipUnless(sys
.maxsize
> _4G
, "test cannot run on 32-bit systems")
696 def test_around_4GB(self
):
697 self
._test
_around
_boundary
(_4G
)
701 run_unittest(MmapTests
, LargeMmapTests
)
703 if __name__
== '__main__':