- Issue #17477: Update the bsddb module to pybsddb 5.3.0, supporting

db-5.x, and dropping support for db-4.1 and db-4.2.
This commit is contained in:
doko@ubuntu.com 2013-03-19 14:46:29 -07:00
parent 868f0aac37
commit 4950a3b6cc
23 changed files with 1226 additions and 710 deletions

View File

@ -33,7 +33,7 @@
#---------------------------------------------------------------------- #----------------------------------------------------------------------
"""Support for Berkeley DB 4.1 through 4.8 with a simple interface. """Support for Berkeley DB 4.3 through 5.3 with a simple interface.
For the full featured object oriented interface use the bsddb.db module For the full featured object oriented interface use the bsddb.db module
instead. It mirrors the Oracle Berkeley DB C API. instead. It mirrors the Oracle Berkeley DB C API.
@ -138,7 +138,7 @@ class _iter_mixin(MutableMapping):
except _bsddb.DBCursorClosedError: except _bsddb.DBCursorClosedError:
# the database was modified during iteration. abort. # the database was modified during iteration. abort.
pass pass
# When Python 2.3 not supported in bsddb3, we can change this to "finally" # When Python 2.4 not supported in bsddb3, we can change this to "finally"
except : except :
self._in_iter -= 1 self._in_iter -= 1
raise raise
@ -181,7 +181,7 @@ class _iter_mixin(MutableMapping):
except _bsddb.DBCursorClosedError: except _bsddb.DBCursorClosedError:
# the database was modified during iteration. abort. # the database was modified during iteration. abort.
pass pass
# When Python 2.3 not supported in bsddb3, we can change this to "finally" # When Python 2.4 not supported in bsddb3, we can change this to "finally"
except : except :
self._in_iter -= 1 self._in_iter -= 1
raise raise

View File

@ -30,12 +30,7 @@ else :
import db import db
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
try: from UserDict import DictMixin as MutableMapping
from UserDict import DictMixin
except ImportError:
# DictMixin is new in Python 2.3
class DictMixin: pass
MutableMapping = DictMixin
else : else :
import collections import collections
MutableMapping = collections.MutableMapping MutableMapping = collections.MutableMapping
@ -196,6 +191,8 @@ class DB(MutableMapping):
return self._cobj.set_bt_compare(*args, **kwargs) return self._cobj.set_bt_compare(*args, **kwargs)
def set_cachesize(self, *args, **kwargs): def set_cachesize(self, *args, **kwargs):
return self._cobj.set_cachesize(*args, **kwargs) return self._cobj.set_cachesize(*args, **kwargs)
def set_dup_compare(self, *args, **kwargs) :
return self._cobj.set_dup_compare(*args, **kwargs)
def set_flags(self, *args, **kwargs): def set_flags(self, *args, **kwargs):
return self._cobj.set_flags(*args, **kwargs) return self._cobj.set_flags(*args, **kwargs)
def set_h_ffactor(self, *args, **kwargs): def set_h_ffactor(self, *args, **kwargs):

View File

@ -43,7 +43,7 @@ else :
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
import cPickle import cPickle
else : else :
# When we drop support for python 2.3 and 2.4 # When we drop support for python 2.4
# we could use: (in 2.5 we need a __future__ statement) # we could use: (in 2.5 we need a __future__ statement)
# #
# with warnings.catch_warnings(): # with warnings.catch_warnings():
@ -51,7 +51,7 @@ else :
# ... # ...
# #
# We can not use "with" as is, because it would be invalid syntax # We can not use "with" as is, because it would be invalid syntax
# in python 2.3, 2.4 and (with no __future__) 2.5. # in python 2.4 and (with no __future__) 2.5.
# Here we simulate "with" following PEP 343 : # Here we simulate "with" following PEP 343 :
import warnings import warnings
w = warnings.catch_warnings() w = warnings.catch_warnings()
@ -65,32 +65,12 @@ else :
w.__exit__() w.__exit__()
del w del w
#At version 2.3 cPickle switched to using protocol instead of bin HIGHEST_PROTOCOL = cPickle.HIGHEST_PROTOCOL
if sys.version_info >= (2, 3): def _dumps(object, protocol):
HIGHEST_PROTOCOL = cPickle.HIGHEST_PROTOCOL return cPickle.dumps(object, protocol=protocol)
# In python 2.3.*, "cPickle.dumps" accepts no
# named parameters. "pickle.dumps" accepts them,
# so this seems a bug.
if sys.version_info < (2, 4):
def _dumps(object, protocol):
return cPickle.dumps(object, protocol)
else :
def _dumps(object, protocol):
return cPickle.dumps(object, protocol=protocol)
else:
HIGHEST_PROTOCOL = None
def _dumps(object, protocol):
return cPickle.dumps(object, bin=protocol)
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
try: from UserDict import DictMixin as MutableMapping
from UserDict import DictMixin
except ImportError:
# DictMixin is new in Python 2.3
class DictMixin: pass
MutableMapping = DictMixin
else : else :
import collections import collections
MutableMapping = collections.MutableMapping MutableMapping = collections.MutableMapping

View File

@ -30,7 +30,7 @@ else :
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
import cPickle as pickle import cPickle as pickle
else : else :
# When we drop support for python 2.3 and 2.4 # When we drop support for python 2.4
# we could use: (in 2.5 we need a __future__ statement) # we could use: (in 2.5 we need a __future__ statement)
# #
# with warnings.catch_warnings(): # with warnings.catch_warnings():
@ -38,7 +38,7 @@ else :
# ... # ...
# #
# We can not use "with" as is, because it would be invalid syntax # We can not use "with" as is, because it would be invalid syntax
# in python 2.3, 2.4 and (with no __future__) 2.5. # in python 2.4 and (with no __future__) 2.5.
# Here we simulate "with" following PEP 343 : # Here we simulate "with" following PEP 343 :
import warnings import warnings
w = warnings.catch_warnings() w = warnings.catch_warnings()

View File

@ -392,10 +392,8 @@ if sys.version_info[0] >= 3 :
return self._dbenv.get_tmp_dir().decode(charset) return self._dbenv.get_tmp_dir().decode(charset)
def get_data_dirs(self) : def get_data_dirs(self) :
# Have to use a list comprehension and not
# generators, because we are supporting Python 2.3.
return tuple( return tuple(
[i.decode(charset) for i in self._dbenv.get_data_dirs()]) (i.decode(charset) for i in self._dbenv.get_data_dirs()))
class DBSequence_py3k(object) : class DBSequence_py3k(object) :
def __init__(self, db, *args, **kwargs) : def __init__(self, db, *args, **kwargs) :
@ -484,6 +482,8 @@ def print_versions():
print '-=' * 38 print '-=' * 38
print db.DB_VERSION_STRING print db.DB_VERSION_STRING
print 'bsddb.db.version(): %s' % (db.version(), ) print 'bsddb.db.version(): %s' % (db.version(), )
if db.version() >= (5, 0) :
print 'bsddb.db.full_version(): %s' %repr(db.full_version())
print 'bsddb.db.__version__: %s' % db.__version__ print 'bsddb.db.__version__: %s' % db.__version__
print 'bsddb.db.cvsid: %s' % db.cvsid print 'bsddb.db.cvsid: %s' % db.cvsid
@ -528,7 +528,8 @@ def get_new_database_path() :
# This path can be overriden via "set_test_path_prefix()". # This path can be overriden via "set_test_path_prefix()".
import os, os.path import os, os.path
get_new_path.prefix=os.path.join(os.sep,"tmp","z-Berkeley_DB") get_new_path.prefix=os.path.join(os.environ.get("TMPDIR",
os.path.join(os.sep,"tmp")), "z-Berkeley_DB")
get_new_path.num=0 get_new_path.num=0
def get_test_path_prefix() : def get_test_path_prefix() :

View File

@ -9,6 +9,7 @@ import string
from pprint import pprint from pprint import pprint
import unittest import unittest
import time import time
import sys
from test_all import db, test_support, verbose, get_new_environment_path, \ from test_all import db, test_support, verbose, get_new_environment_path, \
get_new_database_path get_new_database_path
@ -44,13 +45,6 @@ class BasicTestCase(unittest.TestCase):
_numKeys = 1002 # PRIVATE. NOTE: must be an even value _numKeys = 1002 # PRIVATE. NOTE: must be an even value
import sys
if sys.version_info < (2, 4):
def assertTrue(self, expr, msg=None):
self.failUnless(expr,msg=msg)
def assertFalse(self, expr, msg=None):
self.failIf(expr,msg=msg)
def setUp(self): def setUp(self):
if self.useEnv: if self.useEnv:
self.homeDir=get_new_environment_path() self.homeDir=get_new_environment_path()
@ -74,7 +68,6 @@ class BasicTestCase(unittest.TestCase):
# create and open the DB # create and open the DB
self.d = db.DB(self.env) self.d = db.DB(self.env)
if not self.useEnv : if not self.useEnv :
if db.version() >= (4, 2) :
self.d.set_cachesize(*self.cachesize) self.d.set_cachesize(*self.cachesize)
cachesize = self.d.get_cachesize() cachesize = self.d.get_cachesize()
self.assertEqual(cachesize[0], self.cachesize[0]) self.assertEqual(cachesize[0], self.cachesize[0])
@ -161,7 +154,6 @@ class BasicTestCase(unittest.TestCase):
try: try:
d.delete('abcd') d.delete('abcd')
except db.DBNotFoundError, val: except db.DBNotFoundError, val:
import sys
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
self.assertEqual(val[0], db.DB_NOTFOUND) self.assertEqual(val[0], db.DB_NOTFOUND)
else : else :
@ -184,7 +176,6 @@ class BasicTestCase(unittest.TestCase):
try: try:
d.put('abcd', 'this should fail', flags=db.DB_NOOVERWRITE) d.put('abcd', 'this should fail', flags=db.DB_NOOVERWRITE)
except db.DBKeyExistError, val: except db.DBKeyExistError, val:
import sys
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
self.assertEqual(val[0], db.DB_KEYEXIST) self.assertEqual(val[0], db.DB_KEYEXIST)
else : else :
@ -338,7 +329,6 @@ class BasicTestCase(unittest.TestCase):
rec = c.next() rec = c.next()
except db.DBNotFoundError, val: except db.DBNotFoundError, val:
if get_raises_error: if get_raises_error:
import sys
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
self.assertEqual(val[0], db.DB_NOTFOUND) self.assertEqual(val[0], db.DB_NOTFOUND)
else : else :
@ -363,7 +353,6 @@ class BasicTestCase(unittest.TestCase):
rec = c.prev() rec = c.prev()
except db.DBNotFoundError, val: except db.DBNotFoundError, val:
if get_raises_error: if get_raises_error:
import sys
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
self.assertEqual(val[0], db.DB_NOTFOUND) self.assertEqual(val[0], db.DB_NOTFOUND)
else : else :
@ -390,7 +379,6 @@ class BasicTestCase(unittest.TestCase):
try: try:
n = c.set('bad key') n = c.set('bad key')
except db.DBNotFoundError, val: except db.DBNotFoundError, val:
import sys
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
self.assertEqual(val[0], db.DB_NOTFOUND) self.assertEqual(val[0], db.DB_NOTFOUND)
else : else :
@ -408,7 +396,6 @@ class BasicTestCase(unittest.TestCase):
try: try:
n = c.get_both('0404', 'bad data') n = c.get_both('0404', 'bad data')
except db.DBNotFoundError, val: except db.DBNotFoundError, val:
import sys
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
self.assertEqual(val[0], db.DB_NOTFOUND) self.assertEqual(val[0], db.DB_NOTFOUND)
else : else :
@ -441,7 +428,6 @@ class BasicTestCase(unittest.TestCase):
rec = c.current() rec = c.current()
except db.DBKeyEmptyError, val: except db.DBKeyEmptyError, val:
if get_raises_error: if get_raises_error:
import sys
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
self.assertEqual(val[0], db.DB_KEYEMPTY) self.assertEqual(val[0], db.DB_KEYEMPTY)
else : else :
@ -490,7 +476,6 @@ class BasicTestCase(unittest.TestCase):
# a bug may cause a NULL pointer dereference... # a bug may cause a NULL pointer dereference...
getattr(c, method)(*args) getattr(c, method)(*args)
except db.DBError, val: except db.DBError, val:
import sys
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
self.assertEqual(val[0], 0) self.assertEqual(val[0], 0)
else : else :
@ -712,11 +697,6 @@ class BasicHashWithEnvTestCase(BasicWithEnvTestCase):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class BasicTransactionTestCase(BasicTestCase): class BasicTransactionTestCase(BasicTestCase):
import sys
if sys.version_info < (2, 4):
def assertTrue(self, expr, msg=None):
return self.failUnless(expr,msg=msg)
if (sys.version_info < (2, 7)) or ((sys.version_info >= (3, 0)) and if (sys.version_info < (2, 7)) or ((sys.version_info >= (3, 0)) and
(sys.version_info < (3, 2))) : (sys.version_info < (3, 2))) :
def assertIn(self, a, b, msg=None) : def assertIn(self, a, b, msg=None) :
@ -792,7 +772,6 @@ class BasicTransactionTestCase(BasicTestCase):
for log in logs: for log in logs:
if verbose: if verbose:
print 'log file: ' + log print 'log file: ' + log
if db.version() >= (4,2):
logs = self.env.log_archive(db.DB_ARCH_REMOVE) logs = self.env.log_archive(db.DB_ARCH_REMOVE)
self.assertTrue(not logs) self.assertTrue(not logs)
@ -875,7 +854,6 @@ class BasicTransactionTestCase(BasicTestCase):
#---------------------------------------- #----------------------------------------
if db.version() >= (4, 2) :
def test_get_tx_max(self) : def test_get_tx_max(self) :
self.assertEqual(self.env.get_tx_max(), 30) self.assertEqual(self.env.get_tx_max(), 30)
@ -1098,11 +1076,6 @@ class HashMultiDBTestCase(BasicMultiDBTestCase):
class PrivateObject(unittest.TestCase) : class PrivateObject(unittest.TestCase) :
import sys
if sys.version_info < (2, 4):
def assertTrue(self, expr, msg=None):
self.failUnless(expr,msg=msg)
def tearDown(self) : def tearDown(self) :
del self.obj del self.obj
@ -1116,7 +1089,6 @@ class PrivateObject(unittest.TestCase) :
self.assertTrue(a is b) # Object identity self.assertTrue(a is b) # Object identity
def test03_leak_assignment(self) : def test03_leak_assignment(self) :
import sys
a = "example of private object" a = "example of private object"
refcount = sys.getrefcount(a) refcount = sys.getrefcount(a)
self.obj.set_private(a) self.obj.set_private(a)
@ -1125,7 +1097,6 @@ class PrivateObject(unittest.TestCase) :
self.assertEqual(refcount, sys.getrefcount(a)) self.assertEqual(refcount, sys.getrefcount(a))
def test04_leak_GC(self) : def test04_leak_GC(self) :
import sys
a = "example of private object" a = "example of private object"
refcount = sys.getrefcount(a) refcount = sys.getrefcount(a)
self.obj.set_private(a) self.obj.set_private(a)
@ -1141,11 +1112,6 @@ class DBPrivateObject(PrivateObject) :
self.obj = db.DB() self.obj = db.DB()
class CrashAndBurn(unittest.TestCase) : class CrashAndBurn(unittest.TestCase) :
import sys
if sys.version_info < (2, 4):
def assertTrue(self, expr, msg=None):
self.failUnless(expr,msg=msg)
#def test01_OpenCrash(self) : #def test01_OpenCrash(self) :
# # See http://bugs.python.org/issue3307 # # See http://bugs.python.org/issue3307
# self.assertRaises(db.DBInvalidArgError, db.DB, None, 65535) # self.assertRaises(db.DBInvalidArgError, db.DB, None, 65535)

View File

