Commit d0233940 authored by Martin v. Löwis's avatar Martin v. Löwis

Fix test_bsddb3.

parent c518ecc9
...@@ -27,14 +27,10 @@ import pickle ...@@ -27,14 +27,10 @@ import pickle
from bsddb.db import * from bsddb.db import *
# All table names, row names etc. must be ASCII strings # All table names, row names etc. must be ASCII strings
# However, rowids, when represented as strings, are latin-1 encoded
def _E(s): def _E(s):
return s.encode("ascii") return s.encode("ascii")
# Yet, rowid are arbitrary bytes; if there is a need to hash
# them, convert them to Latin-1 first
def _D(s):
return s.decode("latin-1")
# XXX(nnorwitz): is this correct? DBIncompleteError is conditional in _bsddb.c # XXX(nnorwitz): is this correct? DBIncompleteError is conditional in _bsddb.c
try: try:
DBIncompleteError DBIncompleteError
...@@ -55,22 +51,22 @@ class Cond: ...@@ -55,22 +51,22 @@ class Cond:
class ExactCond(Cond): class ExactCond(Cond):
"""Acts as an exact match condition function""" """Acts as an exact match condition function"""
def __init__(self, strtomatch): def __init__(self, strtomatch, encoding="utf-8"):
self.strtomatch = strtomatch self.strtomatch = strtomatch.encode(encoding)
def __call__(self, s): def __call__(self, s):
return s == self.strtomatch return s == self.strtomatch
class PrefixCond(Cond): class PrefixCond(Cond):
"""Acts as a condition function for matching a string prefix""" """Acts as a condition function for matching a string prefix"""
def __init__(self, prefix): def __init__(self, prefix, encoding="utf-8"):
self.prefix = prefix self.prefix = prefix.encode(encoding)
def __call__(self, s): def __call__(self, s):
return s[:len(self.prefix)] == self.prefix return s[:len(self.prefix)] == self.prefix
class PostfixCond(Cond): class PostfixCond(Cond):
"""Acts as a condition function for matching a string postfix""" """Acts as a condition function for matching a string postfix"""
def __init__(self, postfix): def __init__(self, postfix, encoding="utf-8"):
self.postfix = postfix self.postfix = postfix.encode(encoding)
def __call__(self, s): def __call__(self, s):
return s[-len(self.postfix):] == self.postfix return s[-len(self.postfix):] == self.postfix
...@@ -80,7 +76,7 @@ class LikeCond(Cond): ...@@ -80,7 +76,7 @@ class LikeCond(Cond):
string. Case insensitive and % signs are wild cards. string. Case insensitive and % signs are wild cards.
This isn't perfect but it should work for the simple common cases. This isn't perfect but it should work for the simple common cases.
""" """
def __init__(self, likestr, re_flags=re.IGNORECASE): def __init__(self, likestr, re_flags=re.IGNORECASE, encoding="utf-8"):
# escape python re characters # escape python re characters
chars_to_escape = '.*+()[]?' chars_to_escape = '.*+()[]?'
for char in chars_to_escape : for char in chars_to_escape :
...@@ -88,8 +84,9 @@ class LikeCond(Cond): ...@@ -88,8 +84,9 @@ class LikeCond(Cond):
# convert %s to wildcards # convert %s to wildcards
self.likestr = likestr.replace('%', '.*') self.likestr = likestr.replace('%', '.*')
self.re = re.compile('^'+self.likestr+'$', re_flags) self.re = re.compile('^'+self.likestr+'$', re_flags)
self.encoding = encoding
def __call__(self, s): def __call__(self, s):
return self.re.match(s) return self.re.match(s.decode(self.encoding))
# #
# keys used to store database metadata # keys used to store database metadata
...@@ -264,10 +261,11 @@ class bsdTableDB : ...@@ -264,10 +261,11 @@ class bsdTableDB :
txn.commit() txn.commit()
txn = None txn = None
except DBError as dberror: except DBError as dberror:
raise TableDBError, dberror.args[1]
finally:
if txn: if txn:
txn.abort() txn.abort()
raise TableDBError, dberror.args[1] txn = None
def ListTableColumns(self, table): def ListTableColumns(self, table):
"""Return a list of columns in the given table. """Return a list of columns in the given table.
...@@ -342,9 +340,10 @@ class bsdTableDB : ...@@ -342,9 +340,10 @@ class bsdTableDB :
self.__load_column_info(table) self.__load_column_info(table)
except DBError as dberror: except DBError as dberror:
raise TableDBError, dberror.args[1]
finally:
if txn: if txn:
txn.abort() txn.abort()
raise TableDBError, dberror.args[1]
def __load_column_info(self, table) : def __load_column_info(self, table) :
...@@ -419,7 +418,11 @@ class bsdTableDB : ...@@ -419,7 +418,11 @@ class bsdTableDB :
if txn: if txn:
txn.abort() txn.abort()
self.db.delete(_rowid_key(table, rowid)) self.db.delete(_rowid_key(table, rowid))
txn = None
raise TableDBError, dberror.args[1], info[2] raise TableDBError, dberror.args[1], info[2]
finally:
if txn:
txn.abort()
def Modify(self, table, conditions={}, mappings={}): def Modify(self, table, conditions={}, mappings={}):
...@@ -465,10 +468,9 @@ class bsdTableDB : ...@@ -465,10 +468,9 @@ class bsdTableDB :
txn = None txn = None
# catch all exceptions here since we call unknown callables # catch all exceptions here since we call unknown callables
except: finally:
if txn: if txn:
txn.abort() txn.abort()
raise
except DBError as dberror: except DBError as dberror:
raise TableDBError, dberror.args[1] raise TableDBError, dberror.args[1]
...@@ -493,23 +495,23 @@ class bsdTableDB : ...@@ -493,23 +495,23 @@ class bsdTableDB :
for column in columns: for column in columns:
# delete the data key # delete the data key
try: try:
self.db.delete(_data_key(table, column, rowid), self.db.delete(_data_key(table, column,
rowid.encode("latin-1")),
txn) txn)
except DBNotFoundError: except DBNotFoundError:
# XXXXXXX column may not exist, assume no error # XXXXXXX column may not exist, assume no error
pass pass
try: try:
self.db.delete(_rowid_key(table, rowid), txn) self.db.delete(_rowid_key(table, rowid.encode("latin-1")), txn)
except DBNotFoundError: except DBNotFoundError:
# XXXXXXX row key somehow didn't exist, assume no error # XXXXXXX row key somehow didn't exist, assume no error
pass pass
txn.commit() txn.commit()
txn = None txn = None
except DBError as dberror: finally:
if txn: if txn:
txn.abort() txn.abort()
raise
except DBError as dberror: except DBError as dberror:
raise TableDBError, dberror.args[1] raise TableDBError, dberror.args[1]
...@@ -603,7 +605,7 @@ class bsdTableDB : ...@@ -603,7 +605,7 @@ class bsdTableDB :
key, data = cur.set_range(searchkey) key, data = cur.set_range(searchkey)
while key[:len(searchkey)] == searchkey: while key[:len(searchkey)] == searchkey:
# extract the rowid from the key # extract the rowid from the key
rowid = _D(key[-_rowid_str_len:]) rowid = key[-_rowid_str_len:].decode("latin-1")
if rowid not in rejected_rowids: if rowid not in rejected_rowids:
# if no condition was specified or the condition # if no condition was specified or the condition
...@@ -706,6 +708,7 @@ class bsdTableDB : ...@@ -706,6 +708,7 @@ class bsdTableDB :
del self.__tablecolumns[table] del self.__tablecolumns[table]
except DBError as dberror: except DBError as dberror:
raise TableDBError, dberror.args[1]
finally:
if txn: if txn:
txn.abort() txn.abort()
raise TableDBError, dberror.args[1]
...@@ -79,7 +79,7 @@ class TableDBTestCase(unittest.TestCase): ...@@ -79,7 +79,7 @@ class TableDBTestCase(unittest.TestCase):
values = list(values) values = list(values)
colval = pickle.loads(values[0][colname]) colval = pickle.loads(values[0][colname])
assert(colval > 3.141 and colval < 3.142) self.assertTrue(colval > 3.141 and colval < 3.142)
def test02(self): def test02(self):
...@@ -105,11 +105,11 @@ class TableDBTestCase(unittest.TestCase): ...@@ -105,11 +105,11 @@ class TableDBTestCase(unittest.TestCase):
conditions={col0: lambda x: pickle.loads(x) >= 8}) conditions={col0: lambda x: pickle.loads(x) >= 8})
values = list(values) values = list(values)
assert len(values) == 2 self.assertEquals(len(values), 2)
if values[0]['Species'] == 'Penguin' : if values[0]['Species'] == b'Penguin' :
assert values[1]['Species'] == 'SR-71A Blackbird' self.assertEquals(values[1]['Species'], b'SR-71A Blackbird')
elif values[0]['Species'] == 'SR-71A Blackbird' : elif values[0]['Species'] == b'SR-71A Blackbird' :
assert values[1]['Species'] == 'Penguin' self.assertEquals(values[1]['Species'], b'Penguin')
else : else :
if verbose: if verbose:
print("values= %r" % (values,)) print("values= %r" % (values,))
...@@ -139,13 +139,13 @@ class TableDBTestCase(unittest.TestCase): ...@@ -139,13 +139,13 @@ class TableDBTestCase(unittest.TestCase):
{'a': "", {'a': "",
'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1), 'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1),
'f': "Zero"}) 'f': "Zero"})
assert 0 self.fail("exception not raised")
except dbtables.TableDBError: except dbtables.TableDBError:
pass pass
try: try:
self.tdb.Select(tabname, [], conditions={'foo': '123'}) self.tdb.Select(tabname, [], conditions={'foo': '123'})
assert 0 self.fail("exception not raised")
except dbtables.TableDBError: except dbtables.TableDBError:
pass pass
...@@ -174,7 +174,7 @@ class TableDBTestCase(unittest.TestCase): ...@@ -174,7 +174,7 @@ class TableDBTestCase(unittest.TestCase):
values = self.tdb.Select(tabname, ['b', 'a', 'd'], values = self.tdb.Select(tabname, ['b', 'a', 'd'],
conditions={'e': re.compile('wuzzy').search, conditions={'e': re.compile('wuzzy').search,
'a': re.compile('^[0-9]+$').match}) 'a': re.compile('^[0-9]+$').match})
assert len(values) == 2 self.assertEquals(len(values), 2)
# now lets delete one of them and try again # now lets delete one of them and try again
self.tdb.Delete(tabname, conditions={'b': dbtables.ExactCond('good')}) self.tdb.Delete(tabname, conditions={'b': dbtables.ExactCond('good')})
...@@ -182,14 +182,14 @@ class TableDBTestCase(unittest.TestCase): ...@@ -182,14 +182,14 @@ class TableDBTestCase(unittest.TestCase):
tabname, ['a', 'd', 'b'], tabname, ['a', 'd', 'b'],
conditions={'e': dbtables.PrefixCond('Fuzzy')}) conditions={'e': dbtables.PrefixCond('Fuzzy')})
values = list(values) values = list(values)
assert len(values) == 1 self.assertEquals(len(values), 1)
assert values[0]['d'] == None self.assertEquals(values[0]['d'], None)
values = self.tdb.Select(tabname, ['b'], values = self.tdb.Select(tabname, ['b'],
conditions={'c': lambda c: c == 'meep'}) conditions={'c': lambda c: c.decode("ascii") == 'meep'})
values = list(values) values = list(values)
assert len(values) == 1 self.assertEquals(len(values), 1)
assert values[0]['b'] == "bad" self.assertEquals(values[0]['b'], b"bad")
def test04_MultiCondSelect(self): def test04_MultiCondSelect(self):
...@@ -205,7 +205,7 @@ class TableDBTestCase(unittest.TestCase): ...@@ -205,7 +205,7 @@ class TableDBTestCase(unittest.TestCase):
{'a': "", {'a': "",
'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1), 'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1),
'f': "Zero"}) 'f': "Zero"})
assert 0 self.fail("exception not raised")
except dbtables.TableDBError: except dbtables.TableDBError:
pass pass
...@@ -229,7 +229,7 @@ class TableDBTestCase(unittest.TestCase): ...@@ -229,7 +229,7 @@ class TableDBTestCase(unittest.TestCase):
'a': dbtables.ExactCond('A'), 'a': dbtables.ExactCond('A'),
'd': dbtables.PrefixCond('-') 'd': dbtables.PrefixCond('-')
} ) } )
assert len(values) == 0, values self.assertEquals(len(values), 0, values)
def test_CreateOrExtend(self): def test_CreateOrExtend(self):
...@@ -242,7 +242,7 @@ class TableDBTestCase(unittest.TestCase): ...@@ -242,7 +242,7 @@ class TableDBTestCase(unittest.TestCase):
{'taste': 'crap', {'taste': 'crap',
'filling': 'no', 'filling': 'no',
'is it Guinness?': 'no'}) 'is it Guinness?': 'no'})
assert 0, "Insert should've failed due to bad column name" self.fail("Insert should've failed due to bad column name")
except: except:
pass pass
self.tdb.CreateOrExtendTable(tabname, self.tdb.CreateOrExtendTable(tabname,
...@@ -277,17 +277,17 @@ class TableDBTestCase(unittest.TestCase): ...@@ -277,17 +277,17 @@ class TableDBTestCase(unittest.TestCase):
tabname, ['p', 'e'], tabname, ['p', 'e'],
conditions={'e': dbtables.PrefixCond('the l')}) conditions={'e': dbtables.PrefixCond('the l')})
values = list(values) values = list(values)
assert len(values) == 2, values self.assertEquals(len(values), 2)
assert values[0]['e'] == values[1]['e'], values self.assertEquals(values[0]['e'], values[1]['e'])
assert values[0]['p'] != values[1]['p'], values self.assertNotEquals(values[0]['p'], values[1]['p'])
values = self.tdb.Select( values = self.tdb.Select(
tabname, ['d', 'a'], tabname, ['d', 'a'],
conditions={'a': dbtables.LikeCond('%aardvark%')}) conditions={'a': dbtables.LikeCond('%aardvark%')})
values = list(values) values = list(values)
assert len(values) == 1, values self.assertEquals(len(values), 1)
assert values[0]['d'] == "is for dog", values self.assertEquals(values[0]['d'], b"is for dog")
assert values[0]['a'] == "is for aardvark", values self.assertEquals(values[0]['a'], b"is for aardvark")
values = self.tdb.Select(tabname, None, values = self.tdb.Select(tabname, None,
{'b': dbtables.Cond(), {'b': dbtables.Cond(),
...@@ -297,9 +297,9 @@ class TableDBTestCase(unittest.TestCase): ...@@ -297,9 +297,9 @@ class TableDBTestCase(unittest.TestCase):
'c':dbtables.PrefixCond('is for'), 'c':dbtables.PrefixCond('is for'),
'p':lambda s: not s}) 'p':lambda s: not s})
values = list(values) values = list(values)
assert len(values) == 1, values self.assertEquals(len(values), 1)
assert values[0]['d'] == "is for dog", values self.assertEquals(values[0]['d'], b"is for dog")
assert values[0]['a'] == "is for aardvark", values self.assertEquals(values[0]['a'], b"is for aardvark")
def test_Delete(self): def test_Delete(self):
tabname = "test_Delete" tabname = "test_Delete"
...@@ -315,7 +315,7 @@ class TableDBTestCase(unittest.TestCase): ...@@ -315,7 +315,7 @@ class TableDBTestCase(unittest.TestCase):
self.tdb.Delete(tabname, conditions={'x': dbtables.PrefixCond('X')}) self.tdb.Delete(tabname, conditions={'x': dbtables.PrefixCond('X')})
values = self.tdb.Select(tabname, ['y'], values = self.tdb.Select(tabname, ['y'],
conditions={'x': dbtables.PrefixCond('X')}) conditions={'x': dbtables.PrefixCond('X')})
assert len(values) == 0 self.assertEquals(len(values), 0)
def test_Modify(self): def test_Modify(self):
tabname = "test_Modify" tabname = "test_Modify"
...@@ -362,26 +362,26 @@ class TableDBTestCase(unittest.TestCase): ...@@ -362,26 +362,26 @@ class TableDBTestCase(unittest.TestCase):
tabname, None, tabname, None,
conditions={'Type': dbtables.ExactCond('Unknown')}) conditions={'Type': dbtables.ExactCond('Unknown')})
values = list(values) values = list(values)
assert len(values) == 1, values self.assertEquals(len(values), 1)
assert values[0]['Name'] == None, values self.assertEquals(values[0]['Name'], None)
assert values[0]['Access'] == None, values self.assertEquals(values[0]['Access'], None)
# Modify value by select conditions # Modify value by select conditions
values = self.tdb.Select( values = self.tdb.Select(
tabname, None, tabname, None,
conditions={'Name': dbtables.ExactCond('Nifty.MP3')}) conditions={'Name': dbtables.ExactCond('Nifty.MP3')})
values = list(values) values = list(values)
assert len(values) == 1, values self.assertEquals(len(values), 1)
assert values[0]['Type'] == "MP3", values self.assertEquals(values[0]['Type'], b"MP3")
assert values[0]['Access'] == "2", values self.assertEquals(values[0]['Access'], b"2")
# Make sure change applied only to select conditions # Make sure change applied only to select conditions
values = self.tdb.Select( values = self.tdb.Select(
tabname, None, conditions={'Name': dbtables.LikeCond('%doc%')}) tabname, None, conditions={'Name': dbtables.LikeCond('%doc%')})
values = list(values) values = list(values)
assert len(values) == 1, values self.assertEquals(len(values), 1)
assert values[0]['Type'] == "Word", values self.assertEquals(values[0]['Type'], b"Word")
assert values[0]['Access'] == "9", values self.assertEquals(values[0]['Access'], b"9")
def test_suite(): def test_suite():
......
...@@ -24,8 +24,7 @@ if 'silent' in sys.argv: # take care of old flag, just in case ...@@ -24,8 +24,7 @@ if 'silent' in sys.argv: # take care of old flag, just in case
def suite(): def suite():
try: try:
# this is special, it used to segfault the interpreter # this is special, it used to segfault the interpreter
#import bsddb.test.test_1413192 import bsddb.test.test_1413192
pass
except: except:
for f in ['__db.001', '__db.002', '__db.003', 'log.0000000001']: for f in ['__db.001', '__db.002', '__db.003', 'log.0000000001']:
unlink(f) unlink(f)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment