[Python-checkins] CVS: python/dist/src/Lib/test test_threadedtempfile.py,NONE,1.1

Tim Peters python-dev@python.org
Fri, 12 Jan 2001 19:04:04 -0800


Update of /cvsroot/python/python/dist/src/Lib/test
In directory usw-pr-cvs1:/tmp/cvs-serv19969/python/dist/src/lib/test

Added Files:
	test_threadedtempfile.py 
Log Message:
Guido found a brand new race in tempfile on Linux, due to Linux changing
pid across threads (but in that case, it's still the same process, and so
still sharing the "template" cache in tempfile.py).  Repaired that, and
added a new std test.
On Linux, someone please run that standalone with more files and/or more
threads; e.g.,

    python lib/test/test_threadedtempfile.py -f 1000 -t 10

to run with 10 threads each creating (and deleting) 1000 temp files.


--- NEW FILE: test_threadedtempfile.py ---
"""
Create and delete FILES_PER_THREAD temp files (via tempfile.TemporaryFile)
in each of NUM_THREADS threads, recording the number of successes and
failures.  A failure is a bug in tempfile, and may be due to:

+ Trying to create more than one tempfile with the same name.
+ Trying to delete a tempfile that doesn't still exist.
+ Something we've never seen before.

By default, NUM_THREADS == 20 and FILES_PER_THREAD == 50.  This is enough to
create about 150 failures per run under Win98SE in 2.0, and runs pretty
quickly. Guido reports needing to boost FILES_PER_THREAD to 500 before
provoking a 2.0 failure under Linux.  Run the test alone to boost either
via cmdline switches:

-f  FILES_PER_THREAD (int)
-t  NUM_THREADS (int)
"""

NUM_THREADS = 20        # change w/ -t option
FILES_PER_THREAD = 50   # change w/ -f option

import threading
from test.test_support import TestFailed
import StringIO
from traceback import print_exc

startEvent = threading.Event()

import tempfile
tempfile.gettempdir() # Do this now, to avoid spurious races later

class TempFileGreedy(threading.Thread):
    error_count = 0
    ok_count = 0

    def run(self):
        self.errors = StringIO.StringIO()
        startEvent.wait()
        for i in range(FILES_PER_THREAD):
            try:
                f = tempfile.TemporaryFile("w+b")
                f.close()
            except:
                self.error_count += 1
                print_exc(file=self.errors)
            else:
                self.ok_count += 1

def _test():
    threads = []

    print "Creating"
    for i in range(NUM_THREADS):
        t = TempFileGreedy()
        threads.append(t)
        t.start()

    print "Starting"
    startEvent.set()

    print "Reaping"
    ok = errors = 0
    for t in threads:
        t.join()
        ok += t.ok_count
        errors += t.error_count
        if t.error_count:
            print '%s errors:\n%s' % (t.getName(), t.errors.getvalue())

    msg = "Done: errors %d ok %d" % (errors, ok)
    print msg
    if errors:
        raise TestFailed(msg)

if __name__ == "__main__":
    import sys, getopt
    opts, args = getopt.getopt(sys.argv[1:], "t:f:")
    for o, v in opts:
        if o == "-f":
            FILES_PER_THREAD = int(v)
        elif o == "-t":
            NUM_THREADS = int(v)

_test()