@ -1,5 +1,5 @@
""" """
TestCases for python DB Btree key comparison function. TestCases for python DB duplicate and Btree key comparison function.
""" """
import sys, os, re import sys, os, re
@ -20,31 +20,24 @@ def cmp(a, b) :
lexical_cmp = cmp lexical_cmp = cmp
def lowercase_cmp(left, right): def lowercase_cmp(left, right) :
return cmp (left.lower(), right.lower()) return cmp(left.lower(), right.lower())
def make_reverse_comparator (cmp): def make_reverse_comparator(cmp) :
def reverse (left, right, delegate=cmp): def reverse(left, right, delegate=cmp) :
return - delegate (left, right) return - delegate(left, right)
return reverse return reverse
_expected_lexical_test_data = ['', 'CCCP', 'a', 'aaa', 'b', 'c', 'cccce', 'ccccf'] _expected_lexical_test_data = ['', 'CCCP', 'a', 'aaa', 'b', 'c', 'cccce', 'ccccf']
_expected_lowercase_test_data = ['', 'a', 'aaa', 'b', 'c', 'CC', 'cccce', 'ccccf', 'CCCP'] _expected_lowercase_test_data = ['', 'a', 'aaa', 'b', 'c', 'CC', 'cccce', 'ccccf', 'CCCP']
class ComparatorTests (unittest.TestCase): class ComparatorTests(unittest.TestCase) :
if sys.version_info < (2, 4) : def comparator_test_helper(self, comparator, expected_data) :
def assertTrue(self, expr, msg=None) :
return self.failUnless(expr,msg=msg)
def comparator_test_helper (self, comparator, expected_data):
data = expected_data[:] data = expected_data[:]
import sys import sys
if sys.version_info < (2, 6) : if sys.version_info < (2, 6) :
if sys.version_info < (2, 4) : data.sort(cmp=comparator)
data.sort(comparator)
else :
data.sort(cmp=comparator)
else : # Insertion Sort. Please, improve else : # Insertion Sort. Please, improve
data2 = [] data2 = []
for i in data : for i in data :
@ -60,143 +53,139 @@ class ComparatorTests (unittest.TestCase):
self.assertEqual(data, expected_data, self.assertEqual(data, expected_data,
"comparator `%s' is not right: %s vs. %s" "comparator `%s' is not right: %s vs. %s"
% (comparator, expected_data, data)) % (comparator, expected_data, data))
def test_lexical_comparator (self): def test_lexical_comparator(self) :
self.comparator_test_helper (lexical_cmp, _expected_lexical_test_data) self.comparator_test_helper(lexical_cmp, _expected_lexical_test_data)
def test_reverse_lexical_comparator (self): def test_reverse_lexical_comparator(self) :
rev = _expected_lexical_test_data[:] rev = _expected_lexical_test_data[:]
rev.reverse () rev.reverse()
self.comparator_test_helper (make_reverse_comparator (lexical_cmp), self.comparator_test_helper(make_reverse_comparator(lexical_cmp),
rev) rev)
def test_lowercase_comparator (self): def test_lowercase_comparator(self) :
self.comparator_test_helper (lowercase_cmp, self.comparator_test_helper(lowercase_cmp,
_expected_lowercase_test_data) _expected_lowercase_test_data)
class AbstractBtreeKeyCompareTestCase (unittest.TestCase): class AbstractBtreeKeyCompareTestCase(unittest.TestCase) :
env = None env = None
db = None db = None
if sys.version_info < (2, 4) :
def assertTrue(self, expr, msg=None):
self.failUnless(expr,msg=msg)
if (sys.version_info < (2, 7)) or ((sys.version_info >= (3,0)) and if (sys.version_info < (2, 7)) or ((sys.version_info >= (3,0)) and
(sys.version_info < (3, 2))) : (sys.version_info < (3, 2))) :
def assertLess(self, a, b, msg=None) : def assertLess(self, a, b, msg=None) :
return self.assertTrue(a<b, msg=msg) return self.assertTrue(a<b, msg=msg)
def setUp (self): def setUp(self) :
self.filename = self.__class__.__name__ + '.db' self.filename = self.__class__.__name__ + '.db'
self.homeDir = get_new_environment_path() self.homeDir = get_new_environment_path()
env = db.DBEnv() env = db.DBEnv()
env.open (self.homeDir, env.open(self.homeDir,
db.DB_CREATE | db.DB_INIT_MPOOL db.DB_CREATE | db.DB_INIT_MPOOL
| db.DB_INIT_LOCK | db.DB_THREAD) | db.DB_INIT_LOCK | db.DB_THREAD)
self.env = env self.env = env
def tearDown (self): def tearDown(self) :
self.closeDB() self.closeDB()
if self.env is not None: if self.env is not None:
self.env.close() self.env.close()
self.env = None self.env = None
test_support.rmtree(self.homeDir) test_support.rmtree(self.homeDir)
def addDataToDB (self, data): def addDataToDB(self, data) :
i = 0 i = 0
for item in data: for item in data:
self.db.put (item, str (i)) self.db.put(item, str(i))
i = i + 1 i = i + 1
def createDB (self, key_comparator): def createDB(self, key_comparator) :
self.db = db.DB (self.env) self.db = db.DB(self.env)
self.setupDB (key_comparator) self.setupDB(key_comparator)
self.db.open (self.filename, "test", db.DB_BTREE, db.DB_CREATE) self.db.open(self.filename, "test", db.DB_BTREE, db.DB_CREATE)
def setupDB (self, key_comparator): def setupDB(self, key_comparator) :
self.db.set_bt_compare (key_comparator) self.db.set_bt_compare(key_comparator)
def closeDB (self): def closeDB(self) :
if self.db is not None: if self.db is not None:
self.db.close () self.db.close()
self.db = None self.db = None
def startTest (self): def startTest(self) :
pass pass
def finishTest (self, expected = None): def finishTest(self, expected = None) :
if expected is not None: if expected is not None:
self.check_results (expected) self.check_results(expected)
self.closeDB () self.closeDB()
def check_results (self, expected): def check_results(self, expected) :
curs = self.db.cursor () curs = self.db.cursor()
try: try:
index = 0 index = 0
rec = curs.first () rec = curs.first()
while rec: while rec:
key, ignore = rec key, ignore = rec
self.assertLess(index, len (expected), self.assertLess(index, len(expected),
"to many values returned from cursor") "to many values returned from cursor")
self.assertEqual(expected[index], key, self.assertEqual(expected[index], key,
"expected value `%s' at %d but got `%s'" "expected value `%s' at %d but got `%s'"
% (expected[index], index, key)) % (expected[index], index, key))
index = index + 1 index = index + 1
rec = curs.next () rec = curs.next()
self.assertEqual(index, len (expected), self.assertEqual(index, len(expected),
"not enough values returned from cursor") "not enough values returned from cursor")
finally: finally:
curs.close () curs.close()
class BtreeKeyCompareTestCase (AbstractBtreeKeyCompareTestCase): class BtreeKeyCompareTestCase(AbstractBtreeKeyCompareTestCase) :
def runCompareTest (self, comparator, data): def runCompareTest(self, comparator, data) :
self.startTest () self.startTest()
self.createDB (comparator) self.createDB(comparator)
self.addDataToDB (data) self.addDataToDB(data)
self.finishTest (data) self.finishTest(data)
def test_lexical_ordering (self): def test_lexical_ordering(self) :
self.runCompareTest (lexical_cmp, _expected_lexical_test_data) self.runCompareTest(lexical_cmp, _expected_lexical_test_data)
def test_reverse_lexical_ordering (self): def test_reverse_lexical_ordering(self) :
expected_rev_data = _expected_lexical_test_data[:] expected_rev_data = _expected_lexical_test_data[:]
expected_rev_data.reverse () expected_rev_data.reverse()
self.runCompareTest (make_reverse_comparator (lexical_cmp), self.runCompareTest(make_reverse_comparator(lexical_cmp),
expected_rev_data) expected_rev_data)
def test_compare_function_useless (self): def test_compare_function_useless(self) :
self.startTest () self.startTest()
def socialist_comparator (l, r): def socialist_comparator(l, r) :
return 0 return 0
self.createDB (socialist_comparator) self.createDB(socialist_comparator)
self.addDataToDB (['b', 'a', 'd']) self.addDataToDB(['b', 'a', 'd'])
# all things being equal the first key will be the only key # all things being equal the first key will be the only key
# in the database... (with the last key's value fwiw) # in the database... (with the last key's value fwiw)
self.finishTest (['b']) self.finishTest(['b'])
class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase): class BtreeExceptionsTestCase(AbstractBtreeKeyCompareTestCase) :
def test_raises_non_callable (self): def test_raises_non_callable(self) :
self.startTest () self.startTest()
self.assertRaises (TypeError, self.createDB, 'abc') self.assertRaises(TypeError, self.createDB, 'abc')
self.assertRaises (TypeError, self.createDB, None) self.assertRaises(TypeError, self.createDB, None)
self.finishTest () self.finishTest()
def test_set_bt_compare_with_function (self): def test_set_bt_compare_with_function(self) :
self.startTest () self.startTest()
self.createDB (lexical_cmp) self.createDB(lexical_cmp)
self.finishTest () self.finishTest()
def check_results (self, results): def check_results(self, results) :
pass pass
def test_compare_function_incorrect (self): def test_compare_function_incorrect(self) :
self.startTest () self.startTest()
def bad_comparator (l, r): def bad_comparator(l, r) :
return 1 return 1
# verify that set_bt_compare checks that comparator('', '') == 0 # verify that set_bt_compare checks that comparator('', '') == 0
self.assertRaises (TypeError, self.createDB, bad_comparator) self.assertRaises(TypeError, self.createDB, bad_comparator)
self.finishTest () self.finishTest()
def verifyStderr(self, method, successRe): def verifyStderr(self, method, successRe) :
""" """
Call method() while capturing sys.stderr output internally and Call method() while capturing sys.stderr output internally and
call self.fail() if successRe.search() does not match the stderr call self.fail() if successRe.search() does not match the stderr
@ -210,64 +199,249 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
temp = sys.stderr temp = sys.stderr
sys.stderr = stdErr sys.stderr = stdErr
errorOut = temp.getvalue() errorOut = temp.getvalue()
if not successRe.search(errorOut): if not successRe.search(errorOut) :
self.fail("unexpected stderr output:\n"+errorOut) self.fail("unexpected stderr output:\n"+errorOut)
if sys.version_info < (3, 0) : # XXX: How to do this in Py3k ??? if sys.version_info < (3, 0) : # XXX: How to do this in Py3k ???
sys.exc_traceback = sys.last_traceback = None sys.exc_traceback = sys.last_traceback = None
def _test_compare_function_exception (self): def _test_compare_function_exception(self) :
self.startTest () self.startTest()
def bad_comparator (l, r): def bad_comparator(l, r) :
if l == r: if l == r:
# pass the set_bt_compare test # pass the set_bt_compare test
return 0 return 0
raise RuntimeError, "i'm a naughty comparison function" raise RuntimeError, "i'm a naughty comparison function"
self.createDB (bad_comparator) self.createDB(bad_comparator)
#print "\n*** test should print 2 uncatchable tracebacks ***" #print "\n*** test should print 2 uncatchable tracebacks ***"
self.addDataToDB (['a', 'b', 'c']) # this should raise, but... self.addDataToDB(['a', 'b', 'c']) # this should raise, but...
self.finishTest () self.finishTest()
def test_compare_function_exception(self): def test_compare_function_exception(self) :
self.verifyStderr( self.verifyStderr(
self._test_compare_function_exception, self._test_compare_function_exception,
re.compile('(^RuntimeError:.* naughty.*){2}', re.M|re.S) re.compile('(^RuntimeError:.* naughty.*){2}', re.M|re.S)
) )
def _test_compare_function_bad_return (self): def _test_compare_function_bad_return(self) :
self.startTest () self.startTest()
def bad_comparator (l, r): def bad_comparator(l, r) :
if l == r: if l == r:
# pass the set_bt_compare test # pass the set_bt_compare test
return 0 return 0
return l return l
self.createDB (bad_comparator) self.createDB(bad_comparator)
#print "\n*** test should print 2 errors about returning an int ***" #print "\n*** test should print 2 errors about returning an int ***"
self.addDataToDB (['a', 'b', 'c']) # this should raise, but... self.addDataToDB(['a', 'b', 'c']) # this should raise, but...
self.finishTest () self.finishTest()
def test_compare_function_bad_return(self): def test_compare_function_bad_return(self) :
self.verifyStderr( self.verifyStderr(
self._test_compare_function_bad_return, self._test_compare_function_bad_return,
re.compile('(^TypeError:.* return an int.*){2}', re.M|re.S) re.compile('(^TypeError:.* return an int.*){2}', re.M|re.S)
) )
def test_cannot_assign_twice (self): def test_cannot_assign_twice(self) :
def my_compare (a, b): def my_compare(a, b) :
return 0 return 0
self.startTest() self.startTest()
self.createDB(my_compare) self.createDB(my_compare)
self.assertRaises (RuntimeError, self.db.set_bt_compare, my_compare) self.assertRaises(RuntimeError, self.db.set_bt_compare, my_compare)
def test_suite (): class AbstractDuplicateCompareTestCase(unittest.TestCase) :
res = unittest.TestSuite () env = None
db = None
res.addTest (unittest.makeSuite (ComparatorTests)) if (sys.version_info < (2, 7)) or ((sys.version_info >= (3,0)) and
res.addTest (unittest.makeSuite (BtreeExceptionsTestCase)) (sys.version_info < (3, 2))) :
res.addTest (unittest.makeSuite (BtreeKeyCompareTestCase)) def assertLess(self, a, b, msg=None) :
return self.assertTrue(a<b, msg=msg)
def setUp(self) :
self.filename = self.__class__.__name__ + '.db'
self.homeDir = get_new_environment_path()
env = db.DBEnv()
env.open(self.homeDir,
db.DB_CREATE | db.DB_INIT_MPOOL
| db.DB_INIT_LOCK | db.DB_THREAD)
self.env = env
def tearDown(self) :
self.closeDB()
if self.env is not None:
self.env.close()
self.env = None
test_support.rmtree(self.homeDir)
def addDataToDB(self, data) :
for item in data:
self.db.put("key", item)
def createDB(self, dup_comparator) :
self.db = db.DB(self.env)
self.setupDB(dup_comparator)
self.db.open(self.filename, "test", db.DB_BTREE, db.DB_CREATE)
def setupDB(self, dup_comparator) :
self.db.set_flags(db.DB_DUPSORT)
self.db.set_dup_compare(dup_comparator)
def closeDB(self) :
if self.db is not None:
self.db.close()
self.db = None
def startTest(self) :
pass
def finishTest(self, expected = None) :
if expected is not None:
self.check_results(expected)
self.closeDB()
def check_results(self, expected) :
curs = self.db.cursor()
try:
index = 0
rec = curs.first()
while rec:
ignore, data = rec
self.assertLess(index, len(expected),
"to many values returned from cursor")
self.assertEqual(expected[index], data,
"expected value `%s' at %d but got `%s'"
% (expected[index], index, data))
index = index + 1
rec = curs.next()
self.assertEqual(index, len(expected),
"not enough values returned from cursor")
finally:
curs.close()
class DuplicateCompareTestCase(AbstractDuplicateCompareTestCase) :
def runCompareTest(self, comparator, data) :
self.startTest()
self.createDB(comparator)
self.addDataToDB(data)
self.finishTest(data)
def test_lexical_ordering(self) :
self.runCompareTest(lexical_cmp, _expected_lexical_test_data)
def test_reverse_lexical_ordering(self) :
expected_rev_data = _expected_lexical_test_data[:]
expected_rev_data.reverse()
self.runCompareTest(make_reverse_comparator(lexical_cmp),
expected_rev_data)
class DuplicateExceptionsTestCase(AbstractDuplicateCompareTestCase) :
def test_raises_non_callable(self) :
self.startTest()
self.assertRaises(TypeError, self.createDB, 'abc')
self.assertRaises(TypeError, self.createDB, None)
self.finishTest()
def test_set_dup_compare_with_function(self) :
self.startTest()
self.createDB(lexical_cmp)
self.finishTest()
def check_results(self, results) :
pass
def test_compare_function_incorrect(self) :
self.startTest()
def bad_comparator(l, r) :
return 1
# verify that set_dup_compare checks that comparator('', '') == 0
self.assertRaises(TypeError, self.createDB, bad_comparator)
self.finishTest()
def test_compare_function_useless(self) :
self.startTest()
def socialist_comparator(l, r) :
return 0
self.createDB(socialist_comparator)
# DUPSORT does not allow "duplicate duplicates"
self.assertRaises(db.DBKeyExistError, self.addDataToDB, ['b', 'a', 'd'])
self.finishTest()
def verifyStderr(self, method, successRe) :
"""
Call method() while capturing sys.stderr output internally and
call self.fail() if successRe.search() does not match the stderr
output. This is used to test for uncatchable exceptions.
"""
stdErr = sys.stderr
sys.stderr = StringIO()
try:
method()
finally:
temp = sys.stderr
sys.stderr = stdErr
errorOut = temp.getvalue()
if not successRe.search(errorOut) :
self.fail("unexpected stderr output:\n"+errorOut)
if sys.version_info < (3, 0) : # XXX: How to do this in Py3k ???
sys.exc_traceback = sys.last_traceback = None
def _test_compare_function_exception(self) :
self.startTest()
def bad_comparator(l, r) :
if l == r:
# pass the set_dup_compare test
return 0
raise RuntimeError, "i'm a naughty comparison function"
self.createDB(bad_comparator)
#print "\n*** test should print 2 uncatchable tracebacks ***"
self.addDataToDB(['a', 'b', 'c']) # this should raise, but...
self.finishTest()
def test_compare_function_exception(self) :
self.verifyStderr(
self._test_compare_function_exception,
re.compile('(^RuntimeError:.* naughty.*){2}', re.M|re.S)
)
def _test_compare_function_bad_return(self) :
self.startTest()
def bad_comparator(l, r) :
if l == r:
# pass the set_dup_compare test
return 0
return l
self.createDB(bad_comparator)
#print "\n*** test should print 2 errors about returning an int ***"
self.addDataToDB(['a', 'b', 'c']) # this should raise, but...
self.finishTest()
def test_compare_function_bad_return(self) :
self.verifyStderr(
self._test_compare_function_bad_return,
re.compile('(^TypeError:.* return an int.*){2}', re.M|re.S)
)
def test_cannot_assign_twice(self) :
def my_compare(a, b) :
return 0
self.startTest()
self.createDB(my_compare)
self.assertRaises(RuntimeError, self.db.set_dup_compare, my_compare)
def test_suite() :
res = unittest.TestSuite()
res.addTest(unittest.makeSuite(ComparatorTests))
res.addTest(unittest.makeSuite(BtreeExceptionsTestCase))
res.addTest(unittest.makeSuite(BtreeKeyCompareTestCase))
res.addTest(unittest.makeSuite(DuplicateExceptionsTestCase))
res.addTest(unittest.makeSuite(DuplicateCompareTestCase))
return res return res
if __name__ == '__main__': if __name__ == '__main__':
unittest.main (defaultTest = 'suite') unittest.main(defaultTest = 'suite')

