dbtest_session.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #! /usr/bin/env python3
  2. from db_test import DBDakTestCase
  3. from daklib.dbconn import DBConn, Uid
  4. from sqlalchemy.exc import InvalidRequestError
  5. import time
  6. import unittest
  7. class SessionTestCase(DBDakTestCase):
  8. """
  9. This TestCase checks the behaviour of SQLAlchemy's session object. It should
  10. make sure the SQLAlchemy always works as we expect it. And it might help
  11. dak beginners to get a grasp on how the session works.
  12. """
  13. def sleep(self):
  14. time.sleep(0.001)
  15. def test_timestamps(self):
  16. '''
  17. Test the basic transaction behaviour. The session is not configured for
  18. autocommit mode and that is why we always have an open transaction that
  19. ends with either rollback() or commit().
  20. '''
  21. # timestamps will always be the same in one transaction
  22. timestamp01 = self.now()
  23. self.sleep()
  24. timestamp02 = self.now()
  25. self.assertEqual(timestamp01, timestamp02)
  26. uid = Uid(uid='foobar')
  27. self.session.add(uid)
  28. self.session.flush()
  29. self.assertEqual(timestamp01, uid.created)
  30. # ... but different in multiple transactions
  31. self.session.rollback()
  32. timestamp03 = self.now()
  33. self.assertTrue(timestamp01 < timestamp03)
  34. uid = Uid(uid='foobar')
  35. self.session.add(uid)
  36. self.session.flush()
  37. self.assertTrue(timestamp01 < uid.created)
  38. def test_crud(self):
  39. '''
  40. Test INSERT, UPDATE, DELETE, ROLLBACK, and COMMIT behaviour of the
  41. session.
  42. '''
  43. # test INSERT
  44. uid = Uid(uid='foobar')
  45. self.assertTrue(uid not in self.session)
  46. self.session.add(uid)
  47. self.assertTrue(uid in self.session)
  48. self.assertTrue(uid in self.session.new)
  49. self.session.flush()
  50. self.assertTrue(uid in self.session)
  51. self.assertTrue(uid not in self.session.new)
  52. # test UPDATE
  53. uid.uid = 'foobar2'
  54. self.assertTrue(uid in self.session.dirty)
  55. self.session.flush()
  56. self.assertTrue(uid not in self.session.dirty)
  57. # test ROLLBACK
  58. self.session.rollback()
  59. self.assertTrue(uid not in self.session)
  60. # test COMMIT
  61. uid = Uid(uid='foobar')
  62. self.session.add(uid)
  63. self.assertTrue(uid in self.session.new)
  64. self.session.commit()
  65. self.assertTrue(uid in self.session)
  66. self.assertTrue(uid not in self.session.new)
  67. # test DELETE
  68. self.session.delete(uid)
  69. self.assertTrue(uid in self.session)
  70. self.assertTrue(uid in self.session.deleted)
  71. self.session.flush()
  72. self.assertTrue(uid not in self.session)
  73. self.assertTrue(uid not in self.session.deleted)
  74. def test_expunge(self):
  75. '''
  76. Test expunge() of objects from session and the object_session()
  77. function.
  78. '''
  79. # test expunge()
  80. uid = Uid(uid='foobar')
  81. self.session.add(uid)
  82. self.assertTrue(uid in self.session)
  83. self.session.expunge(uid)
  84. self.assertTrue(uid not in self.session)
  85. # test close()
  86. self.session.add(uid)
  87. self.assertTrue(uid in self.session)
  88. self.session.close()
  89. self.assertTrue(uid not in self.session)
  90. # make uid persistent
  91. self.session.add(uid)
  92. self.session.commit()
  93. self.assertTrue(uid in self.session)
  94. # test rollback() for persistent object
  95. self.session.rollback()
  96. self.assertTrue(uid in self.session)
  97. # test expunge() for persistent object
  98. self.session.expunge(uid)
  99. self.assertTrue(uid not in self.session)
  100. # test close() for persistent object
  101. self.session.add(uid)
  102. self.assertTrue(uid in self.session)
  103. self.session.close()
  104. self.assertTrue(uid not in self.session)
  105. def refresh(self):
  106. '''
  107. Refreshes self.uid and should raise an exception is self.uid is not
  108. persistent.
  109. '''
  110. self.session.refresh(self.uid)
  111. def test_refresh(self):
  112. '''
  113. Test the refresh() of an object.
  114. '''
  115. self.uid = Uid(uid='foobar')
  116. self.assertEqual(None, self.uid.uid_id)
  117. self.session.add(self.uid)
  118. self.assertEqual(None, self.uid.uid_id)
  119. self.session.flush()
  120. self.assertTrue(self.uid.uid_id is not None)
  121. self.session.rollback()
  122. self.assertRaises(InvalidRequestError, self.refresh)
  123. def test_session(self):
  124. '''
  125. Tests the ORMObject.session() method.
  126. '''
  127. uid = Uid(uid='foobar')
  128. self.session.add(uid)
  129. self.assertEqual(self.session, uid.session())
  130. def test_clone(self):
  131. '''
  132. Tests the ORMObject.clone() method.
  133. '''
  134. uid1 = Uid(uid='foobar')
  135. # no session yet
  136. self.assertRaises(RuntimeError, uid1.clone)
  137. self.session.add(uid1)
  138. # object not persistent yet
  139. self.assertRaises(RuntimeError, uid1.clone)
  140. self.session.commit()
  141. # test without session parameter
  142. uid2 = uid1.clone()
  143. self.assertTrue(uid1 is not uid2)
  144. self.assertEqual(uid1.uid, uid2.uid)
  145. self.assertTrue(uid2 not in uid1.session())
  146. self.assertTrue(uid1 not in uid2.session())
  147. # test with explicit session parameter
  148. new_session = DBConn().session()
  149. uid3 = uid1.clone(session=new_session)
  150. self.assertEqual(uid1.uid, uid3.uid)
  151. self.assertTrue(uid3 in new_session)
  152. # test for ressource leaks with mass cloning
  153. for _ in range(1, 1000):
  154. uid1.clone()
  155. def classes_to_clean(self):
  156. # We need to clean all Uid objects in case some test fails.
  157. return (Uid,)
  158. if __name__ == '__main__':
  159. unittest.main()