Commit ced10569 authored by Nadeem Vawda's avatar Nadeem Vawda

Issue #11277: Add tests for mmap crash when using large sparse files on OS X.

Also, reduce code duplication in LargeMmapTests.

Original patch by Steffen Daode Nurpmeso.
parent caed7fe0
from test.support import TESTFN, run_unittest, import_module, unlink, requires from test.support import (TESTFN, run_unittest, import_module, unlink,
requires, _2G, _4G)
import unittest import unittest
import os, re, itertools, socket, sys import os, re, itertools, socket, sys
...@@ -653,28 +654,20 @@ class LargeMmapTests(unittest.TestCase): ...@@ -653,28 +654,20 @@ class LargeMmapTests(unittest.TestCase):
def tearDown(self): def tearDown(self):
unlink(TESTFN) unlink(TESTFN)
def _working_largefile(self): def _create_test_file(self, num_zeroes, tail):
# Only run if the current filesystem supports large files.
f = open(TESTFN, 'wb', buffering=0)
try:
f.seek(0x80000001)
f.write(b'x')
f.flush()
except (IOError, OverflowError):
raise unittest.SkipTest("filesystem does not have largefile support")
finally:
f.close()
unlink(TESTFN)
def test_large_offset(self):
if sys.platform[:3] == 'win' or sys.platform == 'darwin': if sys.platform[:3] == 'win' or sys.platform == 'darwin':
requires('largefile', requires('largefile',
'test requires %s bytes and a long time to run' % str(0x180000000)) 'test requires %s bytes and a long time to run' % str(0x180000000))
self._working_largefile()
with open(TESTFN, 'wb') as f: with open(TESTFN, 'wb') as f:
f.seek(0x14FFFFFFF) try:
f.write(b" ") f.seek(num_zeroes)
f.write(tail)
f.flush()
except (IOError, OverflowError):
raise unittest.SkipTest("filesystem does not have largefile support")
def test_large_offset(self):
self._create_test_file(0x14FFFFFFF, b" ")
with open(TESTFN, 'rb') as f: with open(TESTFN, 'rb') as f:
m = mmap.mmap(f.fileno(), 0, offset=0x140000000, access=mmap.ACCESS_READ) m = mmap.mmap(f.fileno(), 0, offset=0x140000000, access=mmap.ACCESS_READ)
try: try:
...@@ -683,14 +676,7 @@ class LargeMmapTests(unittest.TestCase): ...@@ -683,14 +676,7 @@ class LargeMmapTests(unittest.TestCase):
m.close() m.close()
def test_large_filesize(self): def test_large_filesize(self):
if sys.platform[:3] == 'win' or sys.platform == 'darwin': self._create_test_file(0x17FFFFFFF, b" ")
requires('largefile',
'test requires %s bytes and a long time to run' % str(0x180000000))
self._working_largefile()
with open(TESTFN, 'wb') as f:
f.seek(0x17FFFFFFF)
f.write(b" ")
with open(TESTFN, 'rb') as f: with open(TESTFN, 'rb') as f:
m = mmap.mmap(f.fileno(), 0x10000, access=mmap.ACCESS_READ) m = mmap.mmap(f.fileno(), 0x10000, access=mmap.ACCESS_READ)
try: try:
...@@ -698,6 +684,28 @@ class LargeMmapTests(unittest.TestCase): ...@@ -698,6 +684,28 @@ class LargeMmapTests(unittest.TestCase):
finally: finally:
m.close() m.close()
# Issue 11277: mmap() with large (~4GB) sparse files crashes on OS X.
def _test_around_boundary(self, boundary):
tail = b' DEARdear '
start = boundary - len(tail) // 2
end = start + len(tail)
self._create_test_file(start, tail)
with open(TESTFN, 'rb') as f:
m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
try:
self.assertEqual(m[start:end], tail)
finally:
m.close()
@unittest.skipUnless(sys.maxsize > _4G, "test cannot run on 32-bit systems")
def test_around_2GB(self):
self._test_around_boundary(_2G)
@unittest.skipUnless(sys.maxsize > _4G, "test cannot run on 32-bit systems")
def test_around_4GB(self):
self._test_around_boundary(_4G)
def test_main(): def test_main():
run_unittest(MmapTests, LargeMmapTests) run_unittest(MmapTests, LargeMmapTests)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment