Files
mysqlclient/MySQLdb/tests/capabilities.py
farcepest a6dcb3b683 Travis testing fixes
Squashed commit of the following:

commit 17fb6798cd
Author: farcepest <farcepest@gmail.com>
Date:   Tue Oct 2 14:03:57 2012 -0400

    Add a build status widget for Travis

commit 1cd83ef78e
Author: farcepest <farcepest@gmail.com>
Date:   Tue Oct 2 13:59:48 2012 -0400

    Rewrite the repository root README

commit 72848c84bc
Author: farcepest <farcepest@gmail.com>
Date:   Tue Oct 2 13:50:00 2012 -0400

    Somehow I missed this connection setup

commit 413c3b6623
Author: farcepest <farcepest@gmail.com>
Date:   Tue Oct 2 13:19:09 2012 -0400

    Giving Travis it's own database with utf8 charset in hopes this will fix the callproc test (which works everywhere else)

commit 400112e0c3
Author: farcepest <farcepest@gmail.com>
Date:   Tue Oct 2 13:06:00 2012 -0400

    Update the Travis config so that the tests use the correct database configuration file

commit ae94e44ed1
Author: farcepest <farcepest@gmail.com>
Date:   Tue Oct 2 12:59:29 2012 -0400

    Add Travis-specific configuration file

commit 3581603f45
Merge: f42c369 d0e96c7
Author: farcepest <farcepest@gmail.com>
Date:   Tue Oct 2 12:58:00 2012 -0400

    Merge branch 'master' into MySQLdb-1.2

    Conflicts:
    	MySQLdb/tests/test_MySQLdb_capabilities.py
    	MySQLdb/tests/test_MySQLdb_dbapi20.py

commit f42c369300
Author: Andy Dustman <farcepest@gmail.com>
Date:   Mon Oct 1 13:43:00 2012 -0400

    Maybe a subshell will do the trick?

commit fb346e1d40
Author: Andy Dustman <farcepest@gmail.com>
Date:   Mon Oct 1 13:35:50 2012 -0400

    Travis can't build for Python 2.4 it seems, and the test still weren't all running

commit 2f661f0991
Author: Andy Dustman <farcepest@gmail.com>
Date:   Mon Oct 1 13:31:40 2012 -0400

    OK, this should hopefully fix the build process for Travis

commit 899c3342b2
Author: Andy Dustman <farcepest@gmail.com>
Date:   Mon Oct 1 13:28:14 2012 -0400

    More Travis fixes

commit 8f593def7b
Author: Andy Dustman <farcepest@gmail.com>
Date:   Mon Oct 1 13:19:39 2012 -0400

    Fix test script due to source being down one level.

commit 1936b93cf0
Author: Andy Dustman <farcepest@gmail.com>
Date:   Mon Oct 1 13:14:38 2012 -0400

    Test connection tweaks for Travis

commit 9bf8bcf894
Merge: 7ae4f55 d551f8a
Author: Andy Dustman <farcepest@gmail.com>
Date:   Mon Oct 1 13:10:58 2012 -0400

    Merge branch 'travis' into MySQLdb-1.2

commit d551f8a8d9
Author: Andy Dustman <farcepest@gmail.com>
Date:   Mon Oct 1 13:05:25 2012 -0400

    Initial Travis setup

commit 7ae4f5549b
Merge: 235d846 c16bc33
Author: farcepest <farcepest@gmail.com>
Date:   Thu Sep 27 12:49:07 2012 -0400

    Merge remote-tracking branch 'origin/MySQLdb-1.2' into MySQLdb-1.2

commit 235d8466dd
Author: farcepest <farcepest@gmail.com>
Date:   Thu Sep 27 12:18:07 2012 -0400

    History updates for 1.2.4b2

commit 5fda4c2579
Author: farcepest <farcepest@gmail.com>
Date:   Thu Sep 27 12:06:58 2012 -0400

    Revert raise exc as value statements to raise exc, value since it breaks Python < 2.6.

commit 048b70d901
Author: farcepest <farcepest@gmail.com>
Date:   Wed Sep 26 16:02:05 2012 -0400

    Fix MySQLdb1-1 Exception format incompatible with previous versions

    Unfortunately, when I broke this, I broke the test at the same time. That should have been a red flag.

commit 162e9e4d84
Author: Andy Dustman <farcepest@gmail.com>
Date:   Tue Sep 25 19:56:49 2012 -0400

    General cleanups
2012-10-02 14:15:12 -04:00

281 lines
9.7 KiB
Python

#!/usr/bin/env python -O
""" Script to test database capabilities and the DB-API interface
for functionality and memory leaks.
Adapted from a script by M-A Lemburg.
"""
from time import time
import array
import unittest
class DatabaseTest(unittest.TestCase):
db_module = None
connect_args = ()
connect_kwargs = dict()
create_table_extra = ''
rows = 10
debug = False
def setUp(self):
import gc
db = self.db_module.connect(*self.connect_args, **self.connect_kwargs)
self.connection = db
self.cursor = db.cursor()
# TODO: this needs to be re-evaluated for Python 3
self.BLOBText = ''.join([chr(i) for i in range(256)] * 100);
self.BLOBUText = u''.join([unichr(i) for i in range(16384)])
self.BLOBBinary = self.db_module.Binary(''.join([chr(i) for i in range(256)] * 16))
leak_test = True
def tearDown(self):
if self.leak_test:
import gc
del self.cursor
orphans = gc.collect()
self.failIf(orphans, "%d orphaned objects found after deleting cursor" % orphans)
del self.connection
orphans = gc.collect()
self.failIf(orphans, "%d orphaned objects found after deleting connection" % orphans)
def table_exists(self, name):
try:
self.cursor.execute('select * from %s where 1=0' % name)
except:
return False
else:
return True
def quote_identifier(self, ident):
return '"%s"' % ident
def new_table_name(self):
i = id(self.cursor)
while True:
name = self.quote_identifier('tb%08x' % i)
if not self.table_exists(name):
return name
i = i + 1
def create_table(self, columndefs):
""" Create a table using a list of column definitions given in
columndefs.
generator must be a function taking arguments (row_number,
col_number) returning a suitable data object for insertion
into the table.
"""
self.table = self.new_table_name()
self.cursor.execute('CREATE TABLE %s (%s) %s' %
(self.table,
',\n'.join(columndefs),
self.create_table_extra))
def check_data_integrity(self, columndefs, generator):
# insert
self.create_table(columndefs)
insert_statement = ('INSERT INTO %s VALUES (%s)' %
(self.table,
','.join(['%s'] * len(columndefs))))
data = [ [ generator(i,j) for j in range(len(columndefs)) ]
for i in range(self.rows) ]
self.cursor.executemany(insert_statement, data)
self.connection.commit()
# verify
self.cursor.execute('select * from %s' % self.table)
l = self.cursor.fetchall()
self.assertEquals(len(l), self.rows)
try:
for i in range(self.rows):
for j in range(len(columndefs)):
self.assertEquals(l[i][j], generator(i,j))
finally:
if not self.debug:
self.cursor.execute('drop table %s' % (self.table))
def test_transactions(self):
columndefs = ( 'col1 INT', 'col2 VARCHAR(255)')
def generator(row, col):
if col == 0: return row
else: return ('%i' % (row%10))*255
self.create_table(columndefs)
insert_statement = ('INSERT INTO %s VALUES (%s)' %
(self.table,
','.join(['%s'] * len(columndefs))))
data = [ [ generator(i,j) for j in range(len(columndefs)) ]
for i in range(self.rows) ]
self.cursor.executemany(insert_statement, data)
# verify
self.connection.commit()
self.cursor.execute('select * from %s' % self.table)
l = self.cursor.fetchall()
self.assertEquals(len(l), self.rows)
for i in range(self.rows):
for j in range(len(columndefs)):
self.assertEquals(l[i][j], generator(i,j))
delete_statement = 'delete from %s where col1=%%s' % self.table
self.cursor.execute(delete_statement, (0,))
self.cursor.execute('select col1 from %s where col1=%s' % \
(self.table, 0))
l = self.cursor.fetchall()
self.assertFalse(l, "DELETE didn't work")
self.connection.rollback()
self.cursor.execute('select col1 from %s where col1=%s' % \
(self.table, 0))
l = self.cursor.fetchall()
self.assertTrue(len(l) == 1, "ROLLBACK didn't work")
self.cursor.execute('drop table %s' % (self.table))
def test_truncation(self):
columndefs = ( 'col1 INT', 'col2 VARCHAR(255)')
def generator(row, col):
if col == 0: return row
else: return ('%i' % (row%10))*((255-self.rows/2)+row)
self.create_table(columndefs)
insert_statement = ('INSERT INTO %s VALUES (%s)' %
(self.table,
','.join(['%s'] * len(columndefs))))
try:
self.cursor.execute(insert_statement, (0, '0'*256))
except self.connection.DataError:
pass
else:
self.fail("Over-long column did not generate warnings/exception with single insert")
self.connection.rollback()
try:
for i in range(self.rows):
data = []
for j in range(len(columndefs)):
data.append(generator(i,j))
self.cursor.execute(insert_statement,tuple(data))
except self.connection.DataError:
pass
else:
self.fail("Over-long columns did not generate warnings/exception with execute()")
self.connection.rollback()
try:
data = [ [ generator(i,j) for j in range(len(columndefs)) ]
for i in range(self.rows) ]
self.cursor.executemany(insert_statement, data)
except self.connection.DataError:
pass
else:
self.fail("Over-long columns did not generate warnings/exception with executemany()")
self.connection.rollback()
self.cursor.execute('drop table %s' % (self.table))
def test_CHAR(self):
# Character data
def generator(row,col):
return ('%i' % ((row+col) % 10)) * 255
self.check_data_integrity(
('col1 char(255)','col2 char(255)'),
generator)
def test_INT(self):
# Number data
def generator(row,col):
return row*row
self.check_data_integrity(
('col1 INT',),
generator)
def test_DECIMAL(self):
# DECIMAL
def generator(row,col):
from decimal import Decimal
return Decimal("%d.%02d" % (row, col))
self.check_data_integrity(
('col1 DECIMAL(5,2)',),
generator)
def test_DATE(self):
ticks = time()
def generator(row,col):
return self.db_module.DateFromTicks(ticks+row*86400-col*1313)
self.check_data_integrity(
('col1 DATE',),
generator)
def test_TIME(self):
ticks = time()
def generator(row,col):
return self.db_module.TimeFromTicks(ticks+row*86400-col*1313)
self.check_data_integrity(
('col1 TIME',),
generator)
def test_DATETIME(self):
ticks = time()
def generator(row,col):
return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313)
self.check_data_integrity(
('col1 DATETIME',),
generator)
def test_TIMESTAMP(self):
ticks = time()
def generator(row,col):
return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313)
self.check_data_integrity(
('col1 TIMESTAMP',),
generator)
def test_fractional_TIMESTAMP(self):
ticks = time()
def generator(row,col):
return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313+row*0.7*col/3.0)
self.check_data_integrity(
('col1 TIMESTAMP',),
generator)
def test_LONG(self):
def generator(row,col):
if col == 0:
return row
else:
return self.BLOBUText # 'BLOB Text ' * 1024
self.check_data_integrity(
('col1 INT','col2 LONG'),
generator)
def test_TEXT(self):
def generator(row,col):
return self.BLOBUText # 'BLOB Text ' * 1024
self.check_data_integrity(
('col2 TEXT',),
generator)
def test_LONG_BYTE(self):
def generator(row,col):
if col == 0:
return row
else:
return self.BLOBBinary # 'BLOB\000Binary ' * 1024
self.check_data_integrity(
('col1 INT','col2 LONG BYTE'),
generator)
def test_BLOB(self):
def generator(row,col):
if col == 0:
return row
else:
return self.BLOBBinary # 'BLOB\000Binary ' * 1024
self.check_data_integrity(
('col1 INT','col2 BLOB'),
generator)