View File

@ -7,11 +7,6 @@ from test_all import db, test_support, get_new_environment_path, \
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class DB(unittest.TestCase): class DB(unittest.TestCase):
import sys
if sys.version_info < (2, 4) :
def assertTrue(self, expr, msg=None):
self.failUnless(expr,msg=msg)
def setUp(self): def setUp(self):
self.path = get_new_database_path() self.path = get_new_database_path()
self.db = db.DB() self.db = db.DB()
@ -19,10 +14,28 @@ class DB(unittest.TestCase):
def tearDown(self): def tearDown(self):
self.db.close() self.db.close()
del self.db del self.db
test_support.rmtree(self.path) test_support.unlink(self.path)
class DB_general(DB) : class DB_general(DB) :
if db.version() >= (4, 2) : def test_get_open_flags(self) :
self.db.open(self.path, dbtype=db.DB_HASH, flags = db.DB_CREATE)
self.assertEqual(db.DB_CREATE, self.db.get_open_flags())
def test_get_open_flags2(self) :
self.db.open(self.path, dbtype=db.DB_HASH, flags = db.DB_CREATE |
db.DB_THREAD)
self.assertEqual(db.DB_CREATE | db.DB_THREAD, self.db.get_open_flags())
def test_get_dbname_filename(self) :
self.db.open(self.path, dbtype=db.DB_HASH, flags = db.DB_CREATE)
self.assertEqual((self.path, None), self.db.get_dbname())
def test_get_dbname_filename_database(self) :
name = "jcea-random-name"
self.db.open(self.path, dbname=name, dbtype=db.DB_HASH,
flags = db.DB_CREATE)
self.assertEqual((self.path, name), self.db.get_dbname())
def test_bt_minkey(self) : def test_bt_minkey(self) :
for i in [17, 108, 1030] : for i in [17, 108, 1030] :
self.db.set_bt_minkey(i) self.db.set_bt_minkey(i)
@ -44,8 +57,12 @@ class DB_general(DB) :
self.db.set_priority(flag) self.db.set_priority(flag)
self.assertEqual(flag, self.db.get_priority()) self.assertEqual(flag, self.db.get_priority())
def test_get_transactional(self) :
self.assertFalse(self.db.get_transactional())
self.db.open(self.path, dbtype=db.DB_HASH, flags = db.DB_CREATE)
self.assertFalse(self.db.get_transactional())
class DB_hash(DB) : class DB_hash(DB) :
if db.version() >= (4, 2) :
def test_h_ffactor(self) : def test_h_ffactor(self) :
for ffactor in [4, 16, 256] : for ffactor in [4, 16, 256] :
self.db.set_h_ffactor(ffactor) self.db.set_h_ffactor(ffactor)
@ -84,7 +101,6 @@ class DB_txn(DB) :
del self.env del self.env
test_support.rmtree(self.homeDir) test_support.rmtree(self.homeDir)
if db.version() >= (4, 2) :
def test_flags(self) : def test_flags(self) :
self.db.set_flags(db.DB_CHKSUM) self.db.set_flags(db.DB_CHKSUM)
self.assertEqual(db.DB_CHKSUM, self.db.get_flags()) self.assertEqual(db.DB_CHKSUM, self.db.get_flags())
@ -92,8 +108,14 @@ class DB_txn(DB) :
self.assertEqual(db.DB_TXN_NOT_DURABLE | db.DB_CHKSUM, self.assertEqual(db.DB_TXN_NOT_DURABLE | db.DB_CHKSUM,
self.db.get_flags()) self.db.get_flags())
def test_get_transactional(self) :
self.assertFalse(self.db.get_transactional())
# DB_AUTO_COMMIT = Implicit transaction
self.db.open("XXX", dbtype=db.DB_HASH,
flags = db.DB_CREATE | db.DB_AUTO_COMMIT)
self.assertTrue(self.db.get_transactional())
class DB_recno(DB) : class DB_recno(DB) :
if db.version() >= (4, 2) :
def test_re_pad(self) : def test_re_pad(self) :
for i in [' ', '*'] : # Check chars for i in [' ', '*'] : # Check chars
self.db.set_re_pad(i) self.db.set_re_pad(i)
@ -116,7 +138,6 @@ class DB_recno(DB) :
self.assertEqual(i, self.db.get_re_source()) self.assertEqual(i, self.db.get_re_source())
class DB_queue(DB) : class DB_queue(DB) :
if db.version() >= (4, 2) :
def test_re_len(self) : def test_re_len(self) :
for i in [33, 65, 300, 2000] : for i in [33, 65, 300, 2000] :
self.db.set_re_len(i) self.db.set_re_len(i)

