# -*- coding: utf-8 -*- """ MoinMoin - MoinMoin.module_tested Tests Module names must start with 'test_' to be included in the tests. @copyright: 2005 by Florian Festi @license: GNU GPL, see COPYING for details. """ import unittest, tempfile, os, time, shutil from MoinMoin._tests import TestConfig, TestSkiped from MoinMoin.util.lock import ExclusiveLock class ExclusiveLockTests(unittest.TestCase): def setUp(self): self.test_dir = tempfile.mkdtemp('', 'lock_') self.test_dir_mtime_goal = time.time() self.test_dir_mtime_reported = os.stat(self.test_dir).st_mtime self.lock_dir = os.path.join(self.test_dir, "lock") def tearDown(self): shutil.rmtree(self.test_dir) def testBrokenTimeAPI(self): """ util.lock: os.stat().mtime consistency with time.time() the timestamp os.stat reports as st_mtime on a fresh file should be the same (or at least almost the same) as the time time.time() reported at this time. Differences of n*3600s are usually operating system bugs / limitations, Win32 (as of Win XP SP2 + hotfixes 2006-04-30) is broken if you set TZ to a different value than the rest of the system uses. E.g. if you set "TZ=GMT1EDT" (and the rest of the system is setup on german/berlin timezone), it will report 7200s difference in the summer. """ diff = self.test_dir_mtime_reported - self.test_dir_mtime_goal # diff should be 0 or near 0 self.failUnless(abs(diff) <= 2, "Operating System time.time / os.stat inconsistent (diff==%.1fs). Locking will NOT work correctly." % float(diff)) def testTimeout(self): """ util.lock: ExclusiveLock: raise ValueError for timeout < 2.0 """ self.assertRaises(ValueError, ExclusiveLock, self.lock_dir, timeout=1.0) def testAcquire(self): """ util.lock: ExclusiveLock: acquire """ lock = ExclusiveLock(self.lock_dir) self.failUnless(lock.acquire(0.1), "Could not acquire lock") def testRelease(self): """ util.lock: ExclusiveLock: release After releasing a lock, new one could be acquired. """ lock = ExclusiveLock(self.lock_dir) if not lock.acquire(0.1): raise TestSkiped("can't acquire lock") lock.release() self.failUnless(lock.acquire(0.1), "Could not acquire lock after release") def testIsLocked(self): """ util.lock: ExclusiveLock: isLocked """ lock = ExclusiveLock(self.lock_dir) if not lock.acquire(0.1): raise TestSkiped("can't acquire lock") self.failUnless(lock.isLocked(), "lock state wrong") lock.release() self.failIf(lock.isLocked(), "lock state wrong") def testExists(self): """ util.lock: ExclusiveLock: exists """ lock = ExclusiveLock(self.lock_dir) if not lock.acquire(0.1): raise TestSkiped("can't acquire lock") self.failUnless(lock.exists(), "lock should exists") def testIsExpired(self): """ util.lock: ExclusiveLock: isExpired """ timeout = 2.0 lock = ExclusiveLock(self.lock_dir, timeout=timeout) if not lock.acquire(0.1): raise TestSkiped("can't acquire lock") self.failIf(lock.isExpired(), "lock should not be expired yet") time.sleep(timeout) self.failUnless(lock.isExpired(), "lock should be expired") def testExpire(self): """ util.lock: ExclusiveLock: expire """ timeout = 2.0 lock = ExclusiveLock(self.lock_dir, timeout=timeout) if not lock.acquire(0.1): raise TestSkiped("can't acquire lock") self.failIf(lock.expire(), "lock should not be expired yet") time.sleep(timeout) self.failUnless(lock.expire(), "lock should be expired") def testExclusive(self): """ util.lock: ExclusiveLock: lock is exclusive """ first = ExclusiveLock(self.lock_dir) second = ExclusiveLock(self.lock_dir) if not first.acquire(0.1): raise TestSkiped("can't acquire lock") self.failIf(second.acquire(0.1), "first lock is not exclusive") def testAcquireAfterTimeout(self): """ util.lock: ExclusiveLock: acquire after timeout Lock with one lock, try to acquire another after timeout. """ timeout = 2.0 # minimal timout first = ExclusiveLock(self.lock_dir, timeout) second = ExclusiveLock(self.lock_dir, timeout) if not first.acquire(0.1): raise TestSkiped("can't acquire lock") if second.acquire(0.1): raise TestSkiped("first lock is not exclusive") # Second lock should be acquired after timeout self.failUnless(second.acquire(timeout + 0.1), "can't acquire after timeout") def unlock(self, lock, delay): time.sleep(delay) lock.release()