/Lib/bsddb/test/test_lock.py

http://unladen-swallow.googlecode.com/ · Python · 179 lines · 140 code · 34 blank · 5 comment · 30 complexity · a0f1bd3d2f0694120e97e51b5dc737fe MD5 · raw file

  1. """
  2. TestCases for testing the locking sub-system.
  3. """
  4. import time
  5. import unittest
  6. from test_all import db, test_support, verbose, have_threads, \
  7. get_new_environment_path, get_new_database_path
  8. if have_threads :
  9. from threading import Thread
  10. import sys
  11. if sys.version_info[0] < 3 :
  12. from threading import currentThread
  13. else :
  14. from threading import current_thread as currentThread
  15. #----------------------------------------------------------------------
  16. class LockingTestCase(unittest.TestCase):
  17. import sys
  18. if sys.version_info[:3] < (2, 4, 0):
  19. def assertTrue(self, expr, msg=None):
  20. self.failUnless(expr,msg=msg)
  21. def setUp(self):
  22. self.homeDir = get_new_environment_path()
  23. self.env = db.DBEnv()
  24. self.env.open(self.homeDir, db.DB_THREAD | db.DB_INIT_MPOOL |
  25. db.DB_INIT_LOCK | db.DB_CREATE)
  26. def tearDown(self):
  27. self.env.close()
  28. test_support.rmtree(self.homeDir)
  29. def test01_simple(self):
  30. if verbose:
  31. print '\n', '-=' * 30
  32. print "Running %s.test01_simple..." % self.__class__.__name__
  33. anID = self.env.lock_id()
  34. if verbose:
  35. print "locker ID: %s" % anID
  36. lock = self.env.lock_get(anID, "some locked thing", db.DB_LOCK_WRITE)
  37. if verbose:
  38. print "Aquired lock: %s" % lock
  39. self.env.lock_put(lock)
  40. if verbose:
  41. print "Released lock: %s" % lock
  42. self.env.lock_id_free(anID)
  43. def test02_threaded(self):
  44. if verbose:
  45. print '\n', '-=' * 30
  46. print "Running %s.test02_threaded..." % self.__class__.__name__
  47. threads = []
  48. threads.append(Thread(target = self.theThread,
  49. args=(db.DB_LOCK_WRITE,)))
  50. threads.append(Thread(target = self.theThread,
  51. args=(db.DB_LOCK_READ,)))
  52. threads.append(Thread(target = self.theThread,
  53. args=(db.DB_LOCK_READ,)))
  54. threads.append(Thread(target = self.theThread,
  55. args=(db.DB_LOCK_WRITE,)))
  56. threads.append(Thread(target = self.theThread,
  57. args=(db.DB_LOCK_READ,)))
  58. threads.append(Thread(target = self.theThread,
  59. args=(db.DB_LOCK_READ,)))
  60. threads.append(Thread(target = self.theThread,
  61. args=(db.DB_LOCK_WRITE,)))
  62. threads.append(Thread(target = self.theThread,
  63. args=(db.DB_LOCK_WRITE,)))
  64. threads.append(Thread(target = self.theThread,
  65. args=(db.DB_LOCK_WRITE,)))
  66. for t in threads:
  67. import sys
  68. if sys.version_info[0] < 3 :
  69. t.setDaemon(True)
  70. else :
  71. t.daemon = True
  72. t.start()
  73. for t in threads:
  74. t.join()
  75. def test03_lock_timeout(self):
  76. self.env.set_timeout(0, db.DB_SET_LOCK_TIMEOUT)
  77. self.env.set_timeout(0, db.DB_SET_TXN_TIMEOUT)
  78. self.env.set_timeout(123456, db.DB_SET_LOCK_TIMEOUT)
  79. self.env.set_timeout(7890123, db.DB_SET_TXN_TIMEOUT)
  80. def deadlock_detection() :
  81. while not deadlock_detection.end :
  82. deadlock_detection.count = \
  83. self.env.lock_detect(db.DB_LOCK_EXPIRE)
  84. if deadlock_detection.count :
  85. while not deadlock_detection.end :
  86. pass
  87. break
  88. time.sleep(0.01)
  89. deadlock_detection.end=False
  90. deadlock_detection.count=0
  91. t=Thread(target=deadlock_detection)
  92. import sys
  93. if sys.version_info[0] < 3 :
  94. t.setDaemon(True)
  95. else :
  96. t.daemon = True
  97. t.start()
  98. self.env.set_timeout(100000, db.DB_SET_LOCK_TIMEOUT)
  99. anID = self.env.lock_id()
  100. anID2 = self.env.lock_id()
  101. self.assertNotEqual(anID, anID2)
  102. lock = self.env.lock_get(anID, "shared lock", db.DB_LOCK_WRITE)
  103. start_time=time.time()
  104. self.assertRaises(db.DBLockNotGrantedError,
  105. self.env.lock_get,anID2, "shared lock", db.DB_LOCK_READ)
  106. end_time=time.time()
  107. deadlock_detection.end=True
  108. self.assertTrue((end_time-start_time) >= 0.0999)
  109. self.env.lock_put(lock)
  110. t.join()
  111. self.env.lock_id_free(anID)
  112. self.env.lock_id_free(anID2)
  113. if db.version() >= (4,6):
  114. self.assertTrue(deadlock_detection.count>0)
  115. def theThread(self, lockType):
  116. import sys
  117. if sys.version_info[0] < 3 :
  118. name = currentThread().getName()
  119. else :
  120. name = currentThread().name
  121. if lockType == db.DB_LOCK_WRITE:
  122. lt = "write"
  123. else:
  124. lt = "read"
  125. anID = self.env.lock_id()
  126. if verbose:
  127. print "%s: locker ID: %s" % (name, anID)
  128. for i in xrange(1000) :
  129. lock = self.env.lock_get(anID, "some locked thing", lockType)
  130. if verbose:
  131. print "%s: Aquired %s lock: %s" % (name, lt, lock)
  132. self.env.lock_put(lock)
  133. if verbose:
  134. print "%s: Released %s lock: %s" % (name, lt, lock)
  135. self.env.lock_id_free(anID)
  136. #----------------------------------------------------------------------
  137. def test_suite():
  138. suite = unittest.TestSuite()
  139. if have_threads:
  140. suite.addTest(unittest.makeSuite(LockingTestCase))
  141. else:
  142. suite.addTest(unittest.makeSuite(LockingTestCase, 'test01'))
  143. return suite
  144. if __name__ == '__main__':
  145. unittest.main(defaultTest='test_suite')