Commit daa00f7b authored by Jesus Cea's avatar Jesus Cea

bsddb code updated to version 4.7.3pre2. This code is the same than

Python 2.6 one, since the intention is to keep an unified 2.x/3.x
codebase.

The Python code is automatically translated using "2to3". Please, do not
update this code in Python 3.0 by hand. Update the 2.6 one and then do
"2to3".
parent 521110c0
This diff is collapsed.
...@@ -37,15 +37,24 @@ ...@@ -37,15 +37,24 @@
# case we ever want to augment the stuff in _db in any way. For now # case we ever want to augment the stuff in _db in any way. For now
# it just simply imports everything from _db. # it just simply imports everything from _db.
if __name__.startswith('bsddb3.'): import sys
# import _pybsddb binary as it should be the more recent version from absolute_import = (sys.version_info[0] >= 3)
# a standalone pybsddb addon package than the version included with
# python as bsddb._bsddb.
from _pybsddb import *
from _pybsddb import __version__
else:
from _bsddb import *
from _bsddb import __version__
if version() < (3, 2, 0): if not absolute_import :
raise ImportError("correct BerkeleyDB symbols not found. Perhaps python was statically linked with an older version?") if __name__.startswith('bsddb3.') :
# import _pybsddb binary as it should be the more recent version from
# a standalone pybsddb addon package than the version included with
# python as bsddb._bsddb.
from _pybsddb import *
from _pybsddb import __version__
else:
from _bsddb import *
from _bsddb import __version__
else :
# Because this syntaxis is not valid before Python 2.5
if __name__.startswith('bsddb3.') :
exec("from ._pybsddb import *")
exec("from ._pybsddb import __version__")
else :
exec("from ._bsddb import *")
exec("from ._bsddb import __version__")
...@@ -21,12 +21,24 @@ ...@@ -21,12 +21,24 @@
# added to _bsddb.c. # added to _bsddb.c.
# #
from . import db import sys
absolute_import = (sys.version_info[0] >= 3)
if absolute_import :
# Because this syntaxis is not valid before Python 2.5
exec("from . import db")
else :
from . import db
try: if sys.version_info[0:2] <= (2, 5) :
from collections import MutableMapping try:
except ImportError: from UserDict import DictMixin
class MutableMapping: pass except ImportError:
# DictMixin is new in Python 2.3
class DictMixin: pass
MutableMapping = DictMixin
else :
import collections
MutableMapping = collections.MutableMapping
class DBEnv: class DBEnv:
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
...@@ -95,9 +107,8 @@ class DBEnv: ...@@ -95,9 +107,8 @@ class DBEnv:
def set_get_returns_none(self, *args, **kwargs): def set_get_returns_none(self, *args, **kwargs):
return self._cobj.set_get_returns_none(*args, **kwargs) return self._cobj.set_get_returns_none(*args, **kwargs)
if db.version() >= (4,0): def log_stat(self, *args, **kwargs):
def log_stat(self, *args, **kwargs): return self._cobj.log_stat(*args, **kwargs)
return self._cobj.log_stat(*args, **kwargs)
if db.version() >= (4,1): if db.version() >= (4,1):
def dbremove(self, *args, **kwargs): def dbremove(self, *args, **kwargs):
...@@ -115,7 +126,7 @@ class DBEnv: ...@@ -115,7 +126,7 @@ class DBEnv:
class DB(MutableMapping): class DB(MutableMapping):
def __init__(self, dbenv, *args, **kwargs): def __init__(self, dbenv, *args, **kwargs):
# give it the proper DBEnv C object that its expecting # give it the proper DBEnv C object that its expecting
self._cobj = db.DB(dbenv._cobj, *args, **kwargs) self._cobj = db.DB(*(dbenv._cobj,) + args, **kwargs)
# TODO are there other dict methods that need to be overridden? # TODO are there other dict methods that need to be overridden?
def __len__(self): def __len__(self):
...@@ -126,8 +137,10 @@ class DB(MutableMapping): ...@@ -126,8 +137,10 @@ class DB(MutableMapping):
self._cobj[key] = value self._cobj[key] = value
def __delitem__(self, arg): def __delitem__(self, arg):
del self._cobj[arg] del self._cobj[arg]
def __iter__(self):
return iter(self.keys()) if sys.version_info[0:2] >= (2, 6) :
def __iter__(self) :
return self._cobj.__iter__()
def append(self, *args, **kwargs): def append(self, *args, **kwargs):
return self._cobj.append(*args, **kwargs) return self._cobj.append(*args, **kwargs)
...@@ -163,8 +176,6 @@ class DB(MutableMapping): ...@@ -163,8 +176,6 @@ class DB(MutableMapping):
return self._cobj.key_range(*args, **kwargs) return self._cobj.key_range(*args, **kwargs)
def has_key(self, *args, **kwargs): def has_key(self, *args, **kwargs):
return self._cobj.has_key(*args, **kwargs) return self._cobj.has_key(*args, **kwargs)
def __contains__(self, key):
return self._cobj.has_key(key)
def items(self, *args, **kwargs): def items(self, *args, **kwargs):
return self._cobj.items(*args, **kwargs) return self._cobj.items(*args, **kwargs)
def keys(self, *args, **kwargs): def keys(self, *args, **kwargs):
......
...@@ -29,6 +29,7 @@ From: ...@@ -29,6 +29,7 @@ From:
""" """
import errno import errno
import string
class DBRecIO: class DBRecIO:
def __init__(self, db, key, txn=None): def __init__(self, db, key, txn=None):
...@@ -38,6 +39,7 @@ class DBRecIO: ...@@ -38,6 +39,7 @@ class DBRecIO:
self.len = None self.len = None
self.pos = 0 self.pos = 0
self.closed = 0 self.closed = 0
self.softspace = 0
def close(self): def close(self):
if not self.closed: if not self.closed:
...@@ -82,9 +84,9 @@ class DBRecIO: ...@@ -82,9 +84,9 @@ class DBRecIO:
if self.closed: if self.closed:
raise ValueError, "I/O operation on closed file" raise ValueError, "I/O operation on closed file"
if self.buflist: if self.buflist:
self.buf = self.buf + ''.join(self.buflist) self.buf = self.buf + string.joinfields(self.buflist, '')
self.buflist = [] self.buflist = []
i = self.buf.find('\n', self.pos) i = string.find(self.buf, '\n', self.pos)
if i < 0: if i < 0:
newpos = self.len newpos = self.len
else: else:
...@@ -133,7 +135,7 @@ class DBRecIO: ...@@ -133,7 +135,7 @@ class DBRecIO:
self.pos = newpos self.pos = newpos
def writelines(self, list): def writelines(self, list):
self.write(''.join(list)) self.write(string.joinfields(list, ''))
def flush(self): def flush(self):
if self.closed: if self.closed:
...@@ -158,14 +160,14 @@ def _test(): ...@@ -158,14 +160,14 @@ def _test():
if f.getvalue() != text: if f.getvalue() != text:
raise RuntimeError, 'write failed' raise RuntimeError, 'write failed'
length = f.tell() length = f.tell()
print('File length =', length) print 'File length =', length
f.seek(len(lines[0])) f.seek(len(lines[0]))
f.write(lines[1]) f.write(lines[1])
f.seek(0) f.seek(0)
print('First line =', repr(f.readline())) print 'First line =', repr(f.readline())
here = f.tell() here = f.tell()
line = f.readline() line = f.readline()
print('Second line =', repr(line)) print 'Second line =', repr(line)
f.seek(-len(line), 1) f.seek(-len(line), 1)
line2 = f.read(len(line)) line2 = f.read(len(line))
if line != line2: if line != line2:
...@@ -177,8 +179,8 @@ def _test(): ...@@ -177,8 +179,8 @@ def _test():
line2 = f.read() line2 = f.read()
if line != line2: if line != line2:
raise RuntimeError, 'bad result after seek back from EOF' raise RuntimeError, 'bad result after seek back from EOF'
print('Read', len(list), 'more lines') print 'Read', len(list), 'more lines'
print('File length =', f.tell()) print 'File length =', f.tell()
if f.tell() != length: if f.tell() != length:
raise RuntimeError, 'bad length' raise RuntimeError, 'bad length'
f.close() f.close()
......
...@@ -32,21 +32,43 @@ storage. ...@@ -32,21 +32,43 @@ storage.
import pickle import pickle
import sys import sys
import sys
absolute_import = (sys.version_info[0] >= 3)
if absolute_import :
# Because this syntaxis is not valid before Python 2.5
exec("from . import db")
else :
from . import db
#At version 2.3 cPickle switched to using protocol instead of bin #At version 2.3 cPickle switched to using protocol instead of bin
if sys.version_info[:3] >= (2, 3, 0): if sys.version_info[:3] >= (2, 3, 0):
HIGHEST_PROTOCOL = pickle.HIGHEST_PROTOCOL HIGHEST_PROTOCOL = pickle.HIGHEST_PROTOCOL
def _dumps(object, protocol): # In python 2.3.*, "cPickle.dumps" accepts no
return pickle.dumps(object, protocol=protocol) # named parameters. "pickle.dumps" accepts them,
from collections import MutableMapping # so this seems a bug.
if sys.version_info[:3] < (2, 4, 0):
def _dumps(object, protocol):
return pickle.dumps(object, protocol)
else :
def _dumps(object, protocol):
return pickle.dumps(object, protocol=protocol)
else: else:
HIGHEST_PROTOCOL = None HIGHEST_PROTOCOL = None
def _dumps(object, protocol): def _dumps(object, protocol):
return pickle.dumps(object, bin=protocol) return pickle.dumps(object, bin=protocol)
class MutableMapping: pass
from . import db
_unspecified = object() if sys.version_info[0:2] <= (2, 5) :
try:
from UserDict import DictMixin
except ImportError:
# DictMixin is new in Python 2.3
class DictMixin: pass
MutableMapping = DictMixin
else :
import collections
MutableMapping = collections.MutableMapping
#------------------------------------------------------------------------ #------------------------------------------------------------------------
...@@ -135,13 +157,15 @@ class DBShelf(MutableMapping): ...@@ -135,13 +157,15 @@ class DBShelf(MutableMapping):
def keys(self, txn=None): def keys(self, txn=None):
if txn is not None: if txn != None:
return self.db.keys(txn) return self.db.keys(txn)
else: else:
return self.db.keys() return list(self.db.keys())
if sys.version_info[0:2] >= (2, 6) :
def __iter__(self) :
return self.db.__iter__()
def __iter__(self):
return iter(self.keys())
def open(self, *args, **kwargs): def open(self, *args, **kwargs):
self.db.open(*args, **kwargs) self.db.open(*args, **kwargs)
...@@ -157,14 +181,14 @@ class DBShelf(MutableMapping): ...@@ -157,14 +181,14 @@ class DBShelf(MutableMapping):
if self._closed: if self._closed:
return '<DBShelf @ 0x%x - closed>' % (id(self)) return '<DBShelf @ 0x%x - closed>' % (id(self))
else: else:
return repr(dict(self.iteritems())) return repr(dict(iter(self.items())))
def items(self, txn=None): def items(self, txn=None):
if txn is not None: if txn != None:
items = self.db.items(txn) items = self.db.items(txn)
else: else:
items = self.db.items() items = list(self.db.items())
newitems = [] newitems = []
for k, v in items: for k, v in items:
...@@ -172,12 +196,12 @@ class DBShelf(MutableMapping): ...@@ -172,12 +196,12 @@ class DBShelf(MutableMapping):
return newitems return newitems
def values(self, txn=None): def values(self, txn=None):
if txn is not None: if txn != None:
values = self.db.values(txn) values = self.db.values(txn)
else: else:
values = self.db.values() values = list(self.db.values())
return map(pickle.loads, values) return list(map(pickle.loads, values))
#----------------------------------- #-----------------------------------
# Other methods # Other methods
...@@ -194,24 +218,28 @@ class DBShelf(MutableMapping): ...@@ -194,24 +218,28 @@ class DBShelf(MutableMapping):
def associate(self, secondaryDB, callback, flags=0): def associate(self, secondaryDB, callback, flags=0):
def _shelf_callback(priKey, priData, realCallback=callback): def _shelf_callback(priKey, priData, realCallback=callback):
data = pickle.loads(priData) # Safe in Python 2.x because expresion short circuit
if sys.version_info[0] < 3 or isinstance(priData, bytes) :
data = pickle.loads(priData)
else :
data = pickle.loads(bytes(priData, "iso8859-1")) # 8 bits
return realCallback(priKey, data) return realCallback(priKey, data)
return self.db.associate(secondaryDB, _shelf_callback, flags) return self.db.associate(secondaryDB, _shelf_callback, flags)
def get(self, key, default=_unspecified, txn=None, flags=0): #def get(self, key, default=None, txn=None, flags=0):
# If no default is given, we must not pass one to the def get(self, *args, **kw):
# extension module, so that an exception can be raised if # We do it with *args and **kw so if the default value wasn't
# set_get_returns_none is turned off. # given nothing is passed to the extension module. That way
if default is _unspecified: # an exception can be raised if set_get_returns_none is turned
data = self.db.get(key, txn=txn, flags=flags) # off.
# if this returns, the default value would be None data = self.db.get(*args, **kw)
default = None try:
else: return pickle.loads(data)
data = self.db.get(key, default, txn=txn, flags=flags) except (EOFError, TypeError, pickle.UnpicklingError):
if data is default: return data # we may be getting the default value, or None,
return data # so it doesn't need unpickled.
return pickle.loads(data)
def get_both(self, key, value, txn=None, flags=0): def get_both(self, key, value, txn=None, flags=0):
data = _dumps(value, self.protocol) data = _dumps(value, self.protocol)
...@@ -234,10 +262,6 @@ class DBShelf(MutableMapping): ...@@ -234,10 +262,6 @@ class DBShelf(MutableMapping):
raise NotImplementedError raise NotImplementedError
def __contains__(self, key):
return self.db.has_key(key)
#---------------------------------------------- #----------------------------------------------
# Methods allowed to pass-through to self.db # Methods allowed to pass-through to self.db
# #
...@@ -331,7 +355,11 @@ class DBShelfCursor: ...@@ -331,7 +355,11 @@ class DBShelfCursor:
return None return None
else: else:
key, data = rec key, data = rec
return key, pickle.loads(data) # Safe in Python 2.x because expresion short circuit
if sys.version_info[0] < 3 or isinstance(data, bytes) :
return key, pickle.loads(data)
else :
return key, pickle.loads(bytes(data, "iso8859-1")) # 8 bits
#---------------------------------------------- #----------------------------------------------
# Methods allowed to pass-through to self.dbc # Methods allowed to pass-through to self.dbc
......
This diff is collapsed.
...@@ -19,8 +19,20 @@ ...@@ -19,8 +19,20 @@
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
import time
from . import db #
# import the time.sleep function in a namespace safe way to allow
# "from bsddb.dbutils import *"
#
from time import sleep as _sleep
import sys
absolute_import = (sys.version_info[0] >= 3)
if absolute_import :
# Because this syntaxis is not valid before Python 2.5
exec("from . import db")
else :
from . import db
# always sleep at least N seconds between retrys # always sleep at least N seconds between retrys
_deadlock_MinSleepTime = 1.0/128 _deadlock_MinSleepTime = 1.0/128
...@@ -54,22 +66,17 @@ def DeadlockWrap(function, *_args, **_kwargs): ...@@ -54,22 +66,17 @@ def DeadlockWrap(function, *_args, **_kwargs):
while True: while True:
try: try:
return function(*_args, **_kwargs) return function(*_args, **_kwargs)
except db.DBLockDeadlockError as e: except db.DBLockDeadlockError:
if _deadlock_VerboseFile: if _deadlock_VerboseFile:
_deadlock_VerboseFile.write( _deadlock_VerboseFile.write(
'bsddb.dbutils.DeadlockWrap: ' + 'dbutils.DeadlockWrap: sleeping %1.3f\n' % sleeptime)
'sleeping %1.3f\n' % sleeptime) _sleep(sleeptime)
time.sleep(sleeptime)
# exponential backoff in the sleep time # exponential backoff in the sleep time
sleeptime *= 2 sleeptime *= 2
if sleeptime > _deadlock_MaxSleepTime: if sleeptime > _deadlock_MaxSleepTime:
sleeptime = _deadlock_MaxSleepTime sleeptime = _deadlock_MaxSleepTime
max_retries -= 1 max_retries -= 1
if max_retries == -1: if max_retries == -1:
if _deadlock_VerboseFile:
_deadlock_VerboseFile.write(
'bsddb.dbutils.DeadlockWrap: ' +
'max_retries reached, reraising %s\n' % e)
raise raise
......
# http://bugs.python.org/issue1413192
#
# See the bug report for details.
# The problem was that the env was deallocated prior to the txn.
import shutil
import tempfile
from test.support import catch_warning
import warnings
try:
# For Pythons w/distutils and add-on pybsddb
from bsddb3 import db
except ImportError:
# For Python >= 2.3 builtin bsddb distribution
from bsddb import db
env_name = tempfile.mkdtemp()
# Wrap test operation in a class so we can control destruction rather than
# waiting for the controlling Python executable to exit
class Context:
def __init__(self):
self.env = db.DBEnv()
self.env.open(env_name,
db.DB_CREATE | db.DB_INIT_TXN | db.DB_INIT_MPOOL)
self.the_txn = self.env.txn_begin()
self.map = db.DB(self.env)
self.map.open('xxx.db', "p",
db.DB_HASH, db.DB_CREATE, 0o666, txn=self.the_txn)
del self.env
del self.the_txn
with catch_warning():
warnings.filterwarnings('ignore', 'DBTxn aborted in destructor')
context = Context()
del context
# try not to leave a turd
try:
shutil.rmtree(env_name)
except EnvironmentError:
pass
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -2,55 +2,51 @@ ...@@ -2,55 +2,51 @@
TestCases for python DB Btree key comparison function. TestCases for python DB Btree key comparison function.
""" """
import shutil
import sys, os, re import sys, os, re
from io import StringIO
import tempfile
from . import test_all from . import test_all
from io import StringIO
import unittest import unittest
try:
# For Pythons w/distutils pybsddb from .test_all import db, dbshelve, test_support, \
from bsddb3 import db, dbshelve get_new_environment_path, get_new_database_path
except ImportError:
# For Python 2.3
from bsddb import db, dbshelve
try:
from bsddb3 import test_support
except ImportError:
from test import support as test_support
lexical_cmp = cmp lexical_cmp = cmp
def lowercase_cmp(left, right): def lowercase_cmp(left, right):
return cmp (str(left, encoding='ascii').lower(), return cmp (left.lower(), right.lower())
str(right, encoding='ascii').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 = [s.encode('ascii') for s in _expected_lexical_test_data = ['', 'CCCP', 'a', 'aaa', 'b', 'c', 'cccce', 'ccccf']
('', 'CCCP', 'a', 'aaa', 'b', 'c', 'cccce', 'ccccf')] _expected_lowercase_test_data = ['', 'a', 'aaa', 'b', 'c', 'CC', 'cccce', 'ccccf', 'CCCP']
_expected_lowercase_test_data = [s.encode('ascii') for s in
('', 'a', 'aaa', 'b', 'c', 'CC', 'cccce', 'ccccf', 'CCCP')]
def CmpToKey(mycmp):
'Convert a cmp= function into a key= function'
class K(object):
def __init__(self, obj, *args):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) == -1
return K
class ComparatorTests (unittest.TestCase): class ComparatorTests (unittest.TestCase):
def comparator_test_helper (self, comparator, expected_data): def comparator_test_helper (self, comparator, expected_data):
data = expected_data[:] data = expected_data[:]
data.sort (key=CmpToKey(comparator))
import sys
if sys.version_info[0] < 3 :
if sys.version_info[:3] < (2, 4, 0):
data.sort(comparator)
else :
data.sort(cmp=comparator)
else : # Insertion Sort. Please, improve
data2 = []
for i in data :
for j, k in enumerate(data2) :
r = comparator(k, i)
if r == 1 :
data2.insert(j, i)
break
else :
data2.append(i)
data = data2
self.failUnless (data == expected_data, self.failUnless (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))
...@@ -71,30 +67,24 @@ class AbstractBtreeKeyCompareTestCase (unittest.TestCase): ...@@ -71,30 +67,24 @@ class AbstractBtreeKeyCompareTestCase (unittest.TestCase):
def setUp (self): def setUp (self):
self.filename = self.__class__.__name__ + '.db' self.filename = self.__class__.__name__ + '.db'
homeDir = os.path.join (tempfile.gettempdir(), 'db_home%d'%os.getpid()) self.homeDir = get_new_environment_path()
self.homeDir = homeDir env = db.DBEnv()
try:
os.mkdir (homeDir)
except os.error:
pass
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).encode("ascii")) self.db.put (item, str (i))
i = i + 1 i = i + 1
def createDB (self, key_comparator): def createDB (self, key_comparator):
...@@ -128,10 +118,10 @@ class AbstractBtreeKeyCompareTestCase (unittest.TestCase): ...@@ -128,10 +118,10 @@ class AbstractBtreeKeyCompareTestCase (unittest.TestCase):
self.failUnless (index < len (expected), self.failUnless (index < len (expected),
"to many values returned from cursor") "to many values returned from cursor")
self.failUnless (expected[index] == key, self.failUnless (expected[index] == key,
"expected value %r at %d but got %r" "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 = next(curs)
self.failUnless (index == len (expected), self.failUnless (index == len (expected),
"not enough values returned from cursor") "not enough values returned from cursor")
finally: finally:
...@@ -158,10 +148,10 @@ class BtreeKeyCompareTestCase (AbstractBtreeKeyCompareTestCase): ...@@ -158,10 +148,10 @@ class BtreeKeyCompareTestCase (AbstractBtreeKeyCompareTestCase):
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'b', b'a', b'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'b']) self.finishTest (['b'])
class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase): class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
...@@ -200,9 +190,9 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase): ...@@ -200,9 +190,9 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
finally: finally:
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: %r" % errorOut) self.fail("unexpected stderr output:\n"+errorOut)
def _test_compare_function_exception (self): def _test_compare_function_exception (self):
self.startTest () self.startTest ()
...@@ -213,7 +203,7 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase): ...@@ -213,7 +203,7 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
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 ([b'a', b'b', 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):
...@@ -231,7 +221,7 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase): ...@@ -231,7 +221,7 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
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 ([b'a', b'b', 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):
...@@ -250,7 +240,7 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase): ...@@ -250,7 +240,7 @@ class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
self.createDB (my_compare) self.createDB (my_compare)
try: try:
self.db.set_bt_compare (my_compare) self.db.set_bt_compare (my_compare)
assert False, "this set should fail" self.assert_(0, "this set should fail")
except RuntimeError as msg: except RuntimeError as msg:
pass pass
...@@ -259,10 +249,9 @@ def test_suite (): ...@@ -259,10 +249,9 @@ def test_suite ():
res = unittest.TestSuite () res = unittest.TestSuite ()
res.addTest (unittest.makeSuite (ComparatorTests)) res.addTest (unittest.makeSuite (ComparatorTests))
if db.version () >= (3, 3, 11): res.addTest (unittest.makeSuite (BtreeExceptionsTestCase))
res.addTest (unittest.makeSuite (BtreeExceptionsTestCase)) res.addTest (unittest.makeSuite (BtreeKeyCompareTestCase))
res.addTest (unittest.makeSuite (BtreeKeyCompareTestCase))
return res return res
if __name__ == '__main__': if __name__ == '__main__':
unittest.main (defaultTest = 'test_suite') unittest.main (defaultTest = 'suite')
...@@ -3,18 +3,16 @@ Test cases adapted from the test_bsddb.py module in Python's ...@@ -3,18 +3,16 @@ Test cases adapted from the test_bsddb.py module in Python's
regression test suite. regression test suite.
""" """
import sys, os import os, string
import unittest import unittest
import tempfile
from bsddb.test.test_all import verbose from .test_all import db, hashopen, btopen, rnopen, verbose, \
get_new_database_path
from bsddb import db, hashopen, btopen, rnopen
class CompatibilityTestCase(unittest.TestCase): class CompatibilityTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.filename = tempfile.mktemp() self.filename = get_new_database_path()
def tearDown(self): def tearDown(self):
try: try:
...@@ -36,31 +34,31 @@ class CompatibilityTestCase(unittest.TestCase): ...@@ -36,31 +34,31 @@ class CompatibilityTestCase(unittest.TestCase):
f = rnopen(self.filename, 'c') f = rnopen(self.filename, 'c')
for x in range(len(data)): for x in range(len(data)):
f[x+1] = data[x].encode("ascii") f[x+1] = data[x]
getTest = (f[1], f[2], f[3]) getTest = (f[1], f[2], f[3])
if verbose: if verbose:
print('%s %s %s' % getTest) print('%s %s %s' % getTest)
assert getTest[1] == b'quick', 'data mismatch!' self.assertEqual(getTest[1], 'quick', 'data mismatch!')
rv = f.set_location(3) rv = f.set_location(3)
if rv != (3, b'brown'): if rv != (3, 'brown'):
self.fail('recno database set_location failed: '+repr(rv)) self.fail('recno database set_location failed: '+repr(rv))
f[25] = b'twenty-five' f[25] = 'twenty-five'
f.close() f.close()
del f del f
f = rnopen(self.filename, 'w') f = rnopen(self.filename, 'w')
f[20] = b'twenty' f[20] = 'twenty'
def noRec(f): def noRec(f):
rec = f[15] rec = f[15]
self.assertRaises(KeyError, noRec, f) self.assertRaises(KeyError, noRec, f)
def badKey(f): def badKey(f):
rec = f[b'a string'] rec = f['a string']
self.assertRaises(TypeError, badKey, f) self.assertRaises(TypeError, badKey, f)
del f[3] del f[3]
...@@ -70,7 +68,7 @@ class CompatibilityTestCase(unittest.TestCase): ...@@ -70,7 +68,7 @@ class CompatibilityTestCase(unittest.TestCase):
if verbose: if verbose:
print(rec) print(rec)
try: try:
rec = f.next() rec = next(f)
except KeyError: except KeyError:
break break
...@@ -96,42 +94,42 @@ class CompatibilityTestCase(unittest.TestCase): ...@@ -96,42 +94,42 @@ class CompatibilityTestCase(unittest.TestCase):
else: else:
if verbose: print("truth test: false") if verbose: print("truth test: false")
f[b'0'] = b'' f['0'] = ''
f[b'a'] = b'Guido' f['a'] = 'Guido'
f[b'b'] = b'van' f['b'] = 'van'
f[b'c'] = b'Rossum' f['c'] = 'Rossum'
f[b'd'] = b'invented' f['d'] = 'invented'
# 'e' intentionally left out # 'e' intentionally left out
f[b'f'] = b'Python' f['f'] = 'Python'
if verbose: if verbose:
print('%s %s %s' % (f['a'], f['b'], f['c'])) print('%s %s %s' % (f['a'], f['b'], f['c']))
if verbose: if verbose:
print('key ordering...') print('key ordering...')
start = f.set_location(f.first()[0]) start = f.set_location(f.first()[0])
if start != (b'0', b''): if start != ('0', ''):
self.fail("incorrect first() result: "+repr(start)) self.fail("incorrect first() result: "+repr(start))
while 1: while 1:
try: try:
rec = f.next() rec = next(f)
except KeyError: except KeyError:
assert rec == f.last(), 'Error, last != last!' self.assertEqual(rec, f.last(), 'Error, last <> last!')
f.previous() f.previous()
break break
if verbose: if verbose:
print(rec) print(rec)
assert f.has_key(b'f'), 'Error, missing key!' self.assert_('f' in f, 'Error, missing key!')
# test that set_location() returns the next nearest key, value # test that set_location() returns the next nearest key, value
# on btree databases and raises KeyError on others. # on btree databases and raises KeyError on others.
if factory == btopen: if factory == btopen:
e = f.set_location(b'e') e = f.set_location('e')
if e != (b'f', b'Python'): if e != ('f', 'Python'):
self.fail('wrong key,value returned: '+repr(e)) self.fail('wrong key,value returned: '+repr(e))
else: else:
try: try:
e = f.set_location(b'e') e = f.set_location('e')
except KeyError: except KeyError:
pass pass
else: else:
...@@ -155,17 +153,17 @@ class CompatibilityTestCase(unittest.TestCase): ...@@ -155,17 +153,17 @@ class CompatibilityTestCase(unittest.TestCase):
if verbose: if verbose:
print('modification...') print('modification...')
f = factory(self.filename, 'w') f = factory(self.filename, 'w')
f[b'd'] = b'discovered' f['d'] = 'discovered'
if verbose: if verbose:
print('access...') print('access...')
for key in f.keys(): for key in list(f.keys()):
word = f[key] word = f[key]
if verbose: if verbose:
print(word) print(word)
def noRec(f): def noRec(f):
rec = f[b'no such key'] rec = f['no such key']
self.assertRaises(KeyError, noRec, f) self.assertRaises(KeyError, noRec, f)
def badKey(f): def badKey(f):
......
import unittest import unittest
import tempfile import os, glob
import sys, os, glob
import shutil
import tempfile
from bsddb import db
try:
from bsddb3 import test_support
except ImportError:
from test import support as test_support
from .test_all import db, test_support, get_new_environment_path, \
get_new_database_path
#---------------------------------------------------------------------- #----------------------------------------------------------------------
...@@ -19,11 +11,7 @@ class pget_bugTestCase(unittest.TestCase): ...@@ -19,11 +11,7 @@ class pget_bugTestCase(unittest.TestCase):
db_name = 'test-cursor_pget.db' db_name = 'test-cursor_pget.db'
def setUp(self): def setUp(self):
self.homeDir = os.path.join(tempfile.gettempdir(), 'db_home%d'%os.getpid()) self.homeDir = get_new_environment_path()
try:
os.mkdir(self.homeDir)
except os.error:
pass
self.env = db.DBEnv() self.env = db.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)
self.primary_db = db.DB(self.env) self.primary_db = db.DB(self.env)
...@@ -32,9 +20,9 @@ class pget_bugTestCase(unittest.TestCase): ...@@ -32,9 +20,9 @@ class pget_bugTestCase(unittest.TestCase):
self.secondary_db.set_flags(db.DB_DUP) self.secondary_db.set_flags(db.DB_DUP)
self.secondary_db.open(self.db_name, 'secondary', db.DB_BTREE, db.DB_CREATE) self.secondary_db.open(self.db_name, 'secondary', db.DB_BTREE, db.DB_CREATE)
self.primary_db.associate(self.secondary_db, lambda key, data: data) self.primary_db.associate(self.secondary_db, lambda key, data: data)
self.primary_db.put(b'salad', b'eggs') self.primary_db.put('salad', 'eggs')
self.primary_db.put(b'spam', b'ham') self.primary_db.put('spam', 'ham')
self.primary_db.put(b'omelet', b'eggs') self.primary_db.put('omelet', 'eggs')
def tearDown(self): def tearDown(self):
...@@ -49,11 +37,11 @@ class pget_bugTestCase(unittest.TestCase): ...@@ -49,11 +37,11 @@ class pget_bugTestCase(unittest.TestCase):
def test_pget(self): def test_pget(self):
cursor = self.secondary_db.cursor() cursor = self.secondary_db.cursor()
self.assertEquals((b'eggs', b'salad', b'eggs'), cursor.pget(key=b'eggs', flags=db.DB_SET)) self.assertEquals(('eggs', 'salad', 'eggs'), cursor.pget(key='eggs', flags=db.DB_SET))
self.assertEquals((b'eggs', b'omelet', b'eggs'), cursor.pget(db.DB_NEXT_DUP)) self.assertEquals(('eggs', 'omelet', 'eggs'), cursor.pget(db.DB_NEXT_DUP))
self.assertEquals(None, cursor.pget(db.DB_NEXT_DUP)) self.assertEquals(None, cursor.pget(db.DB_NEXT_DUP))
self.assertEquals((b'ham', b'spam', b'ham'), cursor.pget(b'ham', b'spam', flags=db.DB_SET)) self.assertEquals(('ham', 'spam', 'ham'), cursor.pget('ham', 'spam', flags=db.DB_SET))
self.assertEquals(None, cursor.pget(db.DB_NEXT_DUP)) self.assertEquals(None, cursor.pget(db.DB_NEXT_DUP))
cursor.close() cursor.close()
......
import shutil import os, string
import sys, os
import unittest import unittest
import tempfile
try:
# For Pythons w/distutils pybsddb
from bsddb3 import db, dbobj
except ImportError:
# For Python 2.3
from bsddb import db, dbobj
try:
from bsddb3 import test_support
except ImportError:
from test import support as test_support
from .test_all import db, dbobj, test_support, get_new_environment_path, \
get_new_database_path
#---------------------------------------------------------------------- #----------------------------------------------------------------------
...@@ -24,10 +12,7 @@ class dbobjTestCase(unittest.TestCase): ...@@ -24,10 +12,7 @@ class dbobjTestCase(unittest.TestCase):
db_name = 'test-dbobj.db' db_name = 'test-dbobj.db'
def setUp(self): def setUp(self):
homeDir = os.path.join(tempfile.gettempdir(), 'db_home%d'%os.getpid()) self.homeDir = get_new_environment_path()
self.homeDir = homeDir
try: os.mkdir(homeDir)
except os.error: pass
def tearDown(self): def tearDown(self):
if hasattr(self, 'db'): if hasattr(self, 'db'):
...@@ -40,18 +25,18 @@ class dbobjTestCase(unittest.TestCase): ...@@ -40,18 +25,18 @@ class dbobjTestCase(unittest.TestCase):
class TestDBEnv(dbobj.DBEnv): pass class TestDBEnv(dbobj.DBEnv): pass
class TestDB(dbobj.DB): class TestDB(dbobj.DB):
def put(self, key, *args, **kwargs): def put(self, key, *args, **kwargs):
key = key.decode("ascii").upper().encode("ascii") key = key.upper()
# call our parent classes put method with an upper case key # call our parent classes put method with an upper case key
return dbobj.DB.put(self, key, *args, **kwargs) return dbobj.DB.put(*(self, key) + args, **kwargs)
self.env = TestDBEnv() self.env = TestDBEnv()
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL) self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
self.db = TestDB(self.env) self.db = TestDB(self.env)
self.db.open(self.db_name, db.DB_HASH, db.DB_CREATE) self.db.open(self.db_name, db.DB_HASH, db.DB_CREATE)
self.db.put(b'spam', b'eggs') self.db.put('spam', 'eggs')
assert self.db.get(b'spam') == None, \ self.assertEqual(self.db.get('spam'), None,
"overridden dbobj.DB.put() method failed [1]" "overridden dbobj.DB.put() method failed [1]")
assert self.db.get(b'SPAM') == b'eggs', \ self.assertEqual(self.db.get('SPAM'), 'eggs',
"overridden dbobj.DB.put() method failed [2]" "overridden dbobj.DB.put() method failed [2]")
self.db.close() self.db.close()
self.env.close() self.env.close()
...@@ -61,14 +46,14 @@ class dbobjTestCase(unittest.TestCase): ...@@ -61,14 +46,14 @@ class dbobjTestCase(unittest.TestCase):
self.db = dbobj.DB(self.env) self.db = dbobj.DB(self.env)
self.db.open(self.db_name+'02', db.DB_HASH, db.DB_CREATE) self.db.open(self.db_name+'02', db.DB_HASH, db.DB_CREATE)
# __setitem__ # __setitem__
self.db[b'spam'] = b'eggs' self.db['spam'] = 'eggs'
# __len__ # __len__
assert len(self.db) == 1 self.assertEqual(len(self.db), 1)
# __getitem__ # __getitem__
assert self.db[b'spam'] == b'eggs' self.assertEqual(self.db['spam'], 'eggs')
# __del__ # __del__
del self.db[b'spam'] del self.db['spam']
assert self.db.get(b'spam') == None, "dbobj __del__ failed" self.assertEqual(self.db.get('spam'), None, "dbobj __del__ failed")
self.db.close() self.db.close()
self.env.close() self.env.close()
......
This diff is collapsed.
This diff is collapsed.
"""TestCases for distributed transactions.
"""
import os
import unittest
from .test_all import db, test_support, get_new_environment_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
#----------------------------------------------------------------------
class DBTxn_distributed(unittest.TestCase):
num_txns=1234
nosync=True
must_open_db=False
def _create_env(self, must_open_db) :
self.dbenv = db.DBEnv()
self.dbenv.set_tx_max(self.num_txns)
self.dbenv.set_lk_max_lockers(self.num_txns*2)
self.dbenv.set_lk_max_locks(self.num_txns*2)
self.dbenv.set_lk_max_objects(self.num_txns*2)
if self.nosync :
self.dbenv.set_flags(db.DB_TXN_NOSYNC,True)
self.dbenv.open(self.homeDir, db.DB_CREATE | db.DB_THREAD |
db.DB_RECOVER |
db.DB_INIT_TXN | db.DB_INIT_LOG | db.DB_INIT_MPOOL |
db.DB_INIT_LOCK, 0o666)
self.db = db.DB(self.dbenv)
self.db.set_re_len(db.DB_XIDDATASIZE)
if must_open_db :
if db.version() > (4,1) :
txn=self.dbenv.txn_begin()
self.db.open(self.filename,
db.DB_QUEUE, db.DB_CREATE | db.DB_THREAD, 0o666,
txn=txn)
txn.commit()
else :
self.db.open(self.filename,
db.DB_QUEUE, db.DB_CREATE | db.DB_THREAD, 0o666)
def setUp(self) :
self.homeDir = get_new_environment_path()
self.filename = "test"
return self._create_env(must_open_db=True)
def _destroy_env(self):
if self.nosync or (db.version()[:2] == (4,6)): # Known bug
self.dbenv.log_flush()
self.db.close()
self.dbenv.close()
def tearDown(self):
self._destroy_env()
test_support.rmtree(self.homeDir)
def _recreate_env(self,must_open_db) :
self._destroy_env()
self._create_env(must_open_db)
def test01_distributed_transactions(self) :
txns=set()
adapt = lambda x : x
import sys
if sys.version_info[0] >= 3 :
adapt = lambda x : bytes(x, "ascii")
# Create transactions, "prepare" them, and
# let them be garbage collected.
for i in range(self.num_txns) :
txn = self.dbenv.txn_begin()
gid = "%%%dd" %db.DB_XIDDATASIZE
gid = adapt(gid %i)
self.db.put(i, gid, txn=txn, flags=db.DB_APPEND)
txns.add(gid)
txn.prepare(gid)
del txn
self._recreate_env(self.must_open_db)
# Get "to be recovered" transactions but
# let them be garbage collected.
recovered_txns=self.dbenv.txn_recover()
self.assertEquals(self.num_txns,len(recovered_txns))
for gid,txn in recovered_txns :
self.assert_(gid in txns)
del txn
del recovered_txns
self._recreate_env(self.must_open_db)
# Get "to be recovered" transactions. Commit, abort and
# discard them.
recovered_txns=self.dbenv.txn_recover()
self.assertEquals(self.num_txns,len(recovered_txns))
discard_txns=set()
committed_txns=set()
state=0
for gid,txn in recovered_txns :
if state==0 or state==1:
committed_txns.add(gid)
txn.commit()
elif state==2 :
txn.abort()
elif state==3 :
txn.discard()
discard_txns.add(gid)
state=-1
state+=1
del txn
del recovered_txns
self._recreate_env(self.must_open_db)
# Verify the discarded transactions are still
# around, and dispose them.
recovered_txns=self.dbenv.txn_recover()
self.assertEquals(len(discard_txns),len(recovered_txns))
for gid,txn in recovered_txns :
txn.abort()
del txn
del recovered_txns
self._recreate_env(must_open_db=True)
# Be sure there are not pending transactions.
# Check also database size.
recovered_txns=self.dbenv.txn_recover()
self.assert_(len(recovered_txns)==0)
self.assertEquals(len(committed_txns),self.db.stat()["nkeys"])
class DBTxn_distributedSYNC(DBTxn_distributed):
nosync=False
class DBTxn_distributed_must_open_db(DBTxn_distributed):
must_open_db=True
class DBTxn_distributedSYNC_must_open_db(DBTxn_distributed):
nosync=False
must_open_db=True
#----------------------------------------------------------------------
def test_suite():
suite = unittest.TestSuite()
if db.version() >= (4,5) :
suite.addTest(unittest.makeSuite(DBTxn_distributed))
suite.addTest(unittest.makeSuite(DBTxn_distributedSYNC))
if db.version() >= (4,6) :
suite.addTest(unittest.makeSuite(DBTxn_distributed_must_open_db))
suite.addTest(unittest.makeSuite(DBTxn_distributedSYNC_must_open_db))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
"""TestCases for checking that it does not segfault when a DBEnv object
is closed before its DB objects.
"""
import os
import unittest
from .test_all import db, test_support, verbose, get_new_environment_path, get_new_database_path
# We're going to get warnings in this module about trying to close the db when
# its env is already closed. Let's just ignore those.
try:
import warnings
except ImportError:
pass
else:
warnings.filterwarnings('ignore',
message='DB could not be closed in',
category=RuntimeWarning)
#----------------------------------------------------------------------
class DBEnvClosedEarlyCrash(unittest.TestCase):
def setUp(self):
self.homeDir = get_new_environment_path()
self.filename = "test"
def tearDown(self):
test_support.rmtree(self.homeDir)
def test01_close_dbenv_before_db(self):
dbenv = db.DBEnv()
dbenv.open(self.homeDir,
db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
0o666)
d = db.DB(dbenv)
d2 = db.DB(dbenv)
d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
self.assertRaises(db.DBNoSuchFileError, d2.open,
self.filename+"2", db.DB_BTREE, db.DB_THREAD, 0o666)
d.put("test","this is a test")
self.assertEqual(d.get("test"), "this is a test", "put!=get")
dbenv.close() # This "close" should close the child db handle also
self.assertRaises(db.DBError, d.get, "test")
def test02_close_dbenv_before_dbcursor(self):
dbenv = db.DBEnv()
dbenv.open(self.homeDir,
db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
0o666)
d = db.DB(dbenv)
d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
d.put("test","this is a test")
d.put("test2","another test")
d.put("test3","another one")
self.assertEqual(d.get("test"), "this is a test", "put!=get")
c=d.cursor()
c.first()
next(c)
d.close() # This "close" should close the child db handle also
# db.close should close the child cursor
self.assertRaises(db.DBError,c.__next__)
d = db.DB(dbenv)
d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
c=d.cursor()
c.first()
next(c)
dbenv.close()
# The "close" should close the child db handle also, with cursors
self.assertRaises(db.DBError, c.__next__)
def test03_close_db_before_dbcursor_without_env(self):
import os.path
path=os.path.join(self.homeDir,self.filename)
d = db.DB()
d.open(path, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
d.put("test","this is a test")
d.put("test2","another test")
d.put("test3","another one")
self.assertEqual(d.get("test"), "this is a test", "put!=get")
c=d.cursor()
c.first()
next(c)
d.close()
# The "close" should close the child db handle also
self.assertRaises(db.DBError, c.__next__)
def test04_close_massive(self):
dbenv = db.DBEnv()
dbenv.open(self.homeDir,
db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
0o666)
dbs=[db.DB(dbenv) for i in range(16)]
cursors=[]
for i in dbs :
i.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
dbs[10].put("test","this is a test")
dbs[10].put("test2","another test")
dbs[10].put("test3","another one")
self.assertEqual(dbs[4].get("test"), "this is a test", "put!=get")
for i in dbs :
cursors.extend([i.cursor() for j in range(32)])
for i in dbs[::3] :
i.close()
for i in cursors[::3] :
i.close()
# Check for missing exception in DB! (after DB close)
self.assertRaises(db.DBError, dbs[9].get, "test")
# Check for missing exception in DBCursor! (after DB close)
self.assertRaises(db.DBError, cursors[101].first)
cursors[80].first()
next(cursors[80])
dbenv.close() # This "close" should close the child db handle also
# Check for missing exception! (after DBEnv close)
self.assertRaises(db.DBError, cursors[80].__next__)
def test05_close_dbenv_delete_db_success(self):
dbenv = db.DBEnv()
dbenv.open(self.homeDir,
db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
0o666)
d = db.DB(dbenv)
d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
dbenv.close() # This "close" should close the child db handle also
del d
try:
import gc
except ImportError:
gc = None
if gc:
# force d.__del__ [DB_dealloc] to be called
gc.collect()
def test06_close_txn_before_dup_cursor(self) :
dbenv = db.DBEnv()
dbenv.open(self.homeDir,db.DB_INIT_TXN | db.DB_INIT_MPOOL |
db.DB_INIT_LOG | db.DB_CREATE)
d = db.DB(dbenv)
txn = dbenv.txn_begin()
if db.version() < (4,1) :
d.open(self.filename, dbtype = db.DB_HASH, flags = db.DB_CREATE)
else :
d.open(self.filename, dbtype = db.DB_HASH, flags = db.DB_CREATE,
txn=txn)
d.put("XXX", "yyy", txn=txn)
txn.commit()
txn = dbenv.txn_begin()
c1 = d.cursor(txn)
c2 = c1.dup()
self.assertEquals(("XXX", "yyy"), c1.first())
import warnings
# Not interested in warnings about implicit close.
warnings.simplefilter("ignore")
txn.commit()
warnings.resetwarnings()
self.assertRaises(db.DBCursorClosedError, c2.first)
if db.version() > (4,3,0) :
def test07_close_db_before_sequence(self):
import os.path
path=os.path.join(self.homeDir,self.filename)
d = db.DB()
d.open(path, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0o666)
dbs=db.DBSequence(d)
d.close() # This "close" should close the child DBSequence also
dbs.close() # If not closed, core dump (in Berkeley DB 4.6.*)
#----------------------------------------------------------------------
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(DBEnvClosedEarlyCrash))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
...@@ -2,22 +2,17 @@ ...@@ -2,22 +2,17 @@
TestCases for checking set_get_returns_none. TestCases for checking set_get_returns_none.
""" """
import sys, os, string import os, string
import tempfile
from pprint import pprint
import unittest import unittest
from bsddb import db from .test_all import db, verbose, get_new_database_path
from bsddb.test.test_all import verbose
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class GetReturnsNoneTestCase(unittest.TestCase): class GetReturnsNoneTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.filename = tempfile.mktemp() self.filename = get_new_database_path()
def tearDown(self): def tearDown(self):
try: try:
...@@ -31,25 +26,24 @@ class GetReturnsNoneTestCase(unittest.TestCase): ...@@ -31,25 +26,24 @@ class GetReturnsNoneTestCase(unittest.TestCase):
d.open(self.filename, db.DB_BTREE, db.DB_CREATE) d.open(self.filename, db.DB_BTREE, db.DB_CREATE)
d.set_get_returns_none(1) d.set_get_returns_none(1)
for x in letters: for x in string.letters:
x = x.encode("ascii")
d.put(x, x * 40) d.put(x, x * 40)
data = d.get(b'bad key') data = d.get('bad key')
assert data == None self.assertEqual(data, None)
data = d.get(b'a') data = d.get(string.letters[0])
assert data == b'a'*40 self.assertEqual(data, string.letters[0]*40)
count = 0 count = 0
c = d.cursor() c = d.cursor()
rec = c.first() rec = c.first()
while rec: while rec:
count = count + 1 count = count + 1
rec = c.next() rec = next(c)
assert rec == None self.assertEqual(rec, None)
assert count == 52 self.assertEqual(count, len(string.letters))
c.close() c.close()
d.close() d.close()
...@@ -60,15 +54,14 @@ class GetReturnsNoneTestCase(unittest.TestCase): ...@@ -60,15 +54,14 @@ class GetReturnsNoneTestCase(unittest.TestCase):
d.open(self.filename, db.DB_BTREE, db.DB_CREATE) d.open(self.filename, db.DB_BTREE, db.DB_CREATE)
d.set_get_returns_none(0) d.set_get_returns_none(0)
for x in letters: for x in string.letters:
x = x.encode("ascii")
d.put(x, x * 40) d.put(x, x * 40)
self.assertRaises(db.DBNotFoundError, d.get, b'bad key') self.assertRaises(db.DBNotFoundError, d.get, 'bad key')
self.assertRaises(KeyError, d.get, b'bad key') self.assertRaises(KeyError, d.get, 'bad key')
data = d.get(b'a') data = d.get(string.letters[0])
assert data == b'a'*40 self.assertEqual(data, string.letters[0]*40)
count = 0 count = 0
exceptionHappened = 0 exceptionHappened = 0
...@@ -77,14 +70,14 @@ class GetReturnsNoneTestCase(unittest.TestCase): ...@@ -77,14 +70,14 @@ class GetReturnsNoneTestCase(unittest.TestCase):
while rec: while rec:
count = count + 1 count = count + 1
try: try:
rec = c.next() rec = next(c)
except db.DBNotFoundError: # end of the records except db.DBNotFoundError: # end of the records
exceptionHappened = 1 exceptionHappened = 1
break break
assert rec != None self.assertNotEqual(rec, None)
assert exceptionHappened self.assert_(exceptionHappened)
assert count == 52 self.assertEqual(count, len(string.letters))
c.close() c.close()
d.close() d.close()
......
"""TestCases for using the DB.join and DBCursor.join_item methods. """TestCases for using the DB.join and DBCursor.join_item methods.
""" """
import shutil import os
import sys, os
import tempfile
import time
from pprint import pprint
try:
from threading import Thread, current_thread
have_threads = 1
except ImportError:
have_threads = 0
import unittest import unittest
from bsddb.test.test_all import verbose
from bsddb import db, dbshelve, StringKeys from .test_all import db, dbshelve, test_support, verbose, \
get_new_environment_path, get_new_database_path
try:
from bsddb3 import test_support
except ImportError:
from test import support as test_support
#---------------------------------------------------------------------- #----------------------------------------------------------------------
...@@ -44,18 +29,12 @@ ColorIndex = [ ...@@ -44,18 +29,12 @@ ColorIndex = [
('black', "shotgun"), ('black', "shotgun"),
] ]
def ASCII(s):
return s.encode("ascii")
class JoinTestCase(unittest.TestCase): class JoinTestCase(unittest.TestCase):
keytype = '' keytype = ''
def setUp(self): def setUp(self):
self.filename = self.__class__.__name__ + '.db' self.filename = self.__class__.__name__ + '.db'
homeDir = os.path.join(tempfile.gettempdir(), 'db_home%d'%os.getpid()) self.homeDir = get_new_environment_path()
self.homeDir = homeDir
try: os.mkdir(homeDir)
except os.error: pass
self.env = db.DBEnv() self.env = db.DBEnv()
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL | db.DB_INIT_LOCK ) self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL | db.DB_INIT_LOCK )
...@@ -72,13 +51,13 @@ class JoinTestCase(unittest.TestCase): ...@@ -72,13 +51,13 @@ class JoinTestCase(unittest.TestCase):
# create and populate primary index # create and populate primary index
priDB = db.DB(self.env) priDB = db.DB(self.env)
priDB.open(self.filename, "primary", db.DB_BTREE, db.DB_CREATE) priDB.open(self.filename, "primary", db.DB_BTREE, db.DB_CREATE)
[priDB.put(ASCII(k),ASCII(v)) for k,v in ProductIndex] list(map(lambda t, priDB=priDB: priDB.put(*t), ProductIndex))
# create and populate secondary index # create and populate secondary index
secDB = db.DB(self.env) secDB = db.DB(self.env)
secDB.set_flags(db.DB_DUP | db.DB_DUPSORT) secDB.set_flags(db.DB_DUP | db.DB_DUPSORT)
secDB.open(self.filename, "secondary", db.DB_BTREE, db.DB_CREATE) secDB.open(self.filename, "secondary", db.DB_BTREE, db.DB_CREATE)
[secDB.put(ASCII(k),ASCII(v)) for k,v in ColorIndex] list(map(lambda t, secDB=secDB: secDB.put(*t), ColorIndex))
sCursor = None sCursor = None
jCursor = None jCursor = None
...@@ -87,19 +66,19 @@ class JoinTestCase(unittest.TestCase): ...@@ -87,19 +66,19 @@ class JoinTestCase(unittest.TestCase):
sCursor = secDB.cursor() sCursor = secDB.cursor()
# Don't do the .set() in an assert, or you can get a bogus failure # Don't do the .set() in an assert, or you can get a bogus failure
# when running python -O # when running python -O
tmp = sCursor.set(b'red') tmp = sCursor.set('red')
assert tmp self.assert_(tmp)
# FIXME: jCursor doesn't properly hold a reference to its # FIXME: jCursor doesn't properly hold a reference to its
# cursors, if they are closed before jcursor is used it # cursors, if they are closed before jcursor is used it
# can cause a crash. # can cause a crash.
jCursor = priDB.join([sCursor]) jCursor = priDB.join([sCursor])
if jCursor.get(0) != (b'apple', b"Convenience Store"): if jCursor.get(0) != ('apple', "Convenience Store"):
self.fail("join cursor positioned wrong") self.fail("join cursor positioned wrong")
if jCursor.join_item() != b'chainsaw': if jCursor.join_item() != 'chainsaw':
self.fail("DBCursor.join_item returned wrong item") self.fail("DBCursor.join_item returned wrong item")
if jCursor.get(0)[0] != b'strawberry': if jCursor.get(0)[0] != 'strawberry':
self.fail("join cursor returned wrong thing") self.fail("join cursor returned wrong thing")
if jCursor.get(0): # there were only three red items to return if jCursor.get(0): # there were only three red items to return
self.fail("join cursor returned too many items") self.fail("join cursor returned too many items")
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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