View File

@ -7,14 +7,6 @@ from test_all import db, test_support, get_new_environment_path, \
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class DBEnv(unittest.TestCase): class DBEnv(unittest.TestCase):
import sys
if sys.version_info < (2, 4) :
def assertTrue(self, expr, msg=None):
self.failUnless(expr,msg=msg)
def assertFalse(self, expr, msg=None):
self.failIf(expr,msg=msg)
def setUp(self): def setUp(self):
self.homeDir = get_new_environment_path() self.homeDir = get_new_environment_path()
self.env = db.DBEnv() self.env = db.DBEnv()
@ -25,12 +17,31 @@ class DBEnv(unittest.TestCase):
test_support.rmtree(self.homeDir) test_support.rmtree(self.homeDir)
class DBEnv_general(DBEnv) : class DBEnv_general(DBEnv) :
def test_get_open_flags(self) :
flags = db.DB_CREATE | db.DB_INIT_MPOOL
self.env.open(self.homeDir, flags)
self.assertEqual(flags, self.env.get_open_flags())
def test_get_open_flags2(self) :
flags = db.DB_CREATE | db.DB_INIT_MPOOL | \
db.DB_INIT_LOCK | db.DB_THREAD
self.env.open(self.homeDir, flags)
self.assertEqual(flags, self.env.get_open_flags())
if db.version() >= (4, 7) : if db.version() >= (4, 7) :
def test_lk_partitions(self) : def test_lk_partitions(self) :
for i in [10, 20, 40] : for i in [10, 20, 40] :
self.env.set_lk_partitions(i) self.env.set_lk_partitions(i)
self.assertEqual(i, self.env.get_lk_partitions()) self.assertEqual(i, self.env.get_lk_partitions())
def test_getset_intermediate_dir_mode(self) :
self.assertEqual(None, self.env.get_intermediate_dir_mode())
for mode in ["rwx------", "rw-rw-rw-", "rw-r--r--"] :
self.env.set_intermediate_dir_mode(mode)
self.assertEqual(mode, self.env.get_intermediate_dir_mode())
self.assertRaises(db.DBInvalidArgError,
self.env.set_intermediate_dir_mode, "abcde")
if db.version() >= (4, 6) : if db.version() >= (4, 6) :
def test_thread(self) : def test_thread(self) :
for i in [16, 100, 1000] : for i in [16, 100, 1000] :
@ -58,21 +69,19 @@ class DBEnv_general(DBEnv) :
self.env.set_lg_filemode(i) self.env.set_lg_filemode(i)
self.assertEqual(i, self.env.get_lg_filemode()) self.assertEqual(i, self.env.get_lg_filemode())
if db.version() >= (4, 3) : def test_mp_max_openfd(self) :
def test_mp_max_openfd(self) : for i in [17, 31, 42] :
for i in [17, 31, 42] : self.env.set_mp_max_openfd(i)
self.env.set_mp_max_openfd(i) self.assertEqual(i, self.env.get_mp_max_openfd())
self.assertEqual(i, self.env.get_mp_max_openfd())
def test_mp_max_write(self) : def test_mp_max_write(self) :
for i in [100, 200, 300] : for i in [100, 200, 300] :
for j in [1, 2, 3] : for j in [1, 2, 3] :
j *= 1000000 j *= 1000000
self.env.set_mp_max_write(i, j) self.env.set_mp_max_write(i, j)
v=self.env.get_mp_max_write() v=self.env.get_mp_max_write()
self.assertEqual((i, j), v) self.assertEqual((i, j), v)
if db.version() >= (4, 2) :
def test_invalid_txn(self) : def test_invalid_txn(self) :
# This environment doesn't support transactions # This environment doesn't support transactions
self.assertRaises(db.DBInvalidArgError, self.env.txn_begin) self.assertRaises(db.DBInvalidArgError, self.env.txn_begin)
@ -115,7 +124,7 @@ class DBEnv_general(DBEnv) :
self.assertEqual(i, self.env.get_lk_max_lockers()) self.assertEqual(i, self.env.get_lk_max_lockers())
def test_lg_regionmax(self) : def test_lg_regionmax(self) :
for i in [128, 256, 1024] : for i in [128, 256, 1000] :
i = i*1024*1024 i = i*1024*1024
self.env.set_lg_regionmax(i) self.env.set_lg_regionmax(i)
j = self.env.get_lg_regionmax() j = self.env.get_lg_regionmax()
@ -127,8 +136,7 @@ class DBEnv_general(DBEnv) :
db.DB_LOCK_MINLOCKS, db.DB_LOCK_MINWRITE, db.DB_LOCK_MINLOCKS, db.DB_LOCK_MINWRITE,
db.DB_LOCK_OLDEST, db.DB_LOCK_RANDOM, db.DB_LOCK_YOUNGEST] db.DB_LOCK_OLDEST, db.DB_LOCK_RANDOM, db.DB_LOCK_YOUNGEST]
if db.version() >= (4, 3) : flags.append(db.DB_LOCK_MAXWRITE)
flags.append(db.DB_LOCK_MAXWRITE)
for i in flags : for i in flags :
self.env.set_lk_detect(i) self.env.set_lk_detect(i)
@ -172,8 +180,12 @@ class DBEnv_general(DBEnv) :
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL) self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
cachesize = (0, 2*1024*1024, 1) cachesize = (0, 2*1024*1024, 1)
self.assertRaises(db.DBInvalidArgError, self.assertRaises(db.DBInvalidArgError,
self.env.set_cachesize, *cachesize) self.env.set_cachesize, *cachesize)
self.assertEqual(cachesize2, self.env.get_cachesize()) cachesize3 = self.env.get_cachesize()
self.assertEqual(cachesize2[0], cachesize3[0])
self.assertEqual(cachesize2[2], cachesize3[2])
# In Berkeley DB 5.1, the cachesize can change when opening the Env
self.assertTrue(cachesize2[1] <= cachesize3[1])
def test_set_cachesize_dbenv_db(self) : def test_set_cachesize_dbenv_db(self) :
# You can not configure the cachesize using # You can not configure the cachesize using
@ -305,7 +317,7 @@ class DBEnv_log_txn(DBEnv) :
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL | self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL |
db.DB_INIT_LOG | db.DB_INIT_TXN) db.DB_INIT_LOG | db.DB_INIT_TXN)
if db.version() >= (4, 5) : if (db.version() >= (4, 5)) and (db.version() < (5, 2)) :
def test_tx_max(self) : def test_tx_max(self) :
txns=[] txns=[]
def tx() : def tx() :

