From c2745d2d05546d76f655ab450eb23d1af39e0b1c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 5 Jun 2018 19:55:41 +0300 Subject: bpo-33751: Fix test_file. (GH-7378) testModeStrings and testTruncateOnWindows were depended on a file leaked in other tests. Also improve cleaning up after tests. --- Lib/test/test_file.py | 162 ++++++++++++++++++++++++-------------------------- 1 file changed, 78 insertions(+), 84 deletions(-) diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py index 65be30f..9890b8c 100644 --- a/Lib/test/test_file.py +++ b/Lib/test/test_file.py @@ -8,6 +8,7 @@ import io import _pyio as pyio from test.support import TESTFN +from test import support from collections import UserList class AutoFileTests: @@ -19,7 +20,7 @@ class AutoFileTests: def tearDown(self): if self.f: self.f.close() - os.remove(TESTFN) + support.unlink(TESTFN) def testWeakRefs(self): # verify weak references @@ -137,8 +138,12 @@ class PyAutoFileTests(AutoFileTests, unittest.TestCase): class OtherFileTests: + def tearDown(self): + support.unlink(TESTFN) + def testModeStrings(self): # check invalid mode strings + self.open(TESTFN, 'wb').close() for mode in ("", "aU", "wU+", "U+", "+U", "rU+"): try: f = self.open(TESTFN, mode) @@ -185,7 +190,6 @@ class OtherFileTests: # SF bug # "file.truncate fault on windows" - os.unlink(TESTFN) f = self.open(TESTFN, 'wb') try: @@ -209,7 +213,6 @@ class OtherFileTests: self.fail("File size after ftruncate wrong %d" % size) finally: f.close() - os.unlink(TESTFN) def testIteration(self): # Test the complex interaction when mixing file-iteration and the @@ -230,87 +233,84 @@ class OtherFileTests: methods = [("readline", ()), ("read", ()), ("readlines", ()), ("readinto", (array("b", b" "*100),))] + # Prepare the testfile + bag = self.open(TESTFN, "wb") + bag.write(filler * nchunks) + bag.writelines(testlines) + bag.close() + # Test for appropriate errors mixing read* and iteration + for methodname, args in methods: + f = self.open(TESTFN, 'rb') + if next(f) != filler: + self.fail, "Broken testfile" + meth = getattr(f, methodname) + meth(*args) # This simply shouldn't fail + f.close() + + # Test to see if harmless (by accident) mixing of read* and + # iteration still works. This depends on the size of the internal + # iteration buffer (currently 8192,) but we can test it in a + # flexible manner. Each line in the bag o' ham is 4 bytes + # ("h", "a", "m", "\n"), so 4096 lines of that should get us + # exactly on the buffer boundary for any power-of-2 buffersize + # between 4 and 16384 (inclusive). + f = self.open(TESTFN, 'rb') + for i in range(nchunks): + next(f) + testline = testlines.pop(0) try: - # Prepare the testfile - bag = self.open(TESTFN, "wb") - bag.write(filler * nchunks) - bag.writelines(testlines) - bag.close() - # Test for appropriate errors mixing read* and iteration - for methodname, args in methods: - f = self.open(TESTFN, 'rb') - if next(f) != filler: - self.fail, "Broken testfile" - meth = getattr(f, methodname) - meth(*args) # This simply shouldn't fail - f.close() + line = f.readline() + except ValueError: + self.fail("readline() after next() with supposedly empty " + "iteration-buffer failed anyway") + if line != testline: + self.fail("readline() after next() with empty buffer " + "failed. Got %r, expected %r" % (line, testline)) + testline = testlines.pop(0) + buf = array("b", b"\x00" * len(testline)) + try: + f.readinto(buf) + except ValueError: + self.fail("readinto() after next() with supposedly empty " + "iteration-buffer failed anyway") + line = buf.tobytes() + if line != testline: + self.fail("readinto() after next() with empty buffer " + "failed. Got %r, expected %r" % (line, testline)) + + testline = testlines.pop(0) + try: + line = f.read(len(testline)) + except ValueError: + self.fail("read() after next() with supposedly empty " + "iteration-buffer failed anyway") + if line != testline: + self.fail("read() after next() with empty buffer " + "failed. Got %r, expected %r" % (line, testline)) + try: + lines = f.readlines() + except ValueError: + self.fail("readlines() after next() with supposedly empty " + "iteration-buffer failed anyway") + if lines != testlines: + self.fail("readlines() after next() with empty buffer " + "failed. Got %r, expected %r" % (line, testline)) + f.close() - # Test to see if harmless (by accident) mixing of read* and - # iteration still works. This depends on the size of the internal - # iteration buffer (currently 8192,) but we can test it in a - # flexible manner. Each line in the bag o' ham is 4 bytes - # ("h", "a", "m", "\n"), so 4096 lines of that should get us - # exactly on the buffer boundary for any power-of-2 buffersize - # between 4 and 16384 (inclusive). - f = self.open(TESTFN, 'rb') - for i in range(nchunks): - next(f) - testline = testlines.pop(0) - try: - line = f.readline() - except ValueError: - self.fail("readline() after next() with supposedly empty " - "iteration-buffer failed anyway") - if line != testline: - self.fail("readline() after next() with empty buffer " - "failed. Got %r, expected %r" % (line, testline)) - testline = testlines.pop(0) - buf = array("b", b"\x00" * len(testline)) + # Reading after iteration hit EOF shouldn't hurt either + f = self.open(TESTFN, 'rb') + try: + for line in f: + pass try: + f.readline() f.readinto(buf) + f.read() + f.readlines() except ValueError: - self.fail("readinto() after next() with supposedly empty " - "iteration-buffer failed anyway") - line = buf.tobytes() - if line != testline: - self.fail("readinto() after next() with empty buffer " - "failed. Got %r, expected %r" % (line, testline)) - - testline = testlines.pop(0) - try: - line = f.read(len(testline)) - except ValueError: - self.fail("read() after next() with supposedly empty " - "iteration-buffer failed anyway") - if line != testline: - self.fail("read() after next() with empty buffer " - "failed. Got %r, expected %r" % (line, testline)) - try: - lines = f.readlines() - except ValueError: - self.fail("readlines() after next() with supposedly empty " - "iteration-buffer failed anyway") - if lines != testlines: - self.fail("readlines() after next() with empty buffer " - "failed. Got %r, expected %r" % (line, testline)) - f.close() - - # Reading after iteration hit EOF shouldn't hurt either - f = self.open(TESTFN, 'rb') - try: - for line in f: - pass - try: - f.readline() - f.readinto(buf) - f.read() - f.readlines() - except ValueError: - self.fail("read* failed after next() consumed file") - finally: - f.close() + self.fail("read* failed after next() consumed file") finally: - os.unlink(TESTFN) + f.close() class COtherFileTests(OtherFileTests, unittest.TestCase): open = io.open @@ -319,11 +319,5 @@ class PyOtherFileTests(OtherFileTests, unittest.TestCase): open = staticmethod(pyio.open) -def tearDownModule(): - # Historically, these tests have been sloppy about removing TESTFN. - # So get rid of it no matter what. - if os.path.exists(TESTFN): - os.unlink(TESTFN) - if __name__ == '__main__': unittest.main() -- cgit v0.12