Commit c406a121 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #18266: test_largefile now works with unittest test discovery and

supports running only selected tests.  Patch by Zachary Ware.
parent 880254e2
...@@ -5,55 +5,50 @@ import os ...@@ -5,55 +5,50 @@ import os
import stat import stat
import sys import sys
import unittest import unittest
from test.support import run_unittest, TESTFN, verbose, requires, \ from test.support import TESTFN, requires, unlink
unlink
import io # C implementation of io import io # C implementation of io
import _pyio as pyio # Python implementation of io import _pyio as pyio # Python implementation of io
try: # size of file to create (>2GB; 2GB == 2147483648 bytes)
import signal
# The default handler for SIGXFSZ is to abort the process.
# By ignoring it, system calls exceeding the file size resource
# limit will raise IOError instead of crashing the interpreter.
oldhandler = signal.signal(signal.SIGXFSZ, signal.SIG_IGN)
except (ImportError, AttributeError):
pass
# create >2GB file (2GB = 2147483648 bytes)
size = 2500000000 size = 2500000000
class LargeFileTest:
"""Test that each file function works as expected for large
(i.e. > 2GB) files.
"""
class LargeFileTest(unittest.TestCase): def setUp(self):
"""Test that each file function works as expected for a large if os.path.exists(TESTFN):
(i.e. > 2GB, do we have to check > 4GB) files. mode = 'r+b'
else:
mode = 'w+b'
NOTE: the order of execution of the test methods is important! test_seek with self.open(TESTFN, mode) as f:
must run first to create the test file. File cleanup must also be handled current_size = os.fstat(f.fileno())[stat.ST_SIZE]
outside the test instances because of this. if current_size == size+1:
return
""" if current_size == 0:
f.write(b'z')
def test_seek(self):
if verbose:
print('create large file via seek (may be sparse file) ...')
with self.open(TESTFN, 'wb') as f:
f.write(b'z')
f.seek(0) f.seek(0)
f.seek(size) f.seek(size)
f.write(b'a') f.write(b'a')
f.flush() f.flush()
if verbose:
print('check file size with os.fstat')
self.assertEqual(os.fstat(f.fileno())[stat.ST_SIZE], size+1) self.assertEqual(os.fstat(f.fileno())[stat.ST_SIZE], size+1)
@classmethod
def tearDownClass(cls):
with cls.open(TESTFN, 'wb'):
pass
if not os.stat(TESTFN)[stat.ST_SIZE] == 0:
raise cls.failureException('File was not truncated by opening '
'with mode "wb"')
def test_osstat(self): def test_osstat(self):
if verbose:
print('check file size with os.stat')
self.assertEqual(os.stat(TESTFN)[stat.ST_SIZE], size+1) self.assertEqual(os.stat(TESTFN)[stat.ST_SIZE], size+1)
def test_seek_read(self): def test_seek_read(self):
if verbose:
print('play around with seek() and read() with the built largefile')
with self.open(TESTFN, 'rb') as f: with self.open(TESTFN, 'rb') as f:
self.assertEqual(f.tell(), 0) self.assertEqual(f.tell(), 0)
self.assertEqual(f.read(1), b'z') self.assertEqual(f.read(1), b'z')
...@@ -85,8 +80,6 @@ class LargeFileTest(unittest.TestCase): ...@@ -85,8 +80,6 @@ class LargeFileTest(unittest.TestCase):
self.assertEqual(f.tell(), 1) self.assertEqual(f.tell(), 1)
def test_lseek(self): def test_lseek(self):
if verbose:
print('play around with os.lseek() with the built largefile')
with self.open(TESTFN, 'rb') as f: with self.open(TESTFN, 'rb') as f:
self.assertEqual(os.lseek(f.fileno(), 0, 0), 0) self.assertEqual(os.lseek(f.fileno(), 0, 0), 0)
self.assertEqual(os.lseek(f.fileno(), 42, 0), 42) self.assertEqual(os.lseek(f.fileno(), 42, 0), 42)
...@@ -100,13 +93,10 @@ class LargeFileTest(unittest.TestCase): ...@@ -100,13 +93,10 @@ class LargeFileTest(unittest.TestCase):
self.assertEqual(f.read(1), b'a') self.assertEqual(f.read(1), b'a')
def test_truncate(self): def test_truncate(self):
if verbose:
print('try truncate')
with self.open(TESTFN, 'r+b') as f: with self.open(TESTFN, 'r+b') as f:
# this is already decided before start running the test suite
# but we do it anyway for extra protection
if not hasattr(f, 'truncate'): if not hasattr(f, 'truncate'):
raise unittest.SkipTest("open().truncate() not available on this system") raise unittest.SkipTest("open().truncate() not available "
"on this system")
f.seek(0, 2) f.seek(0, 2)
# else we've lost track of the true size # else we've lost track of the true size
self.assertEqual(f.tell(), size+1) self.assertEqual(f.tell(), size+1)
...@@ -141,8 +131,16 @@ class LargeFileTest(unittest.TestCase): ...@@ -141,8 +131,16 @@ class LargeFileTest(unittest.TestCase):
f.seek(pos) f.seek(pos)
self.assertTrue(f.seekable()) self.assertTrue(f.seekable())
def setUpModule():
try:
import signal
# The default handler for SIGXFSZ is to abort the process.
# By ignoring it, system calls exceeding the file size resource
# limit will raise OSError instead of crashing the interpreter.
signal.signal(signal.SIGXFSZ, signal.SIG_IGN)
except (ImportError, AttributeError):
pass
def test_main():
# On Windows and Mac OSX this test comsumes large resources; It # On Windows and Mac OSX this test comsumes large resources; It
# takes a long time to build the >2GB file and takes >2GB of disk # takes a long time to build the >2GB file and takes >2GB of disk
# space therefore the resource must be enabled to run this test. # space therefore the resource must be enabled to run this test.
...@@ -158,35 +156,25 @@ def test_main(): ...@@ -158,35 +156,25 @@ def test_main():
try: try:
# 2**31 == 2147483648 # 2**31 == 2147483648
f.seek(2147483649) f.seek(2147483649)
# Seeking is not enough of a test: you must write and # Seeking is not enough of a test: you must write and flush, too!
# flush, too!
f.write(b'x') f.write(b'x')
f.flush() f.flush()
except (IOError, OverflowError): except (IOError, OverflowError):
raise unittest.SkipTest("filesystem does not have "
"largefile support")
finally:
f.close() f.close()
unlink(TESTFN) unlink(TESTFN)
raise unittest.SkipTest("filesystem does not have largefile support")
else:
f.close() class CLargeFileTest(LargeFileTest, unittest.TestCase):
suite = unittest.TestSuite() open = staticmethod(io.open)
for _open, prefix in [(io.open, 'C'), (pyio.open, 'Py')]:
class TestCase(LargeFileTest): class PyLargeFileTest(LargeFileTest, unittest.TestCase):
pass open = staticmethod(pyio.open)
TestCase.open = staticmethod(_open)
TestCase.__name__ = prefix + LargeFileTest.__name__ def tearDownModule():
suite.addTest(TestCase('test_seek')) unlink(TESTFN)
suite.addTest(TestCase('test_osstat'))
suite.addTest(TestCase('test_seek_read'))
suite.addTest(TestCase('test_lseek'))
with _open(TESTFN, 'wb') as f:
if hasattr(f, 'truncate'):
suite.addTest(TestCase('test_truncate'))
suite.addTest(TestCase('test_seekable'))
unlink(TESTFN)
try:
run_unittest(suite)
finally:
unlink(TESTFN)
if __name__ == '__main__': if __name__ == '__main__':
test_main() unittest.main()
...@@ -198,6 +198,9 @@ IDLE ...@@ -198,6 +198,9 @@ IDLE
Tests Tests
----- -----
- Issue #18266: test_largefile now works with unittest test discovery and
supports running only selected tests. Patch by Zachary Ware.
- Issue #17767: test_locale now works with unittest test discovery. - Issue #17767: test_locale now works with unittest test discovery.
Original patch by Zachary Ware. Original patch by Zachary Ware.
......
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