PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/MySQLdb-1.2.1c7/MySQLdb/test_capabilities.py

https://github.com/twleung/mac-mysql-python
Python | 269 lines | 259 code | 3 blank | 7 comment | 0 complexity | a03ba3f933e9b1538ae9ee9954609a0f MD5 | raw file
  1. #!/usr/bin/env python -O
  2. """ Script to test database capabilities and the DB-API interface
  3. for functionality and memory leaks.
  4. Adapted from a script by M-A Lemburg.
  5. """
  6. from time import time
  7. import array
  8. import unittest
  9. class DatabaseTest(unittest.TestCase):
  10. db_module = None
  11. connect_args = ()
  12. connect_kwargs = dict()
  13. create_table_extra = ''
  14. rows = 10
  15. debug = False
  16. def setUp(self):
  17. db = self.db_module.connect(*self.connect_args, **self.connect_kwargs)
  18. self.connection = db
  19. self.cursor = db.cursor()
  20. self.BLOBText = ''.join([chr(i) for i in range(256)] * 100);
  21. self.BLOBUText = u''.join([unichr(i) for i in range(16384)])
  22. self.BLOBBinary = self.db_module.Binary(''.join([chr(i) for i in range(256)] * 16))
  23. def table_exists(self, name):
  24. try:
  25. self.cursor.execute('select * from %s where 1=0' % name)
  26. except:
  27. return False
  28. else:
  29. return True
  30. def quote_identifier(self, ident):
  31. return '"%s"' % ident
  32. def new_table_name(self):
  33. i = id(self.cursor)
  34. while True:
  35. name = self.quote_identifier('tb%08x' % i)
  36. if not self.table_exists(name):
  37. return name
  38. i = i + 1
  39. def create_table(self, columndefs):
  40. """ Create a table using a list of column definitions given in
  41. columndefs.
  42. generator must be a function taking arguments (row_number,
  43. col_number) returning a suitable data object for insertion
  44. into the table.
  45. """
  46. self.table = self.new_table_name()
  47. self.cursor.execute('CREATE TABLE %s (%s) %s' %
  48. (self.table,
  49. ',\n'.join(columndefs),
  50. self.create_table_extra))
  51. def check_data_integrity(self, columndefs, generator):
  52. # insert
  53. self.create_table(columndefs)
  54. insert_statement = ('INSERT INTO %s VALUES (%s)' %
  55. (self.table,
  56. ','.join(['%s'] * len(columndefs))))
  57. data = [ [ generator(i,j) for j in range(len(columndefs)) ]
  58. for i in range(self.rows) ]
  59. if self.debug:
  60. print data
  61. self.cursor.executemany(insert_statement, data)
  62. self.connection.commit()
  63. # verify
  64. self.cursor.execute('select * from %s' % self.table)
  65. l = self.cursor.fetchall()
  66. if self.debug:
  67. print l
  68. self.assertEquals(len(l), self.rows)
  69. try:
  70. for i in range(self.rows):
  71. for j in range(len(columndefs)):
  72. self.assertEquals(l[i][j], generator(i,j))
  73. finally:
  74. if not self.debug:
  75. self.cursor.execute('drop table %s' % (self.table))
  76. def test_transactions(self):
  77. columndefs = ( 'col1 INT', 'col2 VARCHAR(255)')
  78. def generator(row, col):
  79. if col == 0: return row
  80. else: return ('%i' % (row%10))*255
  81. self.create_table(columndefs)
  82. insert_statement = ('INSERT INTO %s VALUES (%s)' %
  83. (self.table,
  84. ','.join(['%s'] * len(columndefs))))
  85. data = [ [ generator(i,j) for j in range(len(columndefs)) ]
  86. for i in range(self.rows) ]
  87. self.cursor.executemany(insert_statement, data)
  88. # verify
  89. self.connection.commit()
  90. self.cursor.execute('select * from %s' % self.table)
  91. l = self.cursor.fetchall()
  92. self.assertEquals(len(l), self.rows)
  93. for i in range(self.rows):
  94. for j in range(len(columndefs)):
  95. self.assertEquals(l[i][j], generator(i,j))
  96. delete_statement = 'delete from %s where col1=%%s' % self.table
  97. self.cursor.execute(delete_statement, (0,))
  98. self.cursor.execute('select col1 from %s where col1=%s' % \
  99. (self.table, 0))
  100. l = self.cursor.fetchall()
  101. self.failIf(l, "DELETE didn't work")
  102. self.connection.rollback()
  103. self.cursor.execute('select col1 from %s where col1=%s' % \
  104. (self.table, 0))
  105. l = self.cursor.fetchall()
  106. self.failUnless(len(l) == 1, "ROLLBACK didn't work")
  107. self.cursor.execute('drop table %s' % (self.table))
  108. def test_truncation(self):
  109. columndefs = ( 'col1 INT', 'col2 VARCHAR(255)')
  110. def generator(row, col):
  111. if col == 0: return row
  112. else: return ('%i' % (row%10))*((255-self.rows/2)+row)
  113. self.create_table(columndefs)
  114. insert_statement = ('INSERT INTO %s VALUES (%s)' %
  115. (self.table,
  116. ','.join(['%s'] * len(columndefs))))
  117. try:
  118. self.cursor.execute(insert_statement, (0, '0'*256))
  119. except Warning:
  120. if self.debug: print self.cursor.messages
  121. else:
  122. self.fail("Over-long column did not generate warnings with single insert")
  123. self.connection.rollback()
  124. try:
  125. for i in range(self.rows):
  126. data = []
  127. for j in range(len(columndefs)):
  128. data.append(generator(i,j))
  129. self.cursor.execute(insert_statement,tuple(data))
  130. except Warning:
  131. if self.debug: print self.cursor.messages
  132. else:
  133. self.fail("Over-long columns did not generate warnings with execute()")
  134. self.connection.rollback()
  135. try:
  136. data = [ [ generator(i,j) for j in range(len(columndefs)) ]
  137. for i in range(self.rows) ]
  138. self.cursor.executemany(insert_statement, data)
  139. except Warning:
  140. if self.debug: print self.cursor.messages
  141. else:
  142. self.fail("Over-long columns did not generate warnings with executemany()")
  143. self.connection.rollback()
  144. self.cursor.execute('drop table %s' % (self.table))
  145. def test_CHAR(self):
  146. # Character data
  147. def generator(row,col):
  148. return ('%i' % ((row+col) % 10)) * 255
  149. self.check_data_integrity(
  150. ('col1 char(255)','col2 char(255)'),
  151. generator)
  152. def test_INT(self):
  153. # Number data
  154. def generator(row,col):
  155. return row*row
  156. self.check_data_integrity(
  157. ('col1 INT',),
  158. generator)
  159. def test_DECIMAL(self):
  160. # DECIMAL
  161. def generator(row,col):
  162. from decimal import Decimal
  163. return Decimal("%d.%02d" % (row, col))
  164. self.check_data_integrity(
  165. ('col1 DECIMAL(5,2)',),
  166. generator)
  167. def test_DATE(self):
  168. ticks = time()
  169. def generator(row,col):
  170. return self.db_module.DateFromTicks(ticks+row*86400-col*1313)
  171. self.check_data_integrity(
  172. ('col1 DATE',),
  173. generator)
  174. def test_TIME(self):
  175. ticks = time()
  176. def generator(row,col):
  177. return self.db_module.TimeFromTicks(ticks+row*86400-col*1313)
  178. self.check_data_integrity(
  179. ('col1 TIME',),
  180. generator)
  181. def test_DATETIME(self):
  182. ticks = time()
  183. def generator(row,col):
  184. return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313)
  185. self.check_data_integrity(
  186. ('col1 DATETIME',),
  187. generator)
  188. def test_TIMESTAMP(self):
  189. ticks = time()
  190. def generator(row,col):
  191. return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313)
  192. self.check_data_integrity(
  193. ('col1 TIMESTAMP',),
  194. generator)
  195. def test_fractional_TIMESTAMP(self):
  196. ticks = time()
  197. def generator(row,col):
  198. return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313+row*0.7*col/3.0)
  199. self.check_data_integrity(
  200. ('col1 TIMESTAMP',),
  201. generator)
  202. def test_LONG(self):
  203. def generator(row,col):
  204. if col == 0:
  205. return row
  206. else:
  207. return self.BLOBUText # 'BLOB Text ' * 1024
  208. self.check_data_integrity(
  209. ('col1 INT','col2 LONG'),
  210. generator)
  211. def test_TEXT(self):
  212. def generator(row,col):
  213. return self.BLOBUText # 'BLOB Text ' * 1024
  214. self.check_data_integrity(
  215. ('col2 TEXT',),
  216. generator)
  217. def test_LONG_BYTE(self):
  218. def generator(row,col):
  219. if col == 0:
  220. return row
  221. else:
  222. return self.BLOBBinary # 'BLOB\000Binary ' * 1024
  223. self.check_data_integrity(
  224. ('col1 INT','col2 LONG BYTE'),
  225. generator)
  226. def test_BLOB(self):
  227. def generator(row,col):
  228. if col == 0:
  229. return row
  230. else:
  231. return self.BLOBBinary # 'BLOB\000Binary ' * 1024
  232. self.check_data_integrity(
  233. ('col1 INT','col2 BLOB'),
  234. generator)