183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom test.test_support import (TESTFN, run_unittest, import_module, unlink,
283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                               requires, _2G, _4G)
383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport unittest
483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport os, re, itertools, socket, sys
583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehmmap = import_module('mmap')
783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehPAGESIZE = mmap.PAGESIZE
983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass MmapTests(unittest.TestCase):
1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def setUp(self):
1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if os.path.exists(TESTFN):
1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.unlink(TESTFN)
1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def tearDown(self):
1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.unlink(TESTFN)
1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except OSError:
2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_basic(self):
2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test mmap module on Unix systems and Windows
2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Create a file to be mmap'ed.
2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, 'w+')
2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Write 2 pages worth of data to the file
2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write('\0'* PAGESIZE)
3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write('foo')
3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write('\0'* (PAGESIZE-3) )
3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.flush()
3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m = mmap.mmap(f.fileno(), 2 * PAGESIZE)
3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Simple sanity checks
3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            tp = str(type(m))  # SF bug 128713:  segfaulted on Linux
3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m.find('foo'), PAGESIZE)
4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(len(m), 2*PAGESIZE)
4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m[0], '\0')
4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m[0:3], '\0\0\0')
4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Shouldn't crash on boundary (Issue #5292)
4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(IndexError, m.__getitem__, len(m))
4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(IndexError, m.__setitem__, len(m), '\0')
4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Modify the file's content
5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m[0] = '3'
5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m[PAGESIZE +3: PAGESIZE +3+3] = 'bar'
5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Check that the modification worked
5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m[0], '3')
5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m[0:3], '3\0\0')
5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m[PAGESIZE-1 : PAGESIZE + 7], '\0foobar\0')
5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.flush()
6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Test doing a regular expression match in an mmap'ed file
6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            match = re.search('[A-Za-z]+', m)
6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if match is None:
6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail('regex match on mmap failed!')
6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                start, end = match.span(0)
6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                length = end - start
6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(start, PAGESIZE)
7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(end, PAGESIZE + 6)
7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # test seeking around (try to overflow the seek implementation)
7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.seek(0,0)
7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m.tell(), 0)
7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.seek(42,1)
7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m.tell(), 42)
7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.seek(0,2)
7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m.tell(), len(m))
7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Try to seek to negative position...
8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(ValueError, m.seek, -1)
8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Try to seek beyond end of mmap...
8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(ValueError, m.seek, 1, 2)
8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Try to seek to negative position...
8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(ValueError, m.seek, -len(m)-1, 2)
8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Try resizing map
9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m.resize(512)
9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except SystemError:
9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # resize() not supported
9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # No messages are printed, since the output of this test suite
9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # would then be different across platforms.
9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # resize() is supported
9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(len(m), 512)
10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # Check that we can no longer seek beyond the new size.
10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertRaises(ValueError, m.seek, 513, 0)
10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # Check that the underlying file is truncated too
10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # (bug #728515)
10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f = open(TESTFN)
10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.seek(0, 2)
10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(f.tell(), 512)
10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.close()
10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(m.size(), 512)
11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.close()
11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.close()
11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except OSError:
11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_access_parameter(self):
12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test for "access" keyword parameter
12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mapsize = 10
12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        open(TESTFN, "wb").write("a"*mapsize)
12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, "rb")
12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_READ)
12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m[:], 'a'*mapsize, "Readonly memory map data incorrect.")
12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Ensuring that readonly mmap can't be slice assigned
12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m[:] = 'b'*mapsize
13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except TypeError:
13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.fail("Able to write to readonly memory map")
13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Ensuring that readonly mmap can't be item assigned
13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m[0] = 'b'
13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except TypeError:
13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.fail("Able to write to readonly memory map")
14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Ensuring that readonly mmap can't be write() to
14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.seek(0,0)
14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.write('abc')
14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except TypeError:
14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.fail("Able to write to readonly memory map")
15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Ensuring that readonly mmap can't be write_byte() to
15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.seek(0,0)
15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.write_byte('d')
15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except TypeError:
15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.fail("Able to write to readonly memory map")
16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Ensuring that readonly mmap can't be resized
16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.resize(2*mapsize)
16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except SystemError:   # resize is not universally supported
16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except TypeError:
16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.fail("Able to resize readonly memory map")
17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        del m, f
17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(open(TESTFN, "rb").read(), 'a'*mapsize,
17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh               "Readonly memory map data file was modified")
17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Opening mmap with size too big
17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        import sys
17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, "r+b")
17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m = mmap.mmap(f.fileno(), mapsize+1)
18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except ValueError:
18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # we do not expect a ValueError on Windows
18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # CAUTION:  This also changes the size of the file on disk, and
18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # later tests assume that the length hasn't changed.  We need to
18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # repair that.
18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if sys.platform.startswith('win'):
18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("Opening mmap with size+1 should work on Windows.")
18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # we expect a ValueError on Unix, but not on Windows
18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if not sys.platform.startswith('win'):
19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("Opening mmap with size+1 should raise ValueError.")
19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.close()
19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if sys.platform.startswith('win'):
19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Repair damage from the resizing test.
19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN, 'r+b')
19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.truncate(mapsize)
19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Opening mmap with access=ACCESS_WRITE
20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, "r+b")
20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE)
20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Modifying write-through memory map
20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m[:] = 'c'*mapsize
20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m[:], 'c'*mapsize,
20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh               "Write-through memory map memory not updated properly.")
20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.flush()
20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.close()
20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, 'rb')
21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        stuff = f.read()
21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(stuff, 'c'*mapsize,
21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh               "Write-through memory map data file not updated properly.")
21483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
21583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Opening mmap with access=ACCESS_COPY
21683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, "r+b")
21783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_COPY)
21883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Modifying copy-on-write memory map
21983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m[:] = 'd'*mapsize
22083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m[:], 'd' * mapsize,
22183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh               "Copy-on-write memory map data not written correctly.")
22283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.flush()
22383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(open(TESTFN, "rb").read(), 'c'*mapsize,
22483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh               "Copy-on-write test data file should not be modified.")
22583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Ensuring copy-on-write maps cannot be resized
22683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(TypeError, m.resize, 2*mapsize)
22783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
22883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        del m, f
22983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
23083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Ensuring invalid access parameter raises exception
23183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, "r+b")
23283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize, access=4)
23383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
23483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
23583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if os.name == "posix":
23683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Try incompatible flags, prot and access parameters.
23783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN, "r+b")
23883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize,
23983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                              flags=mmap.MAP_PRIVATE,
24083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                              prot=mmap.PROT_READ, access=mmap.ACCESS_WRITE)
24183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
24283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
24383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Try writing with PROT_EXEC and without PROT_WRITE
24483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            prot = mmap.PROT_READ | getattr(mmap, 'PROT_EXEC', 0)
24583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            with open(TESTFN, "r+b") as f:
24683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m = mmap.mmap(f.fileno(), mapsize, prot=prot)
24783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertRaises(TypeError, m.write, b"abcdef")
24883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertRaises(TypeError, m.write_byte, 0)
24983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m.close()
25083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_bad_file_desc(self):
25283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Try opening a bad file descriptor...
25383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(mmap.error, mmap.mmap, -2, 4096)
25483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_tougher_find(self):
25683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Do a tougher .find() test.  SF bug 515943 pointed out that, in 2.2,
25783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # searching for data with embedded \0 bytes didn't work.
25883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, 'w+')
25983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
26083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        data = 'aabaac\x00deef\x00\x00aa\x00'
26183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        n = len(data)
26283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.write(data)
26383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.flush()
26483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(f.fileno(), n)
26583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
26683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
26783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for start in range(n+1):
26883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for finish in range(start, n+1):
26983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                slice = data[start : finish]
27083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(m.find(slice), data.find(slice))
27183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(m.find(slice + 'x'), -1)
27283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.close()
27383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_find_end(self):
27583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # test the new 'end' parameter works as expected
27683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, 'w+')
27783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        data = 'one two ones'
27883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        n = len(data)
27983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.write(data)
28083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.flush()
28183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(f.fileno(), n)
28283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
28383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
28483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.find('one'), 0)
28583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.find('ones'), 8)
28683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.find('one', 0, -1), 0)
28783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.find('one', 1), 8)
28883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.find('one', 1, -1), 8)
28983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.find('one', 1, -2), -1)
29083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
29183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
29283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_rfind(self):
29383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # test the new 'end' parameter works as expected
29483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, 'w+')
29583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        data = 'one two ones'
29683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        n = len(data)
29783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.write(data)
29883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.flush()
29983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(f.fileno(), n)
30083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
30183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
30283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.rfind('one'), 8)
30383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.rfind('one '), 0)
30483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.rfind('one', 0, -1), 8)
30583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.rfind('one', 0, -2), 0)
30683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.rfind('one', 1, -1), 8)
30783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.rfind('one', 1, -2), -1)
30883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
30983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
31083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_double_close(self):
31183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # make sure a double close doesn't crash on Solaris (Bug# 665913)
31283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, 'w+')
31383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
31483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.write(2**16 * 'a') # Arbitrary character
31583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
31683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
31783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN)
31883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mf = mmap.mmap(f.fileno(), 2**16, access=mmap.ACCESS_READ)
31983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mf.close()
32083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mf.close()
32183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
32283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
32383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_entire_file(self):
32483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # test mapping of entire file by passing 0 for map length
32583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if hasattr(os, "stat"):
32683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN, "w+")
32783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
32883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write(2**16 * 'm') # Arbitrary character
32983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
33083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
33183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN, "rb+")
33283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            mf = mmap.mmap(f.fileno(), 0)
33383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(len(mf), 2**16, "Map size should equal file size.")
33483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(mf.read(2**16), 2**16 * "m")
33583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            mf.close()
33683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
33783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
33883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_length_0_offset(self):
33983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue #10916: test mapping of remainder of file by passing 0 for
34083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # map length with an offset doesn't cause a segfault.
34183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if not hasattr(os, "stat"):
34283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.skipTest("needs os.stat")
34383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # NOTE: allocation granularity is currently 65536 under Win64,
34483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # and therefore the minimum offset alignment.
34583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with open(TESTFN, "wb") as f:
34683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write((65536 * 2) * b'm') # Arbitrary character
34783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
34883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with open(TESTFN, "rb") as f:
34983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            mf = mmap.mmap(f.fileno(), 0, offset=65536, access=mmap.ACCESS_READ)
35083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
35183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertRaises(IndexError, mf.__getitem__, 80000)
35283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            finally:
35383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                mf.close()
35483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
35583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_length_0_large_offset(self):
35683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue #10959: test mapping of a file by passing 0 for
35783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # map length with a large offset doesn't cause a segfault.
35883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if not hasattr(os, "stat"):
35983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.skipTest("needs os.stat")
36083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
36183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with open(TESTFN, "wb") as f:
36283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write(115699 * b'm') # Arbitrary character
36383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
36483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with open(TESTFN, "w+b") as f:
36583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(ValueError, mmap.mmap, f.fileno(), 0,
36683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                              offset=2147418112)
36783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
36883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_move(self):
36983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # make move works everywhere (64-bit format problem earlier)
37083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, 'w+')
37183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
37283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.write("ABCDEabcde") # Arbitrary character
37383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.flush()
37483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
37583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mf = mmap.mmap(f.fileno(), 10)
37683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mf.move(5, 0, 5)
37783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(mf[:], "ABCDEABCDE", "Map move should have duplicated front 5")
37883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mf.close()
37983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
38083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
38183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # more excessive test
38283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        data = "0123456789"
38383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for dest in range(len(data)):
38483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for src in range(len(data)):
38583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                for count in range(len(data) - max(dest, src)):
38683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    expected = data[:dest] + data[src:src+count] + data[dest+count:]
38783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    m = mmap.mmap(-1, len(data))
38883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    m[:] = data
38983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    m.move(dest, src, count)
39083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    self.assertEqual(m[:], expected)
39183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    m.close()
39283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
39383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # segfault test (Issue 5387)
39483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(-1, 100)
39583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        offsets = [-100, -1, 0, 1, 100]
39683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for source, dest, size in itertools.product(offsets, offsets, offsets):
39783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
39883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m.move(source, dest, size)
39983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except ValueError:
40083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
40183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
40283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        offsets = [(-1, -1, -1), (-1, -1, 0), (-1, 0, -1), (0, -1, -1),
40383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                   (-1, 0, 0), (0, -1, 0), (0, 0, -1)]
40483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for source, dest, size in offsets:
40583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(ValueError, m.move, source, dest, size)
40683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
40783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.close()
40883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
40983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(-1, 1) # single byte
41083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ValueError, m.move, 0, 0, 2)
41183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ValueError, m.move, 1, 0, 1)
41283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ValueError, m.move, 0, 1, 1)
41383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.move(0, 0, 1)
41483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.move(0, 0, 0)
41583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
41683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
41783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_anonymous(self):
41883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # anonymous mmap.mmap(-1, PAGE)
41983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(-1, PAGESIZE)
42083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for x in xrange(PAGESIZE):
42183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m[x], '\0', "anonymously mmap'ed contents should be zero")
42283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
42383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for x in xrange(PAGESIZE):
42483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m[x] = ch = chr(x & 255)
42583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m[x], ch)
42683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
42783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_extended_getslice(self):
42883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test extended slicing by comparing with list slicing.
42983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        s = "".join(chr(c) for c in reversed(range(256)))
43083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(-1, len(s))
43183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m[:] = s
43283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m[:], s)
43383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
43483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for start in indices:
43583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for stop in indices:
43683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # Skip step 0 (invalid)
43783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                for step in indices[1:]:
43883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    self.assertEqual(m[start:stop:step],
43983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                     s[start:stop:step])
44083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
44183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_extended_set_del_slice(self):
44283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test extended slicing by comparing with list slicing.
44383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        s = "".join(chr(c) for c in reversed(range(256)))
44483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(-1, len(s))
44583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
44683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for start in indices:
44783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for stop in indices:
44883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # Skip invalid step 0
44983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                for step in indices[1:]:
45083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    m[:] = s
45183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    self.assertEqual(m[:], s)
45283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    L = list(s)
45383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    # Make sure we have a slice of exactly the right length,
45483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    # but with different data.
45583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    data = L[start:stop:step]
45683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    data = "".join(reversed(data))
45783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    L[start:stop:step] = data
45883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    m[start:stop:step] = data
45983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    self.assertEqual(m[:], "".join(L))
46083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
46183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def make_mmap_file (self, f, halfsize):
46283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Write 2 pages worth of data to the file
46383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.write ('\0' * halfsize)
46483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.write ('foo')
46583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.write ('\0' * (halfsize - 3))
46683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.flush ()
46783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return mmap.mmap (f.fileno(), 0)
46883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
46983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_empty_file (self):
47083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open (TESTFN, 'w+b')
47183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
47283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with open(TESTFN, "rb") as f :
47383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
47483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
47583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m.close()
47683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("should not have been able to mmap empty file")
47783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except ValueError as e:
47883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(e.message, "cannot mmap an empty file")
47983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except:
48083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("unexpected exception: " + str(e))
48183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_offset (self):
48383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open (TESTFN, 'w+b')
48483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try: # unlink TESTFN no matter what
48683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            halfsize = mmap.ALLOCATIONGRANULARITY
48783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m = self.make_mmap_file (f, halfsize)
48883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.close ()
48983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close ()
49083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
49183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            mapsize = halfsize * 2
49283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Try invalid offset
49383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN, "r+b")
49483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for offset in [-2, -1, None]:
49583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                try:
49683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    m = mmap.mmap(f.fileno(), mapsize, offset=offset)
49783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    self.assertEqual(0, 1)
49883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                except (ValueError, TypeError, OverflowError):
49983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    pass
50083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                else:
50183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    self.assertEqual(0, 0)
50283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
50383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
50483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Try valid offset, hopefully 8192 works on all OSes
50583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN, "r+b")
50683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m = mmap.mmap(f.fileno(), mapsize - halfsize, offset=halfsize)
50783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m[0:3], 'foo')
50883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
50983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
51083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Try resizing map
51183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
51283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m.resize(512)
51383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except SystemError:
51483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
51583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
51683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # resize() is supported
51783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(len(m), 512)
51883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # Check that we can no longer seek beyond the new size.
51983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertRaises(ValueError, m.seek, 513, 0)
52083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # Check that the content is not changed
52183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(m[0:3], 'foo')
52283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
52383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # Check that the underlying file is truncated too
52483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f = open(TESTFN)
52583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.seek(0, 2)
52683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(f.tell(), halfsize + 512)
52783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.close()
52883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(m.size(), halfsize + 512)
52983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
53083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.close()
53183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
53283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
53383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
53483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
53583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                os.unlink(TESTFN)
53683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except OSError:
53783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
53883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
53983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_subclass(self):
54083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        class anon_mmap(mmap.mmap):
54183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            def __new__(klass, *args, **kwargs):
54283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                return mmap.mmap.__new__(klass, -1, *args, **kwargs)
54383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        anon_mmap(PAGESIZE)
54483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
54583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_prot_readonly(self):
54683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if not hasattr(mmap, 'PROT_READ'):
54783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            return
54883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mapsize = 10
54983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        open(TESTFN, "wb").write("a"*mapsize)
55083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, "rb")
55183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(f.fileno(), mapsize, prot=mmap.PROT_READ)
55283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(TypeError, m.write, "foo")
55383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
55483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
55583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_error(self):
55683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(issubclass(mmap.error, EnvironmentError))
55783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertIn("mmap.error", str(mmap.error))
55883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
55983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_io_methods(self):
56083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        data = "0123456789"
56183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        open(TESTFN, "wb").write("x"*len(data))
56283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, "r+b")
56383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = mmap.mmap(f.fileno(), len(data))
56483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
56583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test write_byte()
56683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for i in xrange(len(data)):
56783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m.tell(), i)
56883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.write_byte(data[i])
56983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m.tell(), i+1)
57083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ValueError, m.write_byte, "x")
57183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m[:], data)
57283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test read_byte()
57383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.seek(0)
57483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for i in xrange(len(data)):
57583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m.tell(), i)
57683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m.read_byte(), data[i])
57783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m.tell(), i+1)
57883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ValueError, m.read_byte)
57983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test read()
58083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.seek(3)
58183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.read(3), "345")
58283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.tell(), 6)
58383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test write()
58483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.seek(3)
58583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.write("bar")
58683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m.tell(), 6)
58783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(m[:], "012bar6789")
58883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m.seek(8)
58983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ValueError, m.write, "bar")
59083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
59183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if os.name == 'nt':
59283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def test_tagname(self):
59383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            data1 = "0123456789"
59483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            data2 = "abcdefghij"
59583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            assert len(data1) == len(data2)
59683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
59783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Test same tag
59883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m1 = mmap.mmap(-1, len(data1), tagname="foo")
59983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m1[:] = data1
60083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m2 = mmap.mmap(-1, len(data2), tagname="foo")
60183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m2[:] = data2
60283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m1[:], data2)
60383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m2[:], data2)
60483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m2.close()
60583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m1.close()
60683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
60783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Test different tag
60883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m1 = mmap.mmap(-1, len(data1), tagname="foo")
60983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m1[:] = data1
61083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m2 = mmap.mmap(-1, len(data2), tagname="boo")
61183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m2[:] = data2
61283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m1[:], data1)
61383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(m2[:], data2)
61483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m2.close()
61583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m1.close()
61683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
61783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def test_crasher_on_windows(self):
61883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Should not crash (Issue 1733986)
61983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m = mmap.mmap(-1, 1000, tagname="foo")
62083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
62183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                mmap.mmap(-1, 5000, tagname="foo")[:] # same tagname, but larger size
62283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except:
62383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
62483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.close()
62583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
62683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Should not crash (Issue 5385)
62783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            open(TESTFN, "wb").write("x"*10)
62883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN, "r+b")
62983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m = mmap.mmap(f.fileno(), 0)
63083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
63183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
63283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m.resize(0) # will raise WindowsError
63383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except:
63483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
63583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
63683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m[:]
63783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except:
63883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
63983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m.close()
64083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
64183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def test_invalid_descriptor(self):
64283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # socket file descriptors are valid, but out of range
64383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # for _get_osfhandle, causing a crash when validating the
64483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # parameters to _get_osfhandle.
64583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            s = socket.socket()
64683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
64783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                with self.assertRaises(mmap.error):
64883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    m = mmap.mmap(s.fileno(), 10)
64983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            finally:
65083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                s.close()
65183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
65283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
65383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass LargeMmapTests(unittest.TestCase):
65483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
65583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def setUp(self):
65683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        unlink(TESTFN)
65783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
65883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def tearDown(self):
65983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        unlink(TESTFN)
66083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
66183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def _make_test_file(self, num_zeroes, tail):
66283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if sys.platform[:3] == 'win' or sys.platform == 'darwin':
66383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            requires('largefile',
66483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                'test requires %s bytes and a long time to run' % str(0x180000000))
66583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, 'w+b')
66683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
66783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(num_zeroes)
66883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write(tail)
66983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.flush()
67083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except (IOError, OverflowError):
67183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
67283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            raise unittest.SkipTest("filesystem does not have largefile support")
67383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return f
67483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
67583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_large_offset(self):
67683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with self._make_test_file(0x14FFFFFFF, b" ") as f:
67783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m = mmap.mmap(f.fileno(), 0, offset=0x140000000, access=mmap.ACCESS_READ)
67883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
67983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(m[0xFFFFFFF], b" ")
68083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            finally:
68183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m.close()
68283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
68383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_large_filesize(self):
68483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with self._make_test_file(0x17FFFFFFF, b" ") as f:
68583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if sys.maxsize < 0x180000000:
68683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # On 32 bit platforms the file is larger than sys.maxsize so
68783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # mapping the whole file should fail -- Issue #16743
68883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                with self.assertRaises(OverflowError):
68983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    mmap.mmap(f.fileno(), 0x180000000, access=mmap.ACCESS_READ)
69083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                with self.assertRaises(ValueError):
69183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
69283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m = mmap.mmap(f.fileno(), 0x10000, access=mmap.ACCESS_READ)
69383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
69483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(m.size(), 0x180000000)
69583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            finally:
69683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m.close()
69783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
69883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Issue 11277: mmap() with large (~4GB) sparse files crashes on OS X.
69983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
70083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def _test_around_boundary(self, boundary):
70183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        tail = b'  DEARdear  '
70283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        start = boundary - len(tail) // 2
70383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        end = start + len(tail)
70483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with self._make_test_file(start, tail) as f:
70583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
70683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
70783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(m[start:end], tail)
70883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            finally:
70983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                m.close()
71083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
71183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    @unittest.skipUnless(sys.maxsize > _4G, "test cannot run on 32-bit systems")
71283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_around_2GB(self):
71383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_around_boundary(_2G)
71483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
71583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    @unittest.skipUnless(sys.maxsize > _4G, "test cannot run on 32-bit systems")
71683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_around_4GB(self):
71783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_around_boundary(_4G)
71883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
71983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
72083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef test_main():
72183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    run_unittest(MmapTests, LargeMmapTests)
72283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
72383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == '__main__':
72483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    test_main()
725