Home | History | Annotate | Download | only in test
      1 from test.test_support import (TESTFN, run_unittest, import_module, unlink,
      2                                requires, _2G, _4G)
      3 import unittest
      4 import os, re, itertools, socket, sys
      5 
      6 mmap = import_module('mmap')
      7 
      8 PAGESIZE = mmap.PAGESIZE
      9 
     10 class MmapTests(unittest.TestCase):
     11 
     12     def setUp(self):
     13         if os.path.exists(TESTFN):
     14             os.unlink(TESTFN)
     15 
     16     def tearDown(self):
     17         try:
     18             os.unlink(TESTFN)
     19         except OSError:
     20             pass
     21 
     22     def test_basic(self):
     23         # Test mmap module on Unix systems and Windows
     24 
     25         # Create a file to be mmap'ed.
     26         f = open(TESTFN, 'w+')
     27         try:
     28             # Write 2 pages worth of data to the file
     29             f.write('\0'* PAGESIZE)
     30             f.write('foo')
     31             f.write('\0'* (PAGESIZE-3) )
     32             f.flush()
     33             m = mmap.mmap(f.fileno(), 2 * PAGESIZE)
     34             f.close()
     35 
     36             # Simple sanity checks
     37 
     38             tp = str(type(m))  # SF bug 128713:  segfaulted on Linux
     39             self.assertEqual(m.find('foo'), PAGESIZE)
     40 
     41             self.assertEqual(len(m), 2*PAGESIZE)
     42 
     43             self.assertEqual(m[0], '\0')
     44             self.assertEqual(m[0:3], '\0\0\0')
     45 
     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')
     49 
     50             # Modify the file's content
     51             m[0] = '3'
     52             m[PAGESIZE +3: PAGESIZE +3+3] = 'bar'
     53 
     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')
     58 
     59             m.flush()
     60 
     61             # Test doing a regular expression match in an mmap'ed file
     62             match = re.search('[A-Za-z]+', m)
     63             if match is None:
     64                 self.fail('regex match on mmap failed!')
     65             else:
     66                 start, end = match.span(0)
     67                 length = end - start
     68 
     69                 self.assertEqual(start, PAGESIZE)
     70                 self.assertEqual(end, PAGESIZE + 6)
     71 
     72             # test seeking around (try to overflow the seek implementation)
     73             m.seek(0,0)
     74             self.assertEqual(m.tell(), 0)
     75             m.seek(42,1)
     76             self.assertEqual(m.tell(), 42)
     77             m.seek(0,2)
     78             self.assertEqual(m.tell(), len(m))
     79 
     80             # Try to seek to negative position...
     81             self.assertRaises(ValueError, m.seek, -1)
     82 
     83             # Try to seek beyond end of mmap...
     84             self.assertRaises(ValueError, m.seek, 1, 2)
     85 
     86             # Try to seek to negative position...
     87             self.assertRaises(ValueError, m.seek, -len(m)-1, 2)
     88 
     89             # Try resizing map
     90             try:
     91                 m.resize(512)
     92             except SystemError:
     93                 # resize() not supported
     94                 # No messages are printed, since the output of this test suite
     95                 # would then be different across platforms.
     96                 pass
     97             else:
     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)
    102 
    103                 # Check that the underlying file is truncated too
    104                 # (bug #728515)
    105                 f = open(TESTFN)
    106                 f.seek(0, 2)
    107                 self.assertEqual(f.tell(), 512)
    108                 f.close()
    109                 self.assertEqual(m.size(), 512)
    110 
    111             m.close()
    112 
    113         finally:
    114             try:
    115                 f.close()
    116             except OSError:
    117                 pass
    118 
    119     def test_access_parameter(self):
    120         # Test for "access" keyword parameter
    121         mapsize = 10
    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.")
    126 
    127         # Ensuring that readonly mmap can't be slice assigned
    128         try:
    129             m[:] = 'b'*mapsize
    130         except TypeError:
    131             pass
    132         else:
    133             self.fail("Able to write to readonly memory map")
    134 
    135         # Ensuring that readonly mmap can't be item assigned
    136         try:
    137             m[0] = 'b'
    138         except TypeError:
    139             pass
    140         else:
    141             self.fail("Able to write to readonly memory map")
    142 
    143         # Ensuring that readonly mmap can't be write() to
    144         try:
    145             m.seek(0,0)
    146             m.write('abc')
    147         except TypeError:
    148             pass
    149         else:
    150             self.fail("Able to write to readonly memory map")
    151 
    152         # Ensuring that readonly mmap can't be write_byte() to
    153         try:
    154             m.seek(0,0)
    155             m.write_byte('d')
    156         except TypeError:
    157             pass
    158         else:
    159             self.fail("Able to write to readonly memory map")
    160 
    161         # Ensuring that readonly mmap can't be resized
    162         try:
    163             m.resize(2*mapsize)
    164         except SystemError:   # resize is not universally supported
    165             pass
    166         except TypeError:
    167             pass
    168         else:
    169             self.fail("Able to resize readonly memory map")
    170         f.close()
    171         del m, f
    172         self.assertEqual(open(TESTFN, "rb").read(), 'a'*mapsize,
    173                "Readonly memory map data file was modified")
    174 
    175         # Opening mmap with size too big
    176         import sys
    177         f = open(TESTFN, "r+b")
    178         try:
    179             m = mmap.mmap(f.fileno(), mapsize+1)
    180         except ValueError:
    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
    184             # repair that.
    185             if sys.platform.startswith('win'):
    186                 self.fail("Opening mmap with size+1 should work on Windows.")
    187         else:
    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.")
    191             m.close()
    192         f.close()
    193         if sys.platform.startswith('win'):
    194             # Repair damage from the resizing test.
    195             f = open(TESTFN, 'r+b')
    196             f.truncate(mapsize)
    197             f.close()
    198 
    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
    203         m[:] = 'c'*mapsize
    204         self.assertEqual(m[:], 'c'*mapsize,
    205                "Write-through memory map memory not updated properly.")
    206         m.flush()
    207         m.close()
    208         f.close()
    209         f = open(TESTFN, 'rb')
    210         stuff = f.read()
    211         f.close()
    212         self.assertEqual(stuff, 'c'*mapsize,
    213                "Write-through memory map data file not updated properly.")
    214 
    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
    219         m[:] = 'd'*mapsize
    220         self.assertEqual(m[:], 'd' * mapsize,
    221                "Copy-on-write memory map data not written correctly.")
    222         m.flush()
    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)
    227         f.close()
    228         del m, f
    229 
    230         # Ensuring invalid access parameter raises exception
    231         f = open(TESTFN, "r+b")
    232         self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize, access=4)
    233         f.close()
    234 
    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)
    241             f.close()
    242 
    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)
    249                 m.close()
    250 
    251     def test_bad_file_desc(self):
    252         # Try opening a bad file descriptor...
    253         self.assertRaises(mmap.error, mmap.mmap, -2, 4096)
    254 
    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+')
    259 
    260         data = 'aabaac\x00deef\x00\x00aa\x00'
    261         n = len(data)
    262         f.write(data)
    263         f.flush()
    264         m = mmap.mmap(f.fileno(), n)
    265         f.close()
    266 
    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)
    272         m.close()
    273 
    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'
    278         n = len(data)
    279         f.write(data)
    280         f.flush()
    281         m = mmap.mmap(f.fileno(), n)
    282         f.close()
    283 
    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)
    290 
    291 
    292     def test_rfind(self):
    293         # test the new 'end' parameter works as expected
    294         f = open(TESTFN, 'w+')
    295         data = 'one two ones'
    296         n = len(data)
    297         f.write(data)
    298         f.flush()
    299         m = mmap.mmap(f.fileno(), n)
    300         f.close()
    301 
    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)
    308 
    309 
    310     def test_double_close(self):
    311         # make sure a double close doesn't crash on Solaris (Bug# 665913)
    312         f = open(TESTFN, 'w+')
    313 
    314         f.write(2**16 * 'a') # Arbitrary character
    315         f.close()
    316 
    317         f = open(TESTFN)
    318         mf = mmap.mmap(f.fileno(), 2**16, access=mmap.ACCESS_READ)
    319         mf.close()
    320         mf.close()
    321         f.close()
    322 
    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+")
    327 
    328             f.write(2**16 * 'm') # Arbitrary character
    329             f.close()
    330 
    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")
    335             mf.close()
    336             f.close()
    337 
    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
    347 
    348         with open(TESTFN, "rb") as f:
    349             mf = mmap.mmap(f.fileno(), 0, offset=65536, access=mmap.ACCESS_READ)
    350             try:
    351                 self.assertRaises(IndexError, mf.__getitem__, 80000)
    352             finally:
    353                 mf.close()
    354 
    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")
    360 
    361         with open(TESTFN, "wb") as f:
    362             f.write(115699 * b'm') # Arbitrary character
    363 
    364         with open(TESTFN, "w+b") as f:
    365             self.assertRaises(ValueError, mmap.mmap, f.fileno(), 0,
    366                               offset=2147418112)
    367 
    368     def test_move(self):
    369         # make move works everywhere (64-bit format problem earlier)
    370         f = open(TESTFN, 'w+')
    371 
    372         f.write("ABCDEabcde") # Arbitrary character
    373         f.flush()
    374 
    375         mf = mmap.mmap(f.fileno(), 10)
    376         mf.move(5, 0, 5)
    377         self.assertEqual(mf[:], "ABCDEABCDE", "Map move should have duplicated front 5")
    378         mf.close()
    379         f.close()
    380 
    381         # more excessive test
    382         data = "0123456789"
    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))
    388                     m[:] = data
    389                     m.move(dest, src, count)
    390                     self.assertEqual(m[:], expected)
    391                     m.close()
    392 
    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):
    397             try:
    398                 m.move(source, dest, size)
    399             except ValueError:
    400                 pass
    401 
    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)
    406 
    407         m.close()
    408 
    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)
    413         m.move(0, 0, 1)
    414         m.move(0, 0, 0)
    415 
    416 
    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")
    422 
    423         for x in xrange(PAGESIZE):
    424             m[x] = ch = chr(x & 255)
    425             self.assertEqual(m[x], ch)
    426 
    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))
    431         m[:] = s
    432         self.assertEqual(m[:], s)
    433         indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
    434         for start in indices:
    435             for stop in indices:
    436                 # Skip step 0 (invalid)
    437                 for step in indices[1:]:
    438                     self.assertEqual(m[start:stop:step],
    439                                      s[start:stop:step])
    440 
    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:
    447             for stop in indices:
    448                 # Skip invalid step 0
    449                 for step in indices[1:]:
    450                     m[:] = s
    451                     self.assertEqual(m[:], s)
    452                     L = list(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))
    460 
    461     def make_mmap_file (self, f, halfsize):
    462         # Write 2 pages worth of data to the file
    463         f.write ('\0' * halfsize)
    464         f.write ('foo')
    465         f.write ('\0' * (halfsize - 3))
    466         f.flush ()
    467         return mmap.mmap (f.fileno(), 0)
    468 
    469     def test_empty_file (self):
    470         f = open (TESTFN, 'w+b')
    471         f.close()
    472         with open(TESTFN, "rb") as f :
    473             try:
    474                 m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
    475                 m.close()
    476                 self.fail("should not have been able to mmap empty file")
    477             except ValueError as e:
    478                 self.assertEqual(e.message, "cannot mmap an empty file")
    479             except:
    480                 self.fail("unexpected exception: " + str(e))
    481 
    482     def test_offset (self):
    483         f = open (TESTFN, 'w+b')
    484 
    485         try: # unlink TESTFN no matter what
    486             halfsize = mmap.ALLOCATIONGRANULARITY
    487             m = self.make_mmap_file (f, halfsize)
    488             m.close ()
    489             f.close ()
    490 
    491             mapsize = halfsize * 2
    492             # Try invalid offset
    493             f = open(TESTFN, "r+b")
    494             for offset in [-2, -1, None]:
    495                 try:
    496                     m = mmap.mmap(f.fileno(), mapsize, offset=offset)
    497                     self.assertEqual(0, 1)
    498                 except (ValueError, TypeError, OverflowError):
    499                     pass
    500                 else:
    501                     self.assertEqual(0, 0)
    502             f.close()
    503 
    504             # Try valid offset, hopefully 8192 works on all OSes
    505             f = open(TESTFN, "r+b")
    506             m = mmap.mmap(f.fileno(), mapsize - halfsize, offset=halfsize)
    507             self.assertEqual(m[0:3], 'foo')
    508             f.close()
    509 
    510             # Try resizing map
    511             try:
    512                 m.resize(512)
    513             except SystemError:
    514                 pass
    515             else:
    516                 # resize() is supported
    517                 self.assertEqual(len(m), 512)
    518                 # Check that we can no longer seek beyond the new size.
    519                 self.assertRaises(ValueError, m.seek, 513, 0)
    520                 # Check that the content is not changed
    521                 self.assertEqual(m[0:3], 'foo')
    522 
    523                 # Check that the underlying file is truncated too
    524                 f = open(TESTFN)
    525                 f.seek(0, 2)
    526                 self.assertEqual(f.tell(), halfsize + 512)
    527                 f.close()
    528                 self.assertEqual(m.size(), halfsize + 512)
    529 
    530             m.close()
    531 
    532         finally:
    533             f.close()
    534             try:
    535                 os.unlink(TESTFN)
    536             except OSError:
    537                 pass
    538 
    539     def test_subclass(self):
    540         class anon_mmap(mmap.mmap):
    541             def __new__(klass, *args, **kwargs):
    542                 return mmap.mmap.__new__(klass, -1, *args, **kwargs)
    543         anon_mmap(PAGESIZE)
    544 
    545     def test_prot_readonly(self):
    546         if not hasattr(mmap, 'PROT_READ'):
    547             return
    548         mapsize = 10
    549         open(TESTFN, "wb").write("a"*mapsize)
    550         f = open(TESTFN, "rb")
    551         m = mmap.mmap(f.fileno(), mapsize, prot=mmap.PROT_READ)
    552         self.assertRaises(TypeError, m.write, "foo")
    553         f.close()
    554 
    555     def test_error(self):
    556         self.assertTrue(issubclass(mmap.error, EnvironmentError))
    557         self.assertIn("mmap.error", str(mmap.error))
    558 
    559     def test_io_methods(self):
    560         data = "0123456789"
    561         open(TESTFN, "wb").write("x"*len(data))
    562         f = open(TESTFN, "r+b")
    563         m = mmap.mmap(f.fileno(), len(data))
    564         f.close()
    565         # Test write_byte()
    566         for i in xrange(len(data)):
    567             self.assertEqual(m.tell(), i)
    568             m.write_byte(data[i])
    569             self.assertEqual(m.tell(), i+1)
    570         self.assertRaises(ValueError, m.write_byte, "x")
    571         self.assertEqual(m[:], data)
    572         # Test read_byte()
    573         m.seek(0)
    574         for i in xrange(len(data)):
    575             self.assertEqual(m.tell(), i)
    576             self.assertEqual(m.read_byte(), data[i])
    577             self.assertEqual(m.tell(), i+1)
    578         self.assertRaises(ValueError, m.read_byte)
    579         # Test read()
    580         m.seek(3)
    581         self.assertEqual(m.read(3), "345")
    582         self.assertEqual(m.tell(), 6)
    583         # Test write()
    584         m.seek(3)
    585         m.write("bar")
    586         self.assertEqual(m.tell(), 6)
    587         self.assertEqual(m[:], "012bar6789")
    588         m.seek(8)
    589         self.assertRaises(ValueError, m.write, "bar")
    590 
    591     if os.name == 'nt':
    592         def test_tagname(self):
    593             data1 = "0123456789"
    594             data2 = "abcdefghij"
    595             assert len(data1) == len(data2)
    596 
    597             # Test same tag
    598             m1 = mmap.mmap(-1, len(data1), tagname="foo")
    599             m1[:] = data1
    600             m2 = mmap.mmap(-1, len(data2), tagname="foo")
    601             m2[:] = data2
    602             self.assertEqual(m1[:], data2)
    603             self.assertEqual(m2[:], data2)
    604             m2.close()
    605             m1.close()
    606 
    607             # Test different tag
    608             m1 = mmap.mmap(-1, len(data1), tagname="foo")
    609             m1[:] = data1
    610             m2 = mmap.mmap(-1, len(data2), tagname="boo")
    611             m2[:] = data2
    612             self.assertEqual(m1[:], data1)
    613             self.assertEqual(m2[:], data2)
    614             m2.close()
    615             m1.close()
    616 
    617         def test_crasher_on_windows(self):
    618             # Should not crash (Issue 1733986)
    619             m = mmap.mmap(-1, 1000, tagname="foo")
    620             try:
    621                 mmap.mmap(-1, 5000, tagname="foo")[:] # same tagname, but larger size
    622             except:
    623                 pass
    624             m.close()
    625 
    626             # Should not crash (Issue 5385)
    627             open(TESTFN, "wb").write("x"*10)
    628             f = open(TESTFN, "r+b")
    629             m = mmap.mmap(f.fileno(), 0)
    630             f.close()
    631             try:
    632                 m.resize(0) # will raise WindowsError
    633             except:
    634                 pass
    635             try:
    636                 m[:]
    637             except:
    638                 pass
    639             m.close()
    640 
    641         def test_invalid_descriptor(self):
    642             # socket file descriptors are valid, but out of range
    643             # for _get_osfhandle, causing a crash when validating the
    644             # parameters to _get_osfhandle.
    645             s = socket.socket()
    646             try:
    647                 with self.assertRaises(mmap.error):
    648                     m = mmap.mmap(s.fileno(), 10)
    649             finally:
    650                 s.close()
    651 
    652 
    653 class LargeMmapTests(unittest.TestCase):
    654 
    655     def setUp(self):
    656         unlink(TESTFN)
    657 
    658     def tearDown(self):
    659         unlink(TESTFN)
    660 
    661     def _make_test_file(self, num_zeroes, tail):
    662         if sys.platform[:3] == 'win' or sys.platform == 'darwin':
    663             requires('largefile',
    664                 'test requires %s bytes and a long time to run' % str(0x180000000))
    665         f = open(TESTFN, 'w+b')
    666         try:
    667             f.seek(num_zeroes)
    668             f.write(tail)
    669             f.flush()
    670         except (IOError, OverflowError):
    671             f.close()
    672             raise unittest.SkipTest("filesystem does not have largefile support")
    673         return f
    674 
    675     def test_large_offset(self):
    676         with self._make_test_file(0x14FFFFFFF, b" ") as f:
    677             m = mmap.mmap(f.fileno(), 0, offset=0x140000000, access=mmap.ACCESS_READ)
    678             try:
    679                 self.assertEqual(m[0xFFFFFFF], b" ")
    680             finally:
    681                 m.close()
    682 
    683     def test_large_filesize(self):
    684         with self._make_test_file(0x17FFFFFFF, b" ") as f:
    685             if sys.maxsize < 0x180000000:
    686                 # On 32 bit platforms the file is larger than sys.maxsize so
    687                 # mapping the whole file should fail -- Issue #16743
    688                 with self.assertRaises(OverflowError):
    689                     mmap.mmap(f.fileno(), 0x180000000, access=mmap.ACCESS_READ)
    690                 with self.assertRaises(ValueError):
    691                     mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
    692             m = mmap.mmap(f.fileno(), 0x10000, access=mmap.ACCESS_READ)
    693             try:
    694                 self.assertEqual(m.size(), 0x180000000)
    695             finally:
    696                 m.close()
    697 
    698     # Issue 11277: mmap() with large (~4GB) sparse files crashes on OS X.
    699 
    700     def _test_around_boundary(self, boundary):
    701         tail = b'  DEARdear  '
    702         start = boundary - len(tail) // 2
    703         end = start + len(tail)
    704         with self._make_test_file(start, tail) as f:
    705             m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
    706             try:
    707                 self.assertEqual(m[start:end], tail)
    708             finally:
    709                 m.close()
    710 
    711     @unittest.skipUnless(sys.maxsize > _4G, "test cannot run on 32-bit systems")
    712     def test_around_2GB(self):
    713         self._test_around_boundary(_2G)
    714 
    715     @unittest.skipUnless(sys.maxsize > _4G, "test cannot run on 32-bit systems")
    716     def test_around_4GB(self):
    717         self._test_around_boundary(_4G)
    718 
    719 
    720 def test_main():
    721     run_unittest(MmapTests, LargeMmapTests)
    722 
    723 if __name__ == '__main__':
    724     test_main()
    725