View File

@ -12,9 +12,6 @@ from test_all import db, dbshelve, test_support, verbose, \
if sys.version_info < (2, 4) :
from sets import Set as set
#---------------------------------------------------------------------- #----------------------------------------------------------------------
@ -33,10 +30,6 @@ class DataClass:
class DBShelveTestCase(unittest.TestCase): class DBShelveTestCase(unittest.TestCase):
if sys.version_info < (2, 4):
def assertTrue(self, expr, msg=None):
return self.failUnless(expr,msg=msg)
if (sys.version_info < (2, 7)) or ((sys.version_info >= (3, 0)) and if (sys.version_info < (2, 7)) or ((sys.version_info >= (3, 0)) and
(sys.version_info < (3, 2))) : (sys.version_info < (3, 2))) :
def assertIn(self, a, b, msg=None) : def assertIn(self, a, b, msg=None) :

View File

@ -7,13 +7,6 @@ import unittest
from test_all import db, test_support, get_new_environment_path, \ from test_all import db, test_support, get_new_environment_path, \
get_new_database_path get_new_database_path
try :
a=set()
except : # Python 2.3
from sets import Set as set
else :
del a
from test_all import verbose from test_all import verbose
#---------------------------------------------------------------------- #----------------------------------------------------------------------
@ -37,15 +30,11 @@ class DBTxn_distributed(unittest.TestCase):
self.db = db.DB(self.dbenv) self.db = db.DB(self.dbenv)
self.db.set_re_len(db.DB_GID_SIZE) self.db.set_re_len(db.DB_GID_SIZE)
if must_open_db : if must_open_db :
if db.version() >= (4,2) :
txn=self.dbenv.txn_begin() txn=self.dbenv.txn_begin()
self.db.open(self.filename, self.db.open(self.filename,
db.DB_QUEUE, db.DB_CREATE | db.DB_THREAD, 0666, db.DB_QUEUE, db.DB_CREATE | db.DB_THREAD, 0666,
txn=txn) txn=txn)
txn.commit() txn.commit()
else :
self.db.open(self.filename,
db.DB_QUEUE, db.DB_CREATE | db.DB_THREAD, 0666)
def setUp(self) : def setUp(self) :
self.homeDir = get_new_environment_path() self.homeDir = get_new_environment_path()

View File

