|
5 | 5 | import os
|
6 | 6 | import re
|
7 | 7 | import itertools
|
| 8 | +import random |
8 | 9 | import socket
|
9 | 10 | import sys
|
10 | 11 | import weakref
|
@@ -707,7 +708,6 @@ def test_write_returning_the_number_of_bytes_written(self):
|
707 | 708 | self.assertEqual(mm.write(b"yz"), 2)
|
708 | 709 | self.assertEqual(mm.write(b"python"), 6)
|
709 | 710 |
|
710 |
| - @unittest.skipIf(os.name == 'nt', 'cannot resize anonymous mmaps on Windows') |
711 | 711 | def test_resize_past_pos(self):
|
712 | 712 | m = mmap.mmap(-1, 8192)
|
713 | 713 | self.addCleanup(m.close)
|
@@ -796,6 +796,80 @@ def test_madvise(self):
|
796 | 796 | self.assertEqual(m.madvise(mmap.MADV_NORMAL, 0, 2), None)
|
797 | 797 | self.assertEqual(m.madvise(mmap.MADV_NORMAL, 0, size), None)
|
798 | 798 |
|
| 799 | + @unittest.skipUnless(os.name == 'nt', 'requires Windows') |
| 800 | + def test_resize_up_when_mapped_to_pagefile(self): |
| 801 | + """If the mmap is backed by the pagefile ensure a resize up can happen |
| 802 | + and that the original data is still in place |
| 803 | + """ |
| 804 | + start_size = PAGESIZE |
| 805 | + new_size = 2 * start_size |
| 806 | + data = bytes(random.getrandbits(8) for _ in range(start_size)) |
| 807 | + |
| 808 | + m = mmap.mmap(-1, start_size) |
| 809 | + m[:] = data |
| 810 | + m.resize(new_size) |
| 811 | + self.assertEqual(len(m), new_size) |
| 812 | + self.assertEqual(m[:start_size], data[:start_size]) |
| 813 | + |
| 814 | + @unittest.skipUnless(os.name == 'nt', 'requires Windows') |
| 815 | + def test_resize_down_when_mapped_to_pagefile(self): |
| 816 | + """If the mmap is backed by the pagefile ensure a resize down up can happen |
| 817 | + and that a truncated form of the original data is still in place |
| 818 | + """ |
| 819 | + start_size = PAGESIZE |
| 820 | + new_size = start_size // 2 |
| 821 | + data = bytes(random.getrandbits(8) for _ in range(start_size)) |
| 822 | + |
| 823 | + m = mmap.mmap(-1, start_size) |
| 824 | + m[:] = data |
| 825 | + m.resize(new_size) |
| 826 | + self.assertEqual(len(m), new_size) |
| 827 | + self.assertEqual(m[:new_size], data[:new_size]) |
| 828 | + |
| 829 | + @unittest.skipUnless(os.name == 'nt', 'requires Windows') |
| 830 | + def test_resize_fails_if_mapping_held_elsewhere(self): |
| 831 | + """If more than one mapping is held against a named file on Windows, neither |
| 832 | + mapping can be resized |
| 833 | + """ |
| 834 | + start_size = 2 * PAGESIZE |
| 835 | + reduced_size = PAGESIZE |
| 836 | + |
| 837 | + f = open(TESTFN, 'wb+') |
| 838 | + f.truncate(start_size) |
| 839 | + try: |
| 840 | + m1 = mmap.mmap(f.fileno(), start_size) |
| 841 | + m2 = mmap.mmap(f.fileno(), start_size) |
| 842 | + with self.assertRaises(OSError): |
| 843 | + m1.resize(reduced_size) |
| 844 | + with self.assertRaises(OSError): |
| 845 | + m2.resize(reduced_size) |
| 846 | + m2.close() |
| 847 | + m1.resize(reduced_size) |
| 848 | + self.assertEqual(m1.size(), reduced_size) |
| 849 | + self.assertEqual(os.stat(f.fileno()).st_size, reduced_size) |
| 850 | + finally: |
| 851 | + f.close() |
| 852 | + |
| 853 | + @unittest.skipUnless(os.name == 'nt', 'requires Windows') |
| 854 | + def test_resize_succeeds_with_error_for_second_named_mapping(self): |
| 855 | + """If a more than one mapping exists of the same name, none of them can |
| 856 | + be resized: they'll raise an Exception and leave the original mapping intact |
| 857 | + """ |
| 858 | + start_size = 2 * PAGESIZE |
| 859 | + reduced_size = PAGESIZE |
| 860 | + tagname = "TEST" |
| 861 | + data_length = 8 |
| 862 | + data = bytes(random.getrandbits(8) for _ in range(data_length)) |
| 863 | + |
| 864 | + m1 = mmap.mmap(-1, start_size, tagname=tagname) |
| 865 | + m2 = mmap.mmap(-1, start_size, tagname=tagname) |
| 866 | + m1[:data_length] = data |
| 867 | + self.assertEqual(m2[:data_length], data) |
| 868 | + with self.assertRaises(OSError): |
| 869 | + m1.resize(reduced_size) |
| 870 | + self.assertEqual(m1.size(), start_size) |
| 871 | + self.assertEqual(m1[:data_length], data) |
| 872 | + self.assertEqual(m2[:data_length], data) |
799 | 873 |
|
800 | 874 | class LargeMmapTests(unittest.TestCase):
|
801 | 875 |
|
|
0 commit comments