183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""Test largefile support on system where this makes sense.
283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""
383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom __future__ import print_function
583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport os
783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport stat
883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport sys
983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport unittest
1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom test.test_support import run_unittest, TESTFN, verbose, requires, \
1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                              unlink
1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport io  # C implementation of io
1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport _pyio as pyio # Python implementation of io
1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehtry:
1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    import signal
1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # The default handler for SIGXFSZ is to abort the process.
1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # By ignoring it, system calls exceeding the file size resource
1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # limit will raise IOError instead of crashing the interpreter.
2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    oldhandler = signal.signal(signal.SIGXFSZ, signal.SIG_IGN)
2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehexcept (ImportError, AttributeError):
2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    pass
2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# create >2GB file (2GB = 2147483648 bytes)
2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehsize = 2500000000
2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass LargeFileTest(unittest.TestCase):
2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """Test that each file function works as expected for a large
3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    (i.e. > 2GB, do  we have to check > 4GB) files.
3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    NOTE: the order of execution of the test methods is important! test_seek
3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    must run first to create the test file. File cleanup must also be handled
3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    outside the test instances because of this.
3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_seek(self):
3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if verbose:
4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print('create large file via seek (may be sparse file) ...')
4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with self.open(TESTFN, 'wb') as f:
4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write(b'z')
4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(0)
4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(size)
4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write(b'a')
4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.flush()
4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if verbose:
4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                print('check file size with os.fstat')
4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(os.fstat(f.fileno())[stat.ST_SIZE], size+1)
5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_osstat(self):
5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if verbose:
5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print('check file size with os.stat')
5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(os.stat(TESTFN)[stat.ST_SIZE], size+1)
5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_seek_read(self):
5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if verbose:
5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print('play around with seek() and read() with the built largefile')
5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with self.open(TESTFN, 'rb') as f:
6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), 0)
6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.read(1), b'z')
6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), 1)
6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(0)
6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), 0)
6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(0, 0)
6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), 0)
6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(42)
6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), 42)
6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(42, 0)
7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), 42)
7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(42, 1)
7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), 84)
7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(0, 1)
7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), 84)
7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(0, 2)  # seek from the end
7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), size + 1 + 0)
7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(-10, 2)
7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), size + 1 - 10)
7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(-size-1, 2)
8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), 0)
8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(size)
8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), size)
8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # the 'a' that was written at the end of file above
8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.read(1), b'a')
8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(-size-1, 1)
8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.read(1), b'z')
8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), 1)
8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_lseek(self):
9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if verbose:
9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print('play around with os.lseek() with the built largefile')
9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with self.open(TESTFN, 'rb') as f:
9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(os.lseek(f.fileno(), 0, 0), 0)
9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(os.lseek(f.fileno(), 42, 0), 42)
9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(os.lseek(f.fileno(), 42, 1), 84)
9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(os.lseek(f.fileno(), 0, 1), 84)
9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(os.lseek(f.fileno(), 0, 2), size+1+0)
9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(os.lseek(f.fileno(), -10, 2), size+1-10)
9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(os.lseek(f.fileno(), -size-1, 2), 0)
10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(os.lseek(f.fileno(), size, 0), size)
10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # the 'a' that was written at the end of file above
10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.read(1), b'a')
10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_truncate(self):
10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if verbose:
10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print('try truncate')
10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with self.open(TESTFN, 'r+b') as f:
10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # this is already decided before start running the test suite
10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # but we do it anyway for extra protection
11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if not hasattr(f, 'truncate'):
11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                raise unittest.SkipTest("open().truncate() not available on this system")
11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(0, 2)
11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # else we've lost track of the true size
11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), size+1)
11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Cut it back via seek + truncate with no argument.
11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            newsize = size - 10
11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(newsize)
11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.truncate()
11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), newsize)  # else pointer moved
12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(0, 2)
12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), newsize)  # else wasn't truncated
12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Ensure that truncate(smaller than true size) shrinks
12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # the file.
12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            newsize -= 1
12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(42)
12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.truncate(newsize)
12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if self.new_io:
12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(f.tell(), 42)
12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(0, 2)
13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(f.tell(), newsize)
13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # XXX truncate(larger than true size) is ill-defined
13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # across platform; cut it waaaaay back
13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(0)
13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.truncate(1)
13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if self.new_io:
13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(f.tell(), 0)       # else pointer moved
13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(0)
13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(len(f.read()), 1)  # else wasn't truncated
13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_seekable(self):
14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue #5016; seekable() can return False when the current position
14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # is negative when truncated to an int.
14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if not self.new_io:
14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.skipTest("builtin file doesn't have seekable()")
14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for pos in (2**31-1, 2**31, 2**31+1):
14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            with self.open(TESTFN, 'rb') as f:
14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.seek(pos)
14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertTrue(f.seekable())
14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef test_main():
15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # On Windows and Mac OSX this test comsumes large resources; It
15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # takes a long time to build the >2GB file and takes >2GB of disk
15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # space therefore the resource must be enabled to run this test.
15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # If not, nothing after this line stanza will be executed.
15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if sys.platform[:3] == 'win' or sys.platform == 'darwin':
15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        requires('largefile',
15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                 'test requires %s bytes and a long time to run' % str(size))
15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Only run if the current filesystem supports large files.
16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # (Skip this test on Windows, since we now always support
16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # large files.)
16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(TESTFN, 'wb', buffering=0)
16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # 2**31 == 2147483648
16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.seek(2147483649)
16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Seeking is not enough of a test: you must write and
16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # flush, too!
16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write(b'x')
17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.flush()
17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except (IOError, OverflowError):
17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            unlink(TESTFN)
17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            raise unittest.SkipTest("filesystem does not have largefile support")
17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    suite = unittest.TestSuite()
17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    for _open, prefix in [(io.open, 'C'), (pyio.open, 'Py'),
17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          (open, 'Builtin')]:
18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        class TestCase(LargeFileTest):
18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        TestCase.open = staticmethod(_open)
18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        TestCase.new_io = _open is not open
18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        TestCase.__name__ = prefix + LargeFileTest.__name__
18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        suite.addTest(TestCase('test_seek'))
18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        suite.addTest(TestCase('test_osstat'))
18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        suite.addTest(TestCase('test_seek_read'))
18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        suite.addTest(TestCase('test_lseek'))
18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with _open(TESTFN, 'wb') as f:
19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if hasattr(f, 'truncate'):
19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                suite.addTest(TestCase('test_truncate'))
19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        suite.addTest(TestCase('test_seekable'))
19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        unlink(TESTFN)
19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        run_unittest(suite)
19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    finally:
19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        unlink(TESTFN)
19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == '__main__':
20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    test_main()
201