diff options
author | Charles-François Natali <neologix@free.fr> | 2011-12-19 11:19:52 (GMT) |
---|---|---|
committer | Charles-François Natali <neologix@free.fr> | 2011-12-19 11:19:52 (GMT) |
commit | bfaa79a982f1aadfe2aa4e3fdc4ff75153286503 (patch) | |
tree | 051d5c6570679480f1aed9170a8a72f45c269fa8 | |
parent | ca9afca07c9a76312cc01ff5448aabb5df526469 (diff) | |
parent | 78ed83da46b4f87e6e04a15f4d330ccb28274d03 (diff) | |
download | cpython-bfaa79a982f1aadfe2aa4e3fdc4ff75153286503.zip cpython-bfaa79a982f1aadfe2aa4e3fdc4ff75153286503.tar.gz cpython-bfaa79a982f1aadfe2aa4e3fdc4ff75153286503.tar.bz2 |
Issue #11867: Make test_mailbox.test_lock_conflict deterministic (and fix a
race condition).
-rw-r--r-- | Lib/test/test_mailbox.py | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index a1c684e..67386a5 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -17,6 +17,10 @@ try: import fcntl except ImportError: pass +try: + import multiprocessing +except ImportError: + multiprocessing = None class TestBase(unittest.TestCase): @@ -993,28 +997,36 @@ class _TestMboxMMDF(TestMailbox): self.assertEqual(contents, f.read()) self._box = self._factory(self._path) + @unittest.skipUnless(hasattr(os, 'fork'), "Test needs fork().") + @unittest.skipUnless(multiprocessing, "Test needs multiprocessing.") def test_lock_conflict(self): - # Fork off a subprocess that will lock the file for 2 seconds, - # unlock it, and then exit. - if not hasattr(os, 'fork'): - return + # Fork off a child process that will lock the mailbox temporarily, + # unlock it and exit. + ready = multiprocessing.Event() + done = multiprocessing.Event() + pid = os.fork() if pid == 0: - # In the child, lock the mailbox. + # child try: + # lock the mailbox, and signal the parent it can proceed self._box.lock() - time.sleep(2) + ready.set() + + # wait until the parent is done, and unlock the mailbox + done.wait(5) self._box.unlock() finally: os._exit(0) - # In the parent, sleep a bit to give the child time to acquire - # the lock. - time.sleep(0.5) + # In the parent, wait until the child signals it locked the mailbox. + ready.wait(5) try: self.assertRaises(mailbox.ExternalClashError, self._box.lock) finally: + # Signal the child it can now release the lock and exit. + done.set() # Wait for child to exit. Locking should now succeed. exited_pid, status = os.waitpid(pid, 0) |