@ -174,7 +174,7 @@ class DBEnvClosedEarlyCrash(unittest.TestCase):
txn.commit() txn.commit()
warnings.resetwarnings() warnings.resetwarnings()
else : else :
# When we drop support for python 2.3 and 2.4 # When we drop support for python 2.4
# we could use: (in 2.5 we need a __future__ statement) # we could use: (in 2.5 we need a __future__ statement)
# #
# with warnings.catch_warnings(): # with warnings.catch_warnings():
@ -182,7 +182,7 @@ class DBEnvClosedEarlyCrash(unittest.TestCase):
# txn.commit() # txn.commit()
# #
# We can not use "with" as is, because it would be invalid syntax # We can not use "with" as is, because it would be invalid syntax
# in python 2.3, 2.4 and (with no __future__) 2.5. # in python 2.4 and (with no __future__) 2.5.
# Here we simulate "with" following PEP 343 : # Here we simulate "with" following PEP 343 :
w = warnings.catch_warnings() w = warnings.catch_warnings()
w.__enter__() w.__enter__()
@ -194,15 +194,14 @@ class DBEnvClosedEarlyCrash(unittest.TestCase):
self.assertRaises(db.DBCursorClosedError, c2.first) self.assertRaises(db.DBCursorClosedError, c2.first)
if db.version() > (4,3,0) : def test07_close_db_before_sequence(self):
def test07_close_db_before_sequence(self): import os.path
import os.path path=os.path.join(self.homeDir,self.filename)
path=os.path.join(self.homeDir,self.filename) d = db.DB()
d = db.DB() d.open(path, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
d.open(path, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666) dbs=db.DBSequence(d)
dbs=db.DBSequence(d) d.close() # This "close" should close the child DBSequence also
d.close() # This "close" should close the child DBSequence also dbs.close() # If not closed, core dump (in Berkeley DB 4.6.*)
dbs.close() # If not closed, core dump (in Berkeley DB 4.6.*)
#---------------------------------------------------------------------- #----------------------------------------------------------------------

View File

@ -19,12 +19,6 @@ if have_threads :
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class LockingTestCase(unittest.TestCase): class LockingTestCase(unittest.TestCase):
import sys
if sys.version_info < (2, 4) :
def assertTrue(self, expr, msg=None):
self.failUnless(expr,msg=msg)
def setUp(self): def setUp(self):
self.homeDir = get_new_environment_path() self.homeDir = get_new_environment_path()
self.env = db.DBEnv() self.env = db.DBEnv()
@ -89,7 +83,6 @@ class LockingTestCase(unittest.TestCase):
for t in threads: for t in threads:
t.join() t.join()
if db.version() >= (4, 2) :
def test03_lock_timeout(self): def test03_lock_timeout(self):
self.env.set_timeout(0, db.DB_SET_LOCK_TIMEOUT) self.env.set_timeout(0, db.DB_SET_LOCK_TIMEOUT)
self.assertEqual(self.env.get_timeout(db.DB_SET_LOCK_TIMEOUT), 0) self.assertEqual(self.env.get_timeout(db.DB_SET_LOCK_TIMEOUT), 0)

View File

@ -9,13 +9,6 @@ from test_all import db, dbshelve, hashopen, test_support, get_new_environment_p
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class MiscTestCase(unittest.TestCase): class MiscTestCase(unittest.TestCase):
if sys.version_info < (2, 4) :
def assertTrue(self, expr, msg=None):
self.failUnless(expr, msg=msg)
def assertFalse(self, expr, msg=None):
self.failIf(expr, msg=msg)
def setUp(self): def setUp(self):
self.filename = get_new_database_path() self.filename = get_new_database_path()
self.homeDir = get_new_environment_path() self.homeDir = get_new_environment_path()
@ -97,10 +90,6 @@ class MiscTestCase(unittest.TestCase):
test_support.unlink(self.filename) test_support.unlink(self.filename)
def test07_DB_set_flags_persists(self): def test07_DB_set_flags_persists(self):
if db.version() < (4,2):
# The get_flags API required for this to work is only available
# in Berkeley DB >= 4.2
return
try: try:
db1 = db.DB() db1 = db.DB()
db1.set_flags(db.DB_DUPSORT) db1.set_flags(db.DB_DUPSORT)

View File

@ -99,11 +99,6 @@ class SimpleQueueTestCase(unittest.TestCase):
print '\n', '-=' * 30 print '\n', '-=' * 30
print "Running %s.test02_basicPost32..." % self.__class__.__name__ print "Running %s.test02_basicPost32..." % self.__class__.__name__
if db.version() < (3, 2, 0):
if verbose:
print "Test not run, DB not new enough..."
return
d = db.DB() d = db.DB()
d.set_re_len(40) # Queues must be fixed length d.set_re_len(40) # Queues must be fixed length
d.open(self.filename, db.DB_QUEUE, db.DB_CREATE) d.open(self.filename, db.DB_QUEUE, db.DB_CREATE)

View File

@ -14,12 +14,6 @@ letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class SimpleRecnoTestCase(unittest.TestCase): class SimpleRecnoTestCase(unittest.TestCase):
if sys.version_info < (2, 4) :
def assertFalse(self, expr, msg=None) :
return self.failIf(expr,msg=msg)
def assertTrue(self, expr, msg=None) :
return self.assertTrue(expr, msg=msg)
if (sys.version_info < (2, 7)) or ((sys.version_info >= (3, 0)) and if (sys.version_info < (2, 7)) or ((sys.version_info >= (3, 0)) and
(sys.version_info < (3, 2))) : (sys.version_info < (3, 2))) :
def assertIsInstance(self, obj, datatype, msg=None) : def assertIsInstance(self, obj, datatype, msg=None) :
@ -236,7 +230,9 @@ class SimpleRecnoTestCase(unittest.TestCase):
d.close() d.close()
# get the text from the backing source # get the text from the backing source
text = open(source, 'r').read() f = open(source, 'r')
text = f.read()
f.close()
text = text.strip() text = text.strip()
if verbose: if verbose:
print text print text
@ -256,7 +252,9 @@ class SimpleRecnoTestCase(unittest.TestCase):
d.sync() d.sync()
d.close() d.close()
text = open(source, 'r').read() f = open(source, 'r')
text = f.read()
f.close()
text = text.strip() text = text.strip()
if verbose: if verbose:
print text print text
@ -298,6 +296,18 @@ class SimpleRecnoTestCase(unittest.TestCase):
c.close() c.close()
d.close() d.close()
def test04_get_size_empty(self) :
d = db.DB()
d.open(self.filename, dbtype=db.DB_RECNO, flags=db.DB_CREATE)
row_id = d.append(' ')
self.assertEqual(1, d.get_size(key=row_id))
row_id = d.append('')
self.assertEqual(0, d.get_size(key=row_id))
#---------------------------------------------------------------------- #----------------------------------------------------------------------

View File

@ -12,11 +12,6 @@ from test_all import db, test_support, have_threads, verbose, \
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class DBReplication(unittest.TestCase) : class DBReplication(unittest.TestCase) :
import sys
if sys.version_info < (2, 4) :
def assertTrue(self, expr, msg=None):
self.failUnless(expr,msg=msg)
def setUp(self) : def setUp(self) :
self.homeDirMaster = get_new_environment_path() self.homeDirMaster = get_new_environment_path()
self.homeDirClient = get_new_environment_path() self.homeDirClient = get_new_environment_path()
@ -76,13 +71,57 @@ class DBReplication(unittest.TestCase) :
class DBReplicationManager(DBReplication) : class DBReplicationManager(DBReplication) :
def test01_basic_replication(self) : def test01_basic_replication(self) :
master_port = test_support.find_unused_port() master_port = test_support.find_unused_port()
self.dbenvMaster.repmgr_set_local_site("127.0.0.1", master_port)
client_port = test_support.find_unused_port() client_port = test_support.find_unused_port()
self.dbenvClient.repmgr_set_local_site("127.0.0.1", client_port) if db.version() >= (5, 2) :
self.dbenvMaster.repmgr_add_remote_site("127.0.0.1", client_port) self.site = self.dbenvMaster.repmgr_site("127.0.0.1", master_port)
self.dbenvClient.repmgr_add_remote_site("127.0.0.1", master_port) self.site.set_config(db.DB_GROUP_CREATOR, True)
self.dbenvMaster.rep_set_nsites(2) self.site.set_config(db.DB_LOCAL_SITE, True)
self.dbenvClient.rep_set_nsites(2) self.site2 = self.dbenvMaster.repmgr_site("127.0.0.1", client_port)
self.site3 = self.dbenvClient.repmgr_site("127.0.0.1", master_port)
self.site3.set_config(db.DB_BOOTSTRAP_HELPER, True)
self.site4 = self.dbenvClient.repmgr_site("127.0.0.1", client_port)
self.site4.set_config(db.DB_LOCAL_SITE, True)
d = {
db.DB_BOOTSTRAP_HELPER: [False, False, True, False],
db.DB_GROUP_CREATOR: [True, False, False, False],
db.DB_LEGACY: [False, False, False, False],
db.DB_LOCAL_SITE: [True, False, False, True],
db.DB_REPMGR_PEER: [False, False, False, False ],
}
for i, j in d.items() :
for k, v in \
zip([self.site, self.site2, self.site3, self.site4], j) :
if v :
self.assertTrue(k.get_config(i))
else :
self.assertFalse(k.get_config(i))
self.assertNotEqual(self.site.get_eid(), self.site2.get_eid())
self.assertNotEqual(self.site3.get_eid(), self.site4.get_eid())
for i, j in zip([self.site, self.site2, self.site3, self.site4], \
[master_port, client_port, master_port, client_port]) :
addr = i.get_address()
self.assertEqual(addr, ("127.0.0.1", j))
for i in [self.site, self.site2] :
self.assertEqual(i.get_address(),
self.dbenvMaster.repmgr_site_by_eid(i.get_eid()).get_address())
for i in [self.site3, self.site4] :
self.assertEqual(i.get_address(),
self.dbenvClient.repmgr_site_by_eid(i.get_eid()).get_address())
else :
self.dbenvMaster.repmgr_set_local_site("127.0.0.1", master_port)
self.dbenvClient.repmgr_set_local_site("127.0.0.1", client_port)
self.dbenvMaster.repmgr_add_remote_site("127.0.0.1", client_port)
self.dbenvClient.repmgr_add_remote_site("127.0.0.1", master_port)
self.dbenvMaster.rep_set_nsites(2)
self.dbenvClient.rep_set_nsites(2)
self.dbenvMaster.rep_set_priority(10) self.dbenvMaster.rep_set_priority(10)
self.dbenvClient.rep_set_priority(0) self.dbenvClient.rep_set_priority(0)
@ -144,17 +183,19 @@ class DBReplicationManager(DBReplication) :
d = self.dbenvMaster.repmgr_site_list() d = self.dbenvMaster.repmgr_site_list()
self.assertEqual(len(d), 1) self.assertEqual(len(d), 1)
self.assertEqual(d[0][0], "127.0.0.1") d = d.values()[0] # There is only one
self.assertEqual(d[0][1], client_port) self.assertEqual(d[0], "127.0.0.1")
self.assertTrue((d[0][2]==db.DB_REPMGR_CONNECTED) or \ self.assertEqual(d[1], client_port)
(d[0][2]==db.DB_REPMGR_DISCONNECTED)) self.assertTrue((d[2]==db.DB_REPMGR_CONNECTED) or \
(d[2]==db.DB_REPMGR_DISCONNECTED))
d = self.dbenvClient.repmgr_site_list() d = self.dbenvClient.repmgr_site_list()
self.assertEqual(len(d), 1) self.assertEqual(len(d), 1)
self.assertEqual(d[0][0], "127.0.0.1") d = d.values()[0] # There is only one
self.assertEqual(d[0][1], master_port) self.assertEqual(d[0], "127.0.0.1")
self.assertTrue((d[0][2]==db.DB_REPMGR_CONNECTED) or \ self.assertEqual(d[1], master_port)
(d[0][2]==db.DB_REPMGR_DISCONNECTED)) self.assertTrue((d[2]==db.DB_REPMGR_CONNECTED) or \
(d[2]==db.DB_REPMGR_DISCONNECTED))
if db.version() >= (4,6) : if db.version() >= (4,6) :
d = self.dbenvMaster.repmgr_stat(flags=db.DB_STAT_CLEAR); d = self.dbenvMaster.repmgr_stat(flags=db.DB_STAT_CLEAR);
@ -461,6 +502,13 @@ class DBBaseReplication(DBReplication) :
self.assertTrue(self.confirmed_master) self.assertTrue(self.confirmed_master)
# Race condition showed up after upgrading to Solaris 10 Update 10
# https://forums.oracle.com/forums/thread.jspa?messageID=9902860
# jcea@jcea.es: See private email from Paula Bingham (Oracle),
# in 20110929.
while not (self.dbenvClient.rep_stat()["startup_complete"]) :
pass
if db.version() >= (4,7) : if db.version() >= (4,7) :
def test04_test_clockskew(self) : def test04_test_clockskew(self) :
fast, slow = 1234, 1230 fast, slow = 1234, 1230

View File

@ -5,11 +5,6 @@ from test_all import db, test_support, get_new_environment_path, get_new_databas
class DBSequenceTest(unittest.TestCase): class DBSequenceTest(unittest.TestCase):
import sys
if sys.version_info < (2, 4) :
def assertTrue(self, expr, msg=None):
self.failUnless(expr,msg=msg)
def setUp(self): def setUp(self):
self.int_32_max = 0x100000000 self.int_32_max = 0x100000000
self.homeDir = get_new_environment_path() self.homeDir = get_new_environment_path()
@ -133,8 +128,7 @@ class DBSequenceTest(unittest.TestCase):
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
if db.version() >= (4,3): suite.addTest(unittest.makeSuite(DBSequenceTest))
suite.addTest(unittest.makeSuite(DBSequenceTest))
return suite return suite

View File

@ -35,10 +35,6 @@ class BaseThreadedTestCase(unittest.TestCase):
dbsetflags = 0 dbsetflags = 0
envflags = 0 envflags = 0
if sys.version_info < (2, 4) :
def assertTrue(self, expr, msg=None):
self.failUnless(expr,msg=msg)
def setUp(self): def setUp(self):
if verbose: if verbose:
dbutils._deadlock_VerboseFile = sys.stdout dbutils._deadlock_VerboseFile = sys.stdout

View File

@ -793,6 +793,9 @@ Library
Extension Modules Extension Modules
----------------- -----------------
- Issue #17477: Update the bsddb module to pybsddb 5.3.0, supporting
db-5.x, and dropping support for db-4.1 and db-4.2.
- Issue #17192: Update the ctypes module's libffi to v3.0.13. This - Issue #17192: Update the ctypes module's libffi to v3.0.13. This
specifically addresses a stack misalignment issue on x86 and issues on specifically addresses a stack misalignment issue on x86 and issues on
some more recent platforms. some more recent platforms.

File diff suppressed because it is too large Load Diff

View File

@ -61,7 +61,7 @@
* *
* http://www.python.org/peps/pep-0291.html * http://www.python.org/peps/pep-0291.html
* *
* This module contains 6 types: * This module contains 7 types:
* *
* DB (Database) * DB (Database)
* DBCursor (Database Cursor) * DBCursor (Database Cursor)
@ -69,6 +69,7 @@
* DBTxn (An explicit database transaction) * DBTxn (An explicit database transaction)
* DBLock (A lock handle) * DBLock (A lock handle)
* DBSequence (Sequence) * DBSequence (Sequence)
* DBSite (Site)
* *
* New datatypes: * New datatypes:
* *
@ -109,7 +110,7 @@
#error "eek! DBVER can't handle minor versions > 9" #error "eek! DBVER can't handle minor versions > 9"
#endif #endif
#define PY_BSDDB_VERSION "4.8.4.2" #define PY_BSDDB_VERSION "5.3.0"
/* Python object definitions */ /* Python object definitions */
@ -129,6 +130,9 @@ struct DBCursorObject; /* Forward declaration */
struct DBLogCursorObject; /* Forward declaration */ struct DBLogCursorObject; /* Forward declaration */
struct DBTxnObject; /* Forward declaration */ struct DBTxnObject; /* Forward declaration */
struct DBSequenceObject; /* Forward declaration */ struct DBSequenceObject; /* Forward declaration */
#if (DBVER >= 52)
struct DBSiteObject; /* Forward declaration */
#endif
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
@ -140,6 +144,9 @@ typedef struct {
struct DBObject *children_dbs; struct DBObject *children_dbs;
struct DBTxnObject *children_txns; struct DBTxnObject *children_txns;
struct DBLogCursorObject *children_logcursors; struct DBLogCursorObject *children_logcursors;
#if (DBVER >= 52)
struct DBSiteObject *children_sites;
#endif
PyObject *private_obj; PyObject *private_obj;
PyObject *rep_transport; PyObject *rep_transport;
PyObject *in_weakreflist; /* List of weak references */ PyObject *in_weakreflist; /* List of weak references */
@ -154,15 +161,14 @@ typedef struct DBObject {
struct behaviourFlags moduleFlags; struct behaviourFlags moduleFlags;
struct DBTxnObject *txn; struct DBTxnObject *txn;
struct DBCursorObject *children_cursors; struct DBCursorObject *children_cursors;
#if (DBVER >=43)
struct DBSequenceObject *children_sequences; struct DBSequenceObject *children_sequences;
#endif
struct DBObject **sibling_prev_p; struct DBObject **sibling_prev_p;
struct DBObject *sibling_next; struct DBObject *sibling_next;
struct DBObject **sibling_prev_p_txn; struct DBObject **sibling_prev_p_txn;
struct DBObject *sibling_next_txn; struct DBObject *sibling_next_txn;
PyObject* associateCallback; PyObject* associateCallback;
PyObject* btCompareCallback; PyObject* btCompareCallback;
PyObject* dupCompareCallback;
int primaryDBType; int primaryDBType;
PyObject *private_obj; PyObject *private_obj;
PyObject *in_weakreflist; /* List of weak references */ PyObject *in_weakreflist; /* List of weak references */
@ -207,6 +213,16 @@ typedef struct DBLogCursorObject {
PyObject *in_weakreflist; /* List of weak references */ PyObject *in_weakreflist; /* List of weak references */
} DBLogCursorObject; } DBLogCursorObject;
#if (DBVER >= 52)
typedef struct DBSiteObject {
PyObject_HEAD
DB_SITE *site;
DBEnvObject *env;
struct DBSiteObject **sibling_prev_p;
struct DBSiteObject *sibling_next;
PyObject *in_weakreflist; /* List of weak references */
} DBSiteObject;
#endif
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
@ -216,7 +232,6 @@ typedef struct {
} DBLockObject; } DBLockObject;
#if (DBVER >= 43)
typedef struct DBSequenceObject { typedef struct DBSequenceObject {
PyObject_HEAD PyObject_HEAD
DB_SEQUENCE* sequence; DB_SEQUENCE* sequence;
@ -228,7 +243,6 @@ typedef struct DBSequenceObject {
struct DBSequenceObject *sibling_next_txn; struct DBSequenceObject *sibling_next_txn;
PyObject *in_weakreflist; /* List of weak references */ PyObject *in_weakreflist; /* List of weak references */
} DBSequenceObject; } DBSequenceObject;
#endif
/* API structure for use by C code */ /* API structure for use by C code */
@ -236,7 +250,7 @@ typedef struct DBSequenceObject {
/* To access the structure from an external module, use code like the /* To access the structure from an external module, use code like the
following (error checking missed out for clarity): following (error checking missed out for clarity):
// If you are using Python before 3.2: // If you are using Python before 2.7:
BSDDB_api* bsddb_api; BSDDB_api* bsddb_api;
PyObject* mod; PyObject* mod;
PyObject* cobj; PyObject* cobj;
@ -249,7 +263,7 @@ typedef struct DBSequenceObject {
Py_DECREF(mod); Py_DECREF(mod);
// If you are using Python 3.2 or up: // If you are using Python 2.7 or up: (except Python 3.0, unsupported)
BSDDB_api* bsddb_api; BSDDB_api* bsddb_api;
// Use "bsddb3._pybsddb.api" if you're using // Use "bsddb3._pybsddb.api" if you're using
@ -257,10 +271,14 @@ typedef struct DBSequenceObject {
bsddb_api = (void **)PyCapsule_Import("bsddb._bsddb.api", 1); bsddb_api = (void **)PyCapsule_Import("bsddb._bsddb.api", 1);
Check "api_version" number before trying to use the API.
The structure's members must not be changed. The structure's members must not be changed.
*/ */
#define PYBSDDB_API_VERSION 1
typedef struct { typedef struct {
unsigned int api_version;
/* Type objects */ /* Type objects */
PyTypeObject* db_type; PyTypeObject* db_type;
PyTypeObject* dbcursor_type; PyTypeObject* dbcursor_type;
@ -268,9 +286,7 @@ typedef struct {
PyTypeObject* dbenv_type; PyTypeObject* dbenv_type;
PyTypeObject* dbtxn_type; PyTypeObject* dbtxn_type;
PyTypeObject* dblock_type; PyTypeObject* dblock_type;
#if (DBVER >= 43)
PyTypeObject* dbsequence_type; PyTypeObject* dbsequence_type;
#endif
/* Functions */ /* Functions */
int (*makeDBError)(int err); int (*makeDBError)(int err);
@ -289,9 +305,9 @@ typedef struct {
#define DBEnvObject_Check(v) ((v)->ob_type == bsddb_api->dbenv_type) #define DBEnvObject_Check(v) ((v)->ob_type == bsddb_api->dbenv_type)
#define DBTxnObject_Check(v) ((v)->ob_type == bsddb_api->dbtxn_type) #define DBTxnObject_Check(v) ((v)->ob_type == bsddb_api->dbtxn_type)
#define DBLockObject_Check(v) ((v)->ob_type == bsddb_api->dblock_type) #define DBLockObject_Check(v) ((v)->ob_type == bsddb_api->dblock_type)
#if (DBVER >= 43) #define DBSequenceObject_Check(v) \
#define DBSequenceObject_Check(v) ((v)->ob_type == bsddb_api->dbsequence_type) ((bsddb_api->dbsequence_type) && \
#endif ((v)->ob_type == bsddb_api->dbsequence_type))
#endif /* COMPILING_BSDDB_C */ #endif /* COMPILING_BSDDB_C */

View File

@ -878,8 +878,8 @@ class PyBuildExt(build_ext):
# a release. Most open source OSes come with one or more # a release. Most open source OSes come with one or more
# versions of BerkeleyDB already installed. # versions of BerkeleyDB already installed.
max_db_ver = (4, 8) max_db_ver = (5, 3)
min_db_ver = (4, 1) min_db_ver = (4, 3)
db_setup_debug = False # verbose debug prints from this script? db_setup_debug = False # verbose debug prints from this script?
def allow_db_ver(db_ver): def allow_db_ver(db_ver):
@ -900,7 +900,11 @@ class PyBuildExt(build_ext):
return True return True
def gen_db_minor_ver_nums(major): def gen_db_minor_ver_nums(major):
if major == 4: if major == 5:
for x in range(max_db_ver[1]+1):
if allow_db_ver((5, x)):
yield x
elif major == 4:
for x in range(max_db_ver[1]+1): for x in range(max_db_ver[1]+1):
if allow_db_ver((4, x)): if allow_db_ver((4, x)):
yield x yield x