10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""
20a8c90248264a8b26970b4473770bcc3df8515fJosh GaoCreate and delete FILES_PER_THREAD temp files (via tempfile.TemporaryFile)
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoin each of NUM_THREADS threads, recording the number of successes and
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofailures.  A failure is a bug in tempfile, and may be due to:
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao+ Trying to create more than one tempfile with the same name.
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao+ Trying to delete a tempfile that doesn't still exist.
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao+ Something we've never seen before.
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
100a8c90248264a8b26970b4473770bcc3df8515fJosh GaoBy default, NUM_THREADS == 20 and FILES_PER_THREAD == 50.  This is enough to
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaocreate about 150 failures per run under Win98SE in 2.0, and runs pretty
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoquickly. Guido reports needing to boost FILES_PER_THREAD to 500 before
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoprovoking a 2.0 failure under Linux.
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
160a8c90248264a8b26970b4473770bcc3df8515fJosh GaoNUM_THREADS = 20
170a8c90248264a8b26970b4473770bcc3df8515fJosh GaoFILES_PER_THREAD = 50
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport tempfile
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test.test_support import threading_setup, threading_cleanup, run_unittest, import_module
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gaothreading = import_module('threading')
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport StringIO
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom traceback import print_exc
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
270a8c90248264a8b26970b4473770bcc3df8515fJosh GaostartEvent = threading.Event()
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TempFileGreedy(threading.Thread):
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    error_count = 0
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ok_count = 0
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def run(self):
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.errors = StringIO.StringIO()
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        startEvent.wait()
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in range(FILES_PER_THREAD):
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                f = tempfile.TemporaryFile("w+b")
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                f.close()
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except:
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.error_count += 1
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                print_exc(file=self.errors)
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.ok_count += 1
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass ThreadedTempFileTest(unittest.TestCase):
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_main(self):
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        threads = []
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        thread_info = threading_setup()
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in range(NUM_THREADS):
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t = TempFileGreedy()
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            threads.append(t)
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t.start()
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        startEvent.set()
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ok = 0
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        errors = []
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in threads:
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t.join()
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ok += t.ok_count
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if t.error_count:
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                errors.append(str(t.getName()) + str(t.errors.getvalue()))
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        threading_cleanup(*thread_info)
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        msg = "Errors: errors %d ok %d\n%s" % (len(errors), ok,
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            '\n'.join(errors))
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(errors, [], msg)
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(ok, NUM_THREADS * FILES_PER_THREAD)
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test_main():
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    run_unittest(ThreadedTempFileTest)
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == "__main__":
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_main()
79