/Lib/bsddb/test/test_recno.py

http://unladen-swallow.googlecode.com/ · Python · 300 lines · 226 code · 62 blank · 12 comment · 60 complexity · 7a7d038a4c243b9b6365ccbe8a8006ea MD5 · raw file

  1. """TestCases for exercising a Recno DB.
  2. """
  3. import os
  4. import errno
  5. from pprint import pprint
  6. import unittest
  7. from test_all import db, test_support, verbose, get_new_environment_path, get_new_database_path
  8. letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  9. #----------------------------------------------------------------------
  10. class SimpleRecnoTestCase(unittest.TestCase):
  11. import sys
  12. if sys.version_info[:3] < (2, 4, 0):
  13. def assertFalse(self, expr, msg=None):
  14. self.failIf(expr,msg=msg)
  15. def setUp(self):
  16. self.filename = get_new_database_path()
  17. self.homeDir = None
  18. def tearDown(self):
  19. test_support.unlink(self.filename)
  20. if self.homeDir:
  21. test_support.rmtree(self.homeDir)
  22. def test01_basic(self):
  23. d = db.DB()
  24. get_returns_none = d.set_get_returns_none(2)
  25. d.set_get_returns_none(get_returns_none)
  26. d.open(self.filename, db.DB_RECNO, db.DB_CREATE)
  27. for x in letters:
  28. recno = d.append(x * 60)
  29. self.assertEqual(type(recno), type(0))
  30. self.assert_(recno >= 1)
  31. if verbose:
  32. print recno,
  33. if verbose: print
  34. stat = d.stat()
  35. if verbose:
  36. pprint(stat)
  37. for recno in range(1, len(d)+1):
  38. data = d[recno]
  39. if verbose:
  40. print data
  41. self.assertEqual(type(data), type(""))
  42. self.assertEqual(data, d.get(recno))
  43. try:
  44. data = d[0] # This should raise a KeyError!?!?!
  45. except db.DBInvalidArgError, val:
  46. import sys
  47. if sys.version_info[0] < 3 :
  48. self.assertEqual(val[0], db.EINVAL)
  49. else :
  50. self.assertEqual(val.args[0], db.EINVAL)
  51. if verbose: print val
  52. else:
  53. self.fail("expected exception")
  54. # test that has_key raises DB exceptions (fixed in pybsddb 4.3.2)
  55. try:
  56. d.has_key(0)
  57. except db.DBError, val:
  58. pass
  59. else:
  60. self.fail("has_key did not raise a proper exception")
  61. try:
  62. data = d[100]
  63. except KeyError:
  64. pass
  65. else:
  66. self.fail("expected exception")
  67. try:
  68. data = d.get(100)
  69. except db.DBNotFoundError, val:
  70. if get_returns_none:
  71. self.fail("unexpected exception")
  72. else:
  73. self.assertEqual(data, None)
  74. keys = d.keys()
  75. if verbose:
  76. print keys
  77. self.assertEqual(type(keys), type([]))
  78. self.assertEqual(type(keys[0]), type(123))
  79. self.assertEqual(len(keys), len(d))
  80. items = d.items()
  81. if verbose:
  82. pprint(items)
  83. self.assertEqual(type(items), type([]))
  84. self.assertEqual(type(items[0]), type(()))
  85. self.assertEqual(len(items[0]), 2)
  86. self.assertEqual(type(items[0][0]), type(123))
  87. self.assertEqual(type(items[0][1]), type(""))
  88. self.assertEqual(len(items), len(d))
  89. self.assert_(d.has_key(25))
  90. del d[25]
  91. self.assertFalse(d.has_key(25))
  92. d.delete(13)
  93. self.assertFalse(d.has_key(13))
  94. data = d.get_both(26, "z" * 60)
  95. self.assertEqual(data, "z" * 60, 'was %r' % data)
  96. if verbose:
  97. print data
  98. fd = d.fd()
  99. if verbose:
  100. print fd
  101. c = d.cursor()
  102. rec = c.first()
  103. while rec:
  104. if verbose:
  105. print rec
  106. rec = c.next()
  107. c.set(50)
  108. rec = c.current()
  109. if verbose:
  110. print rec
  111. c.put(-1, "a replacement record", db.DB_CURRENT)
  112. c.set(50)
  113. rec = c.current()
  114. self.assertEqual(rec, (50, "a replacement record"))
  115. if verbose:
  116. print rec
  117. rec = c.set_range(30)
  118. if verbose:
  119. print rec
  120. # test that non-existent key lookups work (and that
  121. # DBC_set_range doesn't have a memleak under valgrind)
  122. rec = c.set_range(999999)
  123. self.assertEqual(rec, None)
  124. if verbose:
  125. print rec
  126. c.close()
  127. d.close()
  128. d = db.DB()
  129. d.open(self.filename)
  130. c = d.cursor()
  131. # put a record beyond the consecutive end of the recno's
  132. d[100] = "way out there"
  133. self.assertEqual(d[100], "way out there")
  134. try:
  135. data = d[99]
  136. except KeyError:
  137. pass
  138. else:
  139. self.fail("expected exception")
  140. try:
  141. d.get(99)
  142. except db.DBKeyEmptyError, val:
  143. if get_returns_none:
  144. self.fail("unexpected DBKeyEmptyError exception")
  145. else:
  146. self.assertEqual(val[0], db.DB_KEYEMPTY)
  147. if verbose: print val
  148. else:
  149. if not get_returns_none:
  150. self.fail("expected exception")
  151. rec = c.set(40)
  152. while rec:
  153. if verbose:
  154. print rec
  155. rec = c.next()
  156. c.close()
  157. d.close()
  158. def test02_WithSource(self):
  159. """
  160. A Recno file that is given a "backing source file" is essentially a
  161. simple ASCII file. Normally each record is delimited by \n and so is
  162. just a line in the file, but you can set a different record delimiter
  163. if needed.
  164. """
  165. homeDir = get_new_environment_path()
  166. self.homeDir = homeDir
  167. source = os.path.join(homeDir, 'test_recno.txt')
  168. if not os.path.isdir(homeDir):
  169. os.mkdir(homeDir)
  170. f = open(source, 'w') # create the file
  171. f.close()
  172. d = db.DB()
  173. # This is the default value, just checking if both int
  174. d.set_re_delim(0x0A)
  175. d.set_re_delim('\n') # and char can be used...
  176. d.set_re_source(source)
  177. d.open(self.filename, db.DB_RECNO, db.DB_CREATE)
  178. data = "The quick brown fox jumped over the lazy dog".split()
  179. for datum in data:
  180. d.append(datum)
  181. d.sync()
  182. d.close()
  183. # get the text from the backing source
  184. text = open(source, 'r').read()
  185. text = text.strip()
  186. if verbose:
  187. print text
  188. print data
  189. print text.split('\n')
  190. self.assertEqual(text.split('\n'), data)
  191. # open as a DB again
  192. d = db.DB()
  193. d.set_re_source(source)
  194. d.open(self.filename, db.DB_RECNO)
  195. d[3] = 'reddish-brown'
  196. d[8] = 'comatose'
  197. d.sync()
  198. d.close()
  199. text = open(source, 'r').read()
  200. text = text.strip()
  201. if verbose:
  202. print text
  203. print text.split('\n')
  204. self.assertEqual(text.split('\n'),
  205. "The quick reddish-brown fox jumped over the comatose dog".split())
  206. def test03_FixedLength(self):
  207. d = db.DB()
  208. d.set_re_len(40) # fixed length records, 40 bytes long
  209. d.set_re_pad('-') # sets the pad character...
  210. d.set_re_pad(45) # ...test both int and char
  211. d.open(self.filename, db.DB_RECNO, db.DB_CREATE)
  212. for x in letters:
  213. d.append(x * 35) # These will be padded
  214. d.append('.' * 40) # this one will be exact
  215. try: # this one will fail
  216. d.append('bad' * 20)
  217. except db.DBInvalidArgError, val:
  218. import sys
  219. if sys.version_info[0] < 3 :
  220. self.assertEqual(val[0], db.EINVAL)
  221. else :
  222. self.assertEqual(val.args[0], db.EINVAL)
  223. if verbose: print val
  224. else:
  225. self.fail("expected exception")
  226. c = d.cursor()
  227. rec = c.first()
  228. while rec:
  229. if verbose:
  230. print rec
  231. rec = c.next()
  232. c.close()
  233. d.close()
  234. #----------------------------------------------------------------------
  235. def test_suite():
  236. return unittest.makeSuite(SimpleRecnoTestCase)
  237. if __name__ == '__main__':
  238. unittest.main(defaultTest='